diff --git a/frontend/e2e/affected-routes.unit.test.ts b/frontend/e2e/affected-routes.unit.test.ts index 53e73d66..c8fbed50 100644 --- a/frontend/e2e/affected-routes.unit.test.ts +++ b/frontend/e2e/affected-routes.unit.test.ts @@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest'; import type { RouteSource } from './affected-routes.ts'; import { affectedRoutes } from './affected-routes.ts'; +import { ROUTE_MANIFEST } from './routes.ts'; const MANIFEST: RouteSource[] = [ { @@ -58,4 +59,12 @@ describe('affectedRoutes', () => { expect(result.map((route) => route.path)).toEqual(['/flows']); }); + + // The fake manifest above cannot catch ownership drift in the real one: a shared provider claimed + // by a single route silently scopes a run away from the other routes that mount its consumers. + it('scopes a shared provider to every route that mounts a consumer', () => { + const result = affectedRoutes(['frontend/src/providers/templates-provider.tsx'], ROUTE_MANIFEST); + + expect(result.map((route) => route.path).sort()).toEqual(['/flows/5', '/templates']); + }); }); diff --git a/frontend/e2e/routes.ts b/frontend/e2e/routes.ts index b177c2f2..c6427754 100644 --- a/frontend/e2e/routes.ts +++ b/frontend/e2e/routes.ts @@ -43,6 +43,7 @@ export interface RouteTab { export const FLOW_DETAIL_TABS: RouteTab[] = [ { name: 'Dashboard', ready: (page) => page.getByText('Usage by Model & Provider') }, { name: 'Assistant', ready: (page) => page.getByText('New assistant', { exact: true }) }, + { name: 'Automation', ready: (page) => page.getByText('No active tasks') }, { name: 'Tasks', ready: (page) => page.getByText('E2E Task Alpha') }, { name: 'Agents', ready: (page) => page.getByText('E2E agent reconnaissance') }, { name: 'Searches', ready: (page) => page.getByText('E2E search for the CVE') }, @@ -97,6 +98,8 @@ export const ROUTE_MANIFEST: RouteManifestEntry[] = [ 'src/components/shared/file-manager', 'src/components/dashboard', 'src/features/resources', + // Assistant-tab FlowForm reads useTemplates, so a provider change reaches this route too. + 'src/providers/templates-provider.tsx', ], tabs: FLOW_DETAIL_TABS, }, @@ -130,8 +133,9 @@ export const ROUTE_MANIFEST: RouteManifestEntry[] = [ a11yWaivers: [{ rule: 'aria-valid-attr-value', target: /radix-.*-trigger-/ }], cassette: dashboardCassette, path: routes.dashboard, - ready: (page) => page.getByRole('heading', { name: 'Flows Activity Over Time' }), + ready: (page) => page.getByText('E2E Alpha'), sources: ['src/pages/dashboard', 'src/components/dashboard'], + tabs: [{ name: 'Overview', ready: (page) => page.getByRole('cell', { exact: true, name: 'e2e-provider' }) }], }, { cassette: settingsPromptsCassette,