From cec08d075bfde22bf450a35fbd8aa48836c0fffa Mon Sep 17 00:00:00 2001 From: Sergey Kozyrenko Date: Fri, 24 Jul 2026 13:13:29 +0700 Subject: [PATCH] test(e2e): close three gates that could not fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dashboard laziness check asserted the Overview heading was unattached straight after goto. The route is lazy, so that is satisfied by "nothing has rendered yet": mounting the panel eagerly with forceMount still passed. Wait for the Analytics panel first — with the gate in place forceMount now fails it. The flow-detail a11y waivers matched `button[aria-label`, which waives button-name and target-size for every labelled button on the route rather than the file-manager controls that actually violate them. Anchored both on the offending nodes; the real violations stay waived and a nameless icon button or an undersized labelled button no longer does. The rejected-login smoke test asserted only the disabled half of the behaviour its name describes. Change a field and assert Sign in comes back. Co-Authored-By: Claude Opus 4.8 --- frontend/e2e/routes.ts | 6 ++++-- frontend/e2e/specs/dashboard/dashboard.spec.ts | 4 +++- frontend/e2e/specs/smoke.spec.ts | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/e2e/routes.ts b/frontend/e2e/routes.ts index 9de0908e..8ef9544d 100644 --- a/frontend/e2e/routes.ts +++ b/frontend/e2e/routes.ts @@ -74,8 +74,10 @@ export const ROUTE_MANIFEST: RouteManifestEntry[] = [ { rule: 'color-contrast', target: /text-muted-foreground\\?\/50/ }, // The tab-panel ones below are defects awaiting a fix, not accepted design. { rule: 'aria-progressbar-name', target: /bg-primary/ }, - { rule: 'button-name', target: /span\[data-slot|button\[aria-label/ }, - { rule: 'target-size', target: /text-blue-400|button\[aria-label/ }, + // Both are the Files tab's file-manager controls. Anchored on the offending nodes: matching + // `button[aria-label` instead would waive the rule for every labelled button on the route. + { rule: 'button-name', target: /tooltip-trigger.*size-8\[data-slot="button"\]/ }, + { rule: 'target-size', target: /text-blue-400|button\[aria-label="Select / }, { rule: 'color-contrast', target: /font-semibold\.truncate/ }, // The same file-manager row metadata waived on /resources — this tab embeds it. { rule: 'color-contrast', target: /text-muted-foreground\\?\/80/ }, diff --git a/frontend/e2e/specs/dashboard/dashboard.spec.ts b/frontend/e2e/specs/dashboard/dashboard.spec.ts index b0dbd8b6..b34d9c1c 100644 --- a/frontend/e2e/specs/dashboard/dashboard.spec.ts +++ b/frontend/e2e/specs/dashboard/dashboard.spec.ts @@ -26,7 +26,9 @@ test.describe('dashboard', { tag: '@coverage' }, () => { test('overview tab loads lazily and renders metrics and usage tables', async ({ page, pageErrorLog }) => { await page.goto('/dashboard'); - // Lazy: the overview metrics are not mounted while the Analytics tab is active. + // The route is lazy, so this must wait for the Analytics panel first: a bare negative + // assert is satisfied by "nothing has rendered yet" and can never fail. + await expect(page.getByRole('heading', { name: 'Flows Activity Over Time' })).toBeVisible(); // not.toBeAttached, not toBeHidden — the latter also passes for a mounted-but-hidden node, // so it would not catch the panel being eagerly mounted (all its queries firing). await expect(page.getByRole('heading', { exact: true, name: 'Total Flows' })).not.toBeAttached(); diff --git a/frontend/e2e/specs/smoke.spec.ts b/frontend/e2e/specs/smoke.spec.ts index fba878c0..7ce050fa 100644 --- a/frontend/e2e/specs/smoke.spec.ts +++ b/frontend/e2e/specs/smoke.spec.ts @@ -43,6 +43,10 @@ test.describe('smoke', { tag: '@smoke' }, () => { // react-hook-form leaves Submit disabled after a failed submit until // an input changes. await expect(page.getByRole('button', { name: 'Sign in' })).toBeDisabled(); + + await page.getByRole('textbox', { name: 'Password' }).fill('another-password'); + + await expect(page.getByRole('button', { name: 'Sign in' })).toBeEnabled(); // The 401 logs an expected browser console error, but the path must raise no // uncaught JS exception / unhandled rejection. expect(pageErrorLog.pageErrors).toEqual([]);