From 747ec27d2d184da8f84d2e1cc06184d024f7f9ad Mon Sep 17 00:00:00 2001 From: Lukas Hirt Date: Fri, 24 Jul 2026 23:12:18 +0200 Subject: [PATCH 1/2] fix(frontend): mock useMessages in WorkflowBuilder unit test WorkflowBuilder.vue calls useAutomationConnect(), which calls useMessages() from @ownclouders/web-pkg at setup time. The test's mock of that module didn't include useMessages, so mounting the component threw and failed CI. Signed-off-by: Lukas Hirt --- frontend/tests/unit/WorkflowBuilder.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/tests/unit/WorkflowBuilder.spec.ts b/frontend/tests/unit/WorkflowBuilder.spec.ts index 68bd0e2..11f22bd 100644 --- a/frontend/tests/unit/WorkflowBuilder.spec.ts +++ b/frontend/tests/unit/WorkflowBuilder.spec.ts @@ -9,7 +9,8 @@ import { createGettext } from 'vue3-gettext' // auth store (no token needed since we never hit the network in this test). vi.mock('@ownclouders/web-pkg', () => ({ useRoute: () => ref({ params: { id: 'new' } }), - useAuthStore: () => ({ accessToken: 'test-token' }) + useAuthStore: () => ({ accessToken: 'test-token' }), + useMessages: () => ({ showMessage: vi.fn() }) })) // The canvas itself (pan/zoom/measuring DOM nodes) is irrelevant to this behavior and From 3a8f9d8aa84ea9896c69129d5b5c95f3ac28b2ba Mon Sep 17 00:00:00 2001 From: Lukas Hirt Date: Mon, 27 Jul 2026 14:09:45 +0200 Subject: [PATCH 2/2] fix(frontend): close auto-opened node panel before clicking canvas in e2e specs PR #20 made adding a node auto-open its config overlay, which covers the canvas and intercepts clicks meant for buttons underneath it. Most specs already closed the panel after adding a node, but automation.spec.ts and add-node-button-alignment.spec.ts never did, so their locator clicks timed out waiting for the overlay to get out of the way. Also fixes two flakes surfaced while stabilizing these: the alignment spec measured node bounding boxes before WorkflowBuilder's 50ms-delayed fitView call had settled, and the automation spec could race the workflow list's async load, causing automatedWorkflowCount to read 0 and skip the disconnect confirmation step. --- frontend/tests/e2e/add-node-button-alignment.spec.ts | 11 +++++++++++ frontend/tests/e2e/automation.spec.ts | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/frontend/tests/e2e/add-node-button-alignment.spec.ts b/frontend/tests/e2e/add-node-button-alignment.spec.ts index 2a237df..285738a 100644 --- a/frontend/tests/e2e/add-node-button-alignment.spec.ts +++ b/frontend/tests/e2e/add-node-button-alignment.spec.ts @@ -13,14 +13,25 @@ test('the "+" add-next button aligns consistently across node types', async ({ p await page.getByRole('button', { name: 'Add trigger' }).click() await page.getByRole('button', { name: 'Manual Trigger', exact: true }).click() await expect(page.locator('.workflows-node-trigger')).toBeVisible() + // Adding the node opens its Node Details panel automatically; close it before + // continuing, otherwise its overlay covers the canvas and intercepts clicks below. + await page.getByRole('button', { name: 'Close' }).click() await page.locator('.workflows-node-trigger .workflows-node-add-button').click() await page.getByRole('button', { name: 'LLM Prompt', exact: true }).click() await expect(page.locator('.workflows-node-llm')).toBeVisible() + await page.getByRole('button', { name: 'Close' }).click() await page.locator('.workflows-node-llm .workflows-node-add-button').click() await page.getByRole('button', { name: 'Add Tag', exact: true }).click() await expect(page.locator('.workflows-node-action')).toBeVisible() + await page.getByRole('button', { name: 'Close' }).click() + + // Adding a node schedules a re-fitted viewport via a 50ms-delayed `fitView` call (see + // `fitViewSoon` in WorkflowBuilder.vue — it needs Vue Flow to measure the new node's DOM + // first). Wait it out before measuring, otherwise these bounding-box reads can race that + // delayed pan/zoom and pick up transient coordinates. + await page.waitForTimeout(150) const centerOffsets: number[] = [] diff --git a/frontend/tests/e2e/automation.spec.ts b/frontend/tests/e2e/automation.spec.ts index ec0a0cb..e5af873 100644 --- a/frontend/tests/e2e/automation.spec.ts +++ b/frontend/tests/e2e/automation.spec.ts @@ -40,6 +40,9 @@ test('background execution connects automatically and can be disconnected', asyn await page.getByRole('button', { name: 'Add trigger' }).click() await page.getByRole('button', { name: 'Manual Trigger', exact: true }).click() await expect(page.locator('.workflows-node-trigger')).toBeVisible() + // Adding the node opens its Node Details panel automatically; close it before + // continuing, otherwise its overlay covers the canvas and intercepts clicks below. + await page.getByRole('button', { name: 'Close' }).click() const workflowName = `e2e automation workflow ${Date.now()}` await page.getByRole('button', { name: 'Untitled workflow' }).click() @@ -64,6 +67,10 @@ test('background execution connects automatically and can be disconnected', asyn await page.goto('/workflows/workflows') await expect(page.getByText('Background execution active')).toBeVisible() await expect(page.getByRole('button', { name: 'Connect automation' })).toHaveCount(0) + // The workflow list loads asynchronously after mount — wait for it to settle before + // opening the automation panel below, otherwise its automatedWorkflowCount prop (derived + // from that list) can still read 0 and silently skip the confirm-warning step. + await expect(page.getByText('Loading workflows...')).toBeHidden() // Disconnecting while the workflow is still active shows the warning. await page.getByRole('button', { name: 'manage' }).click()