From 44e79ce2270217bd1aa5dd36486e89e881660a76 Mon Sep 17 00:00:00 2001 From: Eugene Vyborov Date: Wed, 10 Jun 2026 16:16:24 +0100 Subject: [PATCH] fix(e2e): repair smoke drift from #1109 + neutralize ensure-default modal race (#1134) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit frontend-e2e has been red on dev since 2026-06-10 (first on the #1114 run), unnoticed because the workflow is ui-label-gated. - smoke.spec.js: /operating-room now redirects to /operations (#1109); the old text assertions match nothing on the new page. Assert the redirect URL + Operations heading + tab strip instead — the test now also covers the legacy redirect. - api-keys-copy.spec.js: McpKeysTab onMounted fires ensure-default, which auto-creates 'Default MCP Key' and opens the key-ready modal at an arbitrary point mid-test, intercepting the Create click (both modals are fixed z-10 inset-0; later DOM node wins). beforeEach now calls ensure-default via API and reloads, making the page's own call a guaranteed no-op — the auto-modal can never appear mid-test, and the clipboard assertions always run against the test's own key modal rather than green-washing on the auto-modal. Fixes #1134 Co-Authored-By: Claude Fable 5 --- src/frontend/e2e/api-keys-copy.spec.js | 21 ++++++++++++++++++++- src/frontend/e2e/smoke.spec.js | 10 ++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/frontend/e2e/api-keys-copy.spec.js b/src/frontend/e2e/api-keys-copy.spec.js index db3a056b5..4a0270502 100644 --- a/src/frontend/e2e/api-keys-copy.spec.js +++ b/src/frontend/e2e/api-keys-copy.spec.js @@ -18,9 +18,28 @@ import { test, expect } from '@playwright/test' const MCP_KEYS_ROUTE = '/settings?tab=mcp-keys' test.describe('@smoke api-keys copy buttons (#677, #859)', () => { - test.beforeEach(async ({ context }) => { + test.beforeEach(async ({ context, page }) => { // Headless browsers gate clipboard read by default — opt in for the test. await context.grantPermissions(['clipboard-read', 'clipboard-write']) + + // #1134: McpKeysTab's onMounted fires POST /api/mcp/keys/ensure-default; + // when no user-scoped key exists it auto-creates "Default MCP Key" and + // opens the "Your MCP API Key is Ready!" modal at an arbitrary point + // mid-test — both modals are `fixed z-10 inset-0`, so the auto-modal + // lands on top and intercepts the Create click. Neutralize the race: + // call ensure-default ourselves, then reload — the remounted page's own + // ensure-default is a guaranteed no-op, so the auto-modal can never + // appear during the test body. + await page.goto(MCP_KEYS_ROUTE) + const token = await page.evaluate(() => localStorage.getItem('token')) + if (token) { + await page.request + .post('/api/mcp/keys/ensure-default', { + headers: { Authorization: `Bearer ${token}` }, + }) + .catch(() => {}) + } + await page.reload() }) test('Copy Config button writes MCP JSON to clipboard', async ({ page }) => { diff --git a/src/frontend/e2e/smoke.spec.js b/src/frontend/e2e/smoke.spec.js index 38b9bbf72..e44167249 100644 --- a/src/frontend/e2e/smoke.spec.js +++ b/src/frontend/e2e/smoke.spec.js @@ -25,11 +25,13 @@ test.describe('smoke', () => { }) test('@smoke operating room page loads', async ({ page }) => { + // #1109/#1134: /operating-room is a legacy redirect to /operations. + // Navigating the old path also covers the redirect itself. await page.goto('/operating-room') - // Either a queue list, filters, an empty state, or the title. - await expect( - page.getByText(/operating|queue|priority|all types|no items/i).first() - ).toBeVisible({ timeout: 10000 }) + await expect(page).toHaveURL(/\/operations/, { timeout: 10000 }) + await expect(page.getByRole('heading', { name: 'Operations' })).toBeVisible({ timeout: 10000 }) + // Tab strip confirms the view mounted (not just the route resolved). + await expect(page.getByRole('button', { name: 'Needs Response' })).toBeVisible() }) test('@smoke templates page loads', async ({ page }) => {