Skip to content

feat: e2e tests with playwright #3

feat: e2e tests with playwright

feat: e2e tests with playwright #3

Triggered via pull request January 11, 2026 17:33
Status Failure
Total duration 5m 20s
Artifacts 1

ui-tests.yml

on: pull_request
Playwright E2E Tests
5m 16s
Playwright E2E Tests
Fit to window
Zoom out
Zoom in

Annotations

10 errors, 1 warning, and 1 notice
[chromium] › e2e/tests/workflow-crud.spec.ts:44:6 › Workflow CRUD Operations › should list existing workflows: e2e/helpers/frappe.ts#L27
4) [chromium] › e2e/tests/workflow-crud.spec.ts:44:6 › Workflow CRUD Operations › should list existing workflows Error: Failed to create Hazel Workflow: {"exception":"frappe.exceptions.CSRFTokenError: Invalid Request","exc_type":"CSRFTokenError","exc":"[\"Traceback (most recent call last):\\n File \\\"apps/frappe/frappe/app.py\\\", line 102, in application\\n init_request(request)\\n ~~~~~~~~~~~~^^^^^^^^^\\n File \\\"apps/frappe/frappe/app.py\\\", line 200, in init_request\\n frappe.local.http_request = HTTPRequest()\\n ~~~~~~~~~~~^^\\n File \\\"apps/frappe/frappe/auth.py\\\", line 48, in __init__\\n self.validate_csrf_token()\\n ~~~~~~~~~~~~~~~~~~~~~~~~^^\\n File \\\"apps/frappe/frappe/auth.py\\\", line 97, in validate_csrf_token\\n frappe.throw(_(\\\"Invalid Request\\\"), frappe.CSRFTokenError)\\n ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n File \\\"apps/frappe/frappe/utils/messages.py\\\", line 148, in throw\\n msgprint(\\n ~~~~~~~~^\\n \\tmsg,\\n ^^^^\\n ...<6 lines>...\\n \\tprimary_action=primary_action,\\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n )\\n ^\\n File \\\"apps/frappe/frappe/utils/messages.py\\\", line 109, in msgprint\\n _raise_exception()\\n ~~~~~~~~~~~~~~~~^^\\n File \\\"apps/frappe/frappe/utils/messages.py\\\", line 58, in _raise_exception\\n raise exc\\nfrappe.exceptions.CSRFTokenError: Invalid Request\\n\"]","_server_messages":"[\"{\\\"message\\\":\\\"Invalid Request\\\",\\\"as_table\\\":false,\\\"title\\\":\\\"Message\\\",\\\"indicator\\\":\\\"red\\\",\\\"raise_exception\\\":1,\\\"__frappe_exc_id\\\":\\\"9a4d15826b4c34e586a504e100834480b612fcd32aed29cf8482b137\\\"}\"]"} at ../helpers/frappe.ts:27 25 | if (!response.ok()) { 26 | const error = await response.text(); > 27 | throw new Error(`Failed to create ${doctype}: ${error}`); | ^ 28 | } 29 | 30 | const result = await response.json(); at createDoc (/home/runner/work/hazelnode/hazelnode/e2e/helpers/frappe.ts:27:9) at createTestWorkflow (/home/runner/work/hazelnode/hazelnode/e2e/helpers/workflow.ts:50:14) at /home/runner/work/hazelnode/hazelnode/e2e/tests/workflow-crud.spec.ts:49:24
[chromium] › e2e/tests/workflow-crud.spec.ts:23:6 › Workflow CRUD Operations › should create a new workflow via UI: e2e/pages/workflow-list.page.ts#L71
3) [chromium] › e2e/tests/workflow-crud.spec.ts:23:6 › Workflow CRUD Operations › should create a new workflow via UI Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: locator.waitFor: Timeout 15000ms exceeded. Call log: - waiting for locator('[role="dialog"]') to be visible 35 × locator resolved to hidden <div data-open="" role="dialog" tabindex="-1" aria-modal="true" id="headlessui-dialog-:r0:" data-headlessui-state="open" aria-labelledby="headlessui-dialog-title-:r2:">…</div> at ../pages/workflow-list.page.ts:71 69 | async openCreateDialog(): Promise<void> { 70 | await this.newWorkflowButton.click(); > 71 | await this.createDialog.waitFor({ state: 'visible' }); | ^ 72 | } 73 | 74 | /** at WorkflowListPage.openCreateDialog (/home/runner/work/hazelnode/hazelnode/e2e/pages/workflow-list.page.ts:71:27) at WorkflowListPage.createWorkflow (/home/runner/work/hazelnode/hazelnode/e2e/pages/workflow-list.page.ts:78:3) at /home/runner/work/hazelnode/hazelnode/e2e/tests/workflow-crud.spec.ts:28:3
[chromium] › e2e/tests/workflow-crud.spec.ts:23:6 › Workflow CRUD Operations › should create a new workflow via UI: e2e/pages/workflow-list.page.ts#L71
3) [chromium] › e2e/tests/workflow-crud.spec.ts:23:6 › Workflow CRUD Operations › should create a new workflow via UI Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: locator.waitFor: Timeout 15000ms exceeded. Call log: - waiting for locator('[role="dialog"]') to be visible 35 × locator resolved to hidden <div data-open="" role="dialog" tabindex="-1" aria-modal="true" id="headlessui-dialog-:r0:" data-headlessui-state="open" aria-labelledby="headlessui-dialog-title-:r2:">…</div> at ../pages/workflow-list.page.ts:71 69 | async openCreateDialog(): Promise<void> { 70 | await this.newWorkflowButton.click(); > 71 | await this.createDialog.waitFor({ state: 'visible' }); | ^ 72 | } 73 | 74 | /** at WorkflowListPage.openCreateDialog (/home/runner/work/hazelnode/hazelnode/e2e/pages/workflow-list.page.ts:71:27) at WorkflowListPage.createWorkflow (/home/runner/work/hazelnode/hazelnode/e2e/pages/workflow-list.page.ts:78:3) at /home/runner/work/hazelnode/hazelnode/e2e/tests/workflow-crud.spec.ts:28:3
[chromium] › e2e/tests/workflow-crud.spec.ts:23:6 › Workflow CRUD Operations › should create a new workflow via UI: e2e/pages/workflow-list.page.ts#L71
3) [chromium] › e2e/tests/workflow-crud.spec.ts:23:6 › Workflow CRUD Operations › should create a new workflow via UI TimeoutError: locator.waitFor: Timeout 15000ms exceeded. Call log: - waiting for locator('[role="dialog"]') to be visible 35 × locator resolved to hidden <div data-open="" role="dialog" tabindex="-1" aria-modal="true" id="headlessui-dialog-:r0:" data-headlessui-state="open" aria-labelledby="headlessui-dialog-title-:r2:">…</div> at ../pages/workflow-list.page.ts:71 69 | async openCreateDialog(): Promise<void> { 70 | await this.newWorkflowButton.click(); > 71 | await this.createDialog.waitFor({ state: 'visible' }); | ^ 72 | } 73 | 74 | /** at WorkflowListPage.openCreateDialog (/home/runner/work/hazelnode/hazelnode/e2e/pages/workflow-list.page.ts:71:27) at WorkflowListPage.createWorkflow (/home/runner/work/hazelnode/hazelnode/e2e/pages/workflow-list.page.ts:78:3) at /home/runner/work/hazelnode/hazelnode/e2e/tests/workflow-crud.spec.ts:28:3
[chromium] › e2e/tests/auth.spec.ts:42:6 › Authentication - Fresh state › should show error for invalid credentials: e2e/pages/login.page.ts#L47
2) [chromium] › e2e/tests/auth.spec.ts:42:6 › Authentication - Fresh state › should show error for invalid credentials Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── Error: locator.fill: Error: strict mode violation: locator('input#login_email, input[autocomplete="username"], input[name="usr"]') resolved to 3 elements: 1) <input type="text" required="" autofocus="" id="login_email" class="form-control" autocomplete="username" placeholder="jane@example.com"/> aka getByRole('textbox', { name: 'Email' }) 2) <input required="" type="email" autofocus="" id="forgot_email" class="form-control" autocomplete="username" placeholder="Email Address"/> aka locator('#forgot_email') 3) <input required="" type="email" autofocus="" class="form-control" autocomplete="username" placeholder="Email Address" id="login_with_email_link_email"/> aka locator('#login_with_email_link_email') Call log: - waiting for locator('input#login_email, input[autocomplete="username"], input[name="usr"]') at ../pages/login.page.ts:47 45 | */ 46 | async fillCredentials(email: string, password: string): Promise<void> { > 47 | await this.emailInput.fill(email); | ^ 48 | await this.passwordInput.fill(password); 49 | } 50 | at LoginPage.fillCredentials (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:47:25) at /home/runner/work/hazelnode/hazelnode/e2e/tests/auth.spec.ts:46:19
[chromium] › e2e/tests/auth.spec.ts:42:6 › Authentication - Fresh state › should show error for invalid credentials: e2e/pages/login.page.ts#L47
2) [chromium] › e2e/tests/auth.spec.ts:42:6 › Authentication - Fresh state › should show error for invalid credentials Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: locator.fill: Error: strict mode violation: locator('input#login_email, input[autocomplete="username"], input[name="usr"]') resolved to 3 elements: 1) <input type="text" required="" autofocus="" id="login_email" class="form-control" autocomplete="username" placeholder="jane@example.com"/> aka getByRole('textbox', { name: 'Email' }) 2) <input required="" type="email" autofocus="" id="forgot_email" class="form-control" autocomplete="username" placeholder="Email Address"/> aka locator('#forgot_email') 3) <input required="" type="email" autofocus="" class="form-control" autocomplete="username" placeholder="Email Address" id="login_with_email_link_email"/> aka locator('#login_with_email_link_email') Call log: - waiting for locator('input#login_email, input[autocomplete="username"], input[name="usr"]') at ../pages/login.page.ts:47 45 | */ 46 | async fillCredentials(email: string, password: string): Promise<void> { > 47 | await this.emailInput.fill(email); | ^ 48 | await this.passwordInput.fill(password); 49 | } 50 | at LoginPage.fillCredentials (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:47:25) at /home/runner/work/hazelnode/hazelnode/e2e/tests/auth.spec.ts:46:19
[chromium] › e2e/tests/auth.spec.ts:42:6 › Authentication - Fresh state › should show error for invalid credentials: e2e/pages/login.page.ts#L47
2) [chromium] › e2e/tests/auth.spec.ts:42:6 › Authentication - Fresh state › should show error for invalid credentials Error: locator.fill: Error: strict mode violation: locator('input#login_email, input[autocomplete="username"], input[name="usr"]') resolved to 3 elements: 1) <input type="text" required="" autofocus="" id="login_email" class="form-control" autocomplete="username" placeholder="jane@example.com"/> aka getByRole('textbox', { name: 'Email' }) 2) <input required="" type="email" autofocus="" id="forgot_email" class="form-control" autocomplete="username" placeholder="Email Address"/> aka locator('#forgot_email') 3) <input required="" type="email" autofocus="" class="form-control" autocomplete="username" placeholder="Email Address" id="login_with_email_link_email"/> aka locator('#login_with_email_link_email') Call log: - waiting for locator('input#login_email, input[autocomplete="username"], input[name="usr"]') at ../pages/login.page.ts:47 45 | */ 46 | async fillCredentials(email: string, password: string): Promise<void> { > 47 | await this.emailInput.fill(email); | ^ 48 | await this.passwordInput.fill(password); 49 | } 50 | at LoginPage.fillCredentials (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:47:25) at /home/runner/work/hazelnode/hazelnode/e2e/tests/auth.spec.ts:46:19
[chromium] › e2e/tests/auth.spec.ts:33:6 › Authentication - Fresh state › should login via UI: e2e/pages/login.page.ts#L47
1) [chromium] › e2e/tests/auth.spec.ts:33:6 › Authentication - Fresh state › should login via UI ─ Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── Error: locator.fill: Error: strict mode violation: locator('input#login_email, input[autocomplete="username"], input[name="usr"]') resolved to 3 elements: 1) <input type="text" required="" autofocus="" id="login_email" class="form-control" autocomplete="username" placeholder="jane@example.com"/> aka getByRole('textbox', { name: 'Email' }) 2) <input required="" type="email" autofocus="" id="forgot_email" class="form-control" autocomplete="username" placeholder="Email Address"/> aka locator('#forgot_email') 3) <input required="" type="email" autofocus="" class="form-control" autocomplete="username" placeholder="Email Address" id="login_with_email_link_email"/> aka locator('#login_with_email_link_email') Call log: - waiting for locator('input#login_email, input[autocomplete="username"], input[name="usr"]') at ../pages/login.page.ts:47 45 | */ 46 | async fillCredentials(email: string, password: string): Promise<void> { > 47 | await this.emailInput.fill(email); | ^ 48 | await this.passwordInput.fill(password); 49 | } 50 | at LoginPage.fillCredentials (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:47:25) at LoginPage.login (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:66:14) at /home/runner/work/hazelnode/hazelnode/e2e/tests/auth.spec.ts:36:3
[chromium] › e2e/tests/auth.spec.ts:33:6 › Authentication - Fresh state › should login via UI: e2e/pages/login.page.ts#L47
1) [chromium] › e2e/tests/auth.spec.ts:33:6 › Authentication - Fresh state › should login via UI ─ Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: locator.fill: Error: strict mode violation: locator('input#login_email, input[autocomplete="username"], input[name="usr"]') resolved to 3 elements: 1) <input type="text" required="" autofocus="" id="login_email" class="form-control" autocomplete="username" placeholder="jane@example.com"/> aka getByRole('textbox', { name: 'Email' }) 2) <input required="" type="email" autofocus="" id="forgot_email" class="form-control" autocomplete="username" placeholder="Email Address"/> aka locator('#forgot_email') 3) <input required="" type="email" autofocus="" class="form-control" autocomplete="username" placeholder="Email Address" id="login_with_email_link_email"/> aka locator('#login_with_email_link_email') Call log: - waiting for locator('input#login_email, input[autocomplete="username"], input[name="usr"]') at ../pages/login.page.ts:47 45 | */ 46 | async fillCredentials(email: string, password: string): Promise<void> { > 47 | await this.emailInput.fill(email); | ^ 48 | await this.passwordInput.fill(password); 49 | } 50 | at LoginPage.fillCredentials (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:47:25) at LoginPage.login (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:66:14) at /home/runner/work/hazelnode/hazelnode/e2e/tests/auth.spec.ts:36:3
[chromium] › e2e/tests/auth.spec.ts:33:6 › Authentication - Fresh state › should login via UI: e2e/pages/login.page.ts#L47
1) [chromium] › e2e/tests/auth.spec.ts:33:6 › Authentication - Fresh state › should login via UI ─ Error: locator.fill: Error: strict mode violation: locator('input#login_email, input[autocomplete="username"], input[name="usr"]') resolved to 3 elements: 1) <input type="text" required="" autofocus="" id="login_email" class="form-control" autocomplete="username" placeholder="jane@example.com"/> aka getByRole('textbox', { name: 'Email' }) 2) <input required="" type="email" autofocus="" id="forgot_email" class="form-control" autocomplete="username" placeholder="Email Address"/> aka locator('#forgot_email') 3) <input required="" type="email" autofocus="" class="form-control" autocomplete="username" placeholder="Email Address" id="login_with_email_link_email"/> aka locator('#login_with_email_link_email') Call log: - waiting for locator('input#login_email, input[autocomplete="username"], input[name="usr"]') at ../pages/login.page.ts:47 45 | */ 46 | async fillCredentials(email: string, password: string): Promise<void> { > 47 | await this.emailInput.fill(email); | ^ 48 | await this.passwordInput.fill(password); 49 | } 50 | at LoginPage.fillCredentials (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:47:25) at LoginPage.login (/home/runner/work/hazelnode/hazelnode/e2e/pages/login.page.ts:66:14) at /home/runner/work/hazelnode/hazelnode/e2e/tests/auth.spec.ts:36:3
Playwright E2E Tests
No files were found with the provided path: playwright-report/. No artifacts will be uploaded.
🎭 Playwright Run Summary
18 failed [chromium] › e2e/tests/auth.spec.ts:33:6 › Authentication - Fresh state › should login via UI ── [chromium] › e2e/tests/auth.spec.ts:42:6 › Authentication - Fresh state › should show error for invalid credentials [chromium] › e2e/tests/workflow-crud.spec.ts:23:6 › Workflow CRUD Operations › should create a new workflow via UI [chromium] › e2e/tests/workflow-crud.spec.ts:44:6 › Workflow CRUD Operations › should list existing workflows [chromium] › e2e/tests/workflow-crud.spec.ts:60:6 › Workflow CRUD Operations › should navigate to workflow editor when clicking a workflow [chromium] › e2e/tests/workflow-crud.spec.ts:82:6 › Workflow CRUD Operations › should toggle workflow enabled state [chromium] › e2e/tests/workflow-crud.spec.ts:111:6 › Workflow CRUD Operations › should cancel workflow creation dialog [chromium] › e2e/tests/workflow-crud.spec.ts:130:6 › Workflow CRUD Operations › should create workflow via API and verify in list [chromium] › e2e/tests/workflow-editor.spec.ts:17:6 › Workflow Editor › should display workflow editor canvas [chromium] › e2e/tests/workflow-editor.spec.ts:31:6 › Workflow Editor › should display existing nodes from workflow [chromium] › e2e/tests/workflow-editor.spec.ts:53:6 › Workflow Editor › should display existing edges from workflow [chromium] › e2e/tests/workflow-editor.spec.ts:78:6 › Workflow Editor › should show node palette with draggable nodes [chromium] › e2e/tests/workflow-editor.spec.ts:97:6 › Workflow Editor › should show ReactFlow controls [chromium] › e2e/tests/workflow-editor.spec.ts:112:6 › Workflow Editor › should select a node when clicked [chromium] › e2e/tests/workflow-editor.spec.ts:137:6 › Workflow Editor › should use zoom controls [chromium] › e2e/tests/workflow-editor.spec.ts:161:6 › Workflow Editor › should persist node count after page reload [chromium] › e2e/tests/workflow-editor.spec.ts:202:6 › Workflow Editor - Node Interactions › should drag and drop node from palette to canvas [chromium] › e2e/tests/workflow-editor.spec.ts:230:6 › Workflow Editor - Node Interactions › should delete node with keyboard 5 passed (2.7m)

Artifacts

Produced during runtime
Name Size Digest
test-results Expired
3.79 MB
sha256:0ddfa09a4bfa7ded9f709deab98062db56a9ac24613ccf6fd9e4762bca1cdd94