Comparison Engine

Flask server is running

Comparison
# AIlab-comparison-engine Comparison Engine refactored from AIlab-UI-Diff using Object-Oriented Programming. #### Setup - install dependencies using `poetry lock` and `poetry install` - create `.env` file with `API_KEY` - run the virtual environment using `poetry shell` - run the Flask server with `python app.py` - go to `frontend` folder and install dependencies using `npm install` - run the Node server with `node server.js` - go to http://localhost:3000/compare - select test case to compare - run the comparison engine - wait a few seconds - select elements to display On the next run, you can launch the comparison engine using `./run_servers.sh` Give it execute permissions using `chmod +x run_servers.sh` --- #### Endpoints Backend (Flask) - `/` [GET]: **docs** - `/api/compare` [POST]: **json payload (diffs without DOM trees)** - `/api/compare/preprocess` [POST]: **preprocess DOM trees** - `/api/compare/detailed` [POST]: **detailed DOM trees** - `/api/compare/layout` [POST]: **layout DOM trees** Frontend (Node) - `/compare` [GET]: **selection tool** - `/compare` [POST]: **rendered results** The Flask server is launched on port `8001` The Node server is launched on port `3000` --- #### Request The request must be in JSON format (keys provided below). In case of a missing URL for the DOM files, the algorithm will be changed to `pixel`. You can pass data to the engine in 3 ways. 1. Provide the comparison ID and environment: ```json { "comparisonId": "z9WOyd9V", "env": "prod" } ``` 2. Send test case containing required keys: (`test_case_name` and `comparison_mode` are optional) **The options for ``"algorithm"`` are ``"PIXEL"``, ``"DOM-ELEMENT"``, and ``"AI-MODEL"``.** **Comparison using ``"AI-MODEL"`` will do pixel comparison as preprocessing.** So if the results from ``"AI-MODEL"`` look wierd, try ``"PIXEL"`` to see the diffs before model detection. **For branch UIDIFF-114, ``"DOM-ELEMENT"`` is not recommended. Bugs may exist.** ```json { "test_case_name": "Example Page SB", "options": { "algorithm": "dom-element", "moved_tolerance": "30", "comparison_mode": "detailed" }, "base_dom": "https://ailab.dev.visualtest.io/test-case-01-example-page-sb/base.json", "target_dom": "https://ailab.dev.visualtest.io/test-case-01-example-page-sb/target.json", "base_img": "https://ailab.dev.visualtest.io/test-case-01-example-page-sb/base.png", "target_img": "https://ailab.dev.visualtest.io/test-case-01-example-page-sb/target.png" } ``` 3. Send a file (directly or via URL) containing a test case list and choose one in `/compare`. --- #### Response The response is in JSON format (keys provided below). By default, there is no `elements` dictionary. DOM elements are provided on separate endpoints. ```json { "diffs": { "detailed": "detailed_diffs", "layout": "layout_diffs", }, "images": { "base": { "url": "base_img_file.img_url", "height": "base_img_file.height", "width": "base_img_file.width", }, "target": { "url": "target_img_file.img_url", "height": "target_img_file.height", "width": "target_img_file.width", } }, "elements": { "preprocess": { "base": "base_dom.preprocessed_dom_list", "target": "target_dom.preprocessed_dom_list", }, "detailed": { "base": "base_dom.detailed_tree converted to list", "target": "target_dom.detailed_tree converted to list", }, "layout": { "base": "base_dom.layout_tree converted to list", "target": "target_dom.layout_tree converted to list", } }, "logs": { "errors":"logs with level equal to error", "warnings": "logs with level equal to warning", "info": "logs with level equal to info", "debug": "logs with level equal to debug", }, "config": "the whole configuration", "version": "number", } ``` --- #### Diffs All `elements` are converted into `detailed_diffs`. This is necessary to display elements in the `comparison-view`. `detailed_diffs` and `layout_diffs` share the same format as the following example: ``` [ { "diff_type": "changed", "base": { "id": 0, "tag": "IMG", "top": 770, "left": 592, "width": 1072, "height": 628, "dom_id": 308, "xpath": "/HTML[1]/BODY[1]/DIV[3]", "css_selector": " > HTML#1 > BODY#39 > DIV#73.pt_saspage inline-flow" }, "target": { "id": 0, "tag": "IMG", "top": 772, "left": 592, "width": 1072, "height": 674, "dom_id": 304, "xpath": "/HTML[1]/BODY[1]/DIV[3]", "css_selector": " > HTML#1 > BODY#36 > DIV#70.pt_saspage inline-flow" }, "similarity_score": 0.689, "sensitivity": "null for detailed diff and value range in [0, 1, 2] for layout diff", , "description": [ "Element content changed", "Element height grew 46px" ], "ignore": false }, { "diff_type": "added", "base": {}, "target": { "id": 31, "tag": "DIV", "top": 2736, "left": 548, "width": 2360, "height": 754, "dom_id": 558, "xpath": "/HTML[1]/BODY[1]/DIV[3]/MAIN[1]", "css_selector": " > HTML#1 > BODY#36 > DIV#70.pt_saspage inline-flow > MAIN#228.clearfix" }, "similarity_score": null, "sensitivity": "null for detailed diff and value range in [0, 1, 2] for layout diff", "description": [ "Element was added" ], "ignore": false } ] ```