diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f5503391..62cda012 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -137,3 +137,9 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} flags: python-${{ matrix.python-version }} + + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-traces + path: tests/web/snapshots/ diff --git a/aiida_workgraph/web/frontend/package-lock.json b/aiida_workgraph/web/frontend/package-lock.json index ee482d59..7069afc5 100644 --- a/aiida_workgraph/web/frontend/package-lock.json +++ b/aiida_workgraph/web/frontend/package-lock.json @@ -49,7 +49,7 @@ "three": "^0.156.1", "typescript": "^4.9.5", "vis-timeline": "^7.7.3", - "weas": "^0.1.6", + "weas": "^0.1.11", "web-vitals": "^2.1.4", "web-worker": "^1.2.0" }, @@ -5144,8 +5144,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "optional": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -5160,9 +5158,7 @@ "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "optional": true, - "peer": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/ajv-keywords": { "version": "3.5.2", @@ -19095,9 +19091,9 @@ } }, "node_modules/weas": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/weas/-/weas-0.1.6.tgz", - "integrity": "sha512-IbqwhE6JEZbIwfWQhxnp/BqKJ4pVCRvQwqwwht9Cy4fq8oguoWzngwQsYgCXZ1uB5ZrdEx8n8uFgWKtYPZD7pA==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/weas/-/weas-0.1.11.tgz", + "integrity": "sha512-iRUb84RXbl7toQjRBVWBseK1ZDBQPtUdj+maw+VLzllHxWPGz2EbaopDSHaijeetWAdoR+5V+oSJLqKey2mlNQ==", "dependencies": { "dat.gui": "^0.7.9", "three": "^0.160.1" @@ -23621,13 +23617,14 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "requires": {}, + "requires": { + "ajv": "^8.0.0" + }, "dependencies": { "ajv": { - "version": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "optional": true, - "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -23638,9 +23635,7 @@ "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "optional": true, - "peer": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" } } }, @@ -33539,9 +33534,9 @@ } }, "weas": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/weas/-/weas-0.1.6.tgz", - "integrity": "sha512-IbqwhE6JEZbIwfWQhxnp/BqKJ4pVCRvQwqwwht9Cy4fq8oguoWzngwQsYgCXZ1uB5ZrdEx8n8uFgWKtYPZD7pA==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/weas/-/weas-0.1.11.tgz", + "integrity": "sha512-iRUb84RXbl7toQjRBVWBseK1ZDBQPtUdj+maw+VLzllHxWPGz2EbaopDSHaijeetWAdoR+5V+oSJLqKey2mlNQ==", "requires": { "dat.gui": "^0.7.9", "three": "^0.160.1" diff --git a/aiida_workgraph/web/frontend/package.json b/aiida_workgraph/web/frontend/package.json index 6607055e..fba47921 100644 --- a/aiida_workgraph/web/frontend/package.json +++ b/aiida_workgraph/web/frontend/package.json @@ -44,7 +44,7 @@ "three": "^0.156.1", "typescript": "^4.9.5", "vis-timeline": "^7.7.3", - "weas": "^0.1.6", + "weas": "^0.1.11", "web-vitals": "^2.1.4", "web-worker": "^1.2.0" }, diff --git a/pyproject.toml b/pyproject.toml index a83e23c1..93e75175 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,7 @@ tests = [ "pytest~=7.0", "pytest-cov~=2.7,<2.11", "playwright", + "pytest-playwright-visual", "httpx", ] diff --git a/tests/web/snapshots/test_frontend/test_workgraph_item/test_workgraph_item[chromium][linux].png b/tests/web/snapshots/test_frontend/test_workgraph_item/test_workgraph_item[chromium][linux].png new file mode 100644 index 00000000..6aa32252 Binary files /dev/null and b/tests/web/snapshots/test_frontend/test_workgraph_item/test_workgraph_item[chromium][linux].png differ diff --git a/tests/web/test_frontend.py b/tests/web/test_frontend.py index 56406877..c51cff46 100644 --- a/tests/web/test_frontend.py +++ b/tests/web/test_frontend.py @@ -27,7 +27,6 @@ def test_workgraph(page, wg_calcfunction): # Verify the presence of the search input assert page.locator(".search-input").is_visible() - # Verify the presence of the table header columns # Verify the presence of the table header columns assert page.locator("th:has-text('PK')").is_visible() assert page.locator("th:has-text('Created')").is_visible() @@ -43,23 +42,21 @@ def test_workgraph(page, wg_calcfunction): assert page.locator("tr").count() >= 2 # Including header row -def test_workgraph_item(page, wg_calcfunction): +def test_workgraph_item(page, wg_calcfunction, assert_snapshot): wg = wg_calcfunction wg.submit(wait=True) - page.goto("http://localhost:8000/workgraph/{}".format(wg.pk)) - page.wait_for_timeout(8000) - - page.get_by_text("sumdiff3").is_visible() - - # Simulate user interaction (e.g., clicking a button) - # Replace the selector with the actual selector of the button you want to click - # You should identify the button that triggers an action in your component + page.goto( + "http://localhost:8000/workgraph/{}".format(wg.pk), + wait_until="domcontentloaded", + ) + page.wait_for_timeout(3000) page.get_by_role("button", name="Arrange").click() - page.wait_for_timeout(8000) - # Capture a screenshot - screenshot = page.screenshot() + page.wait_for_timeout(5000) + + # compare the screenshot + assert_snapshot(page.screenshot()) - # Save the screenshot to a file - with open("screenshot.png", "wb") as f: - f.write(screenshot) + # page.get_by_text("sumdiff2").click() + # page.wait_for_timeout(3000) + # assert_snapshot(page.screenshot(), name='test_workgraph_item_sumdiff2.png')