diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md index bddb767a1..3ff3c6921 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -1354,7 +1354,10 @@ of the product. Secondary disclosures such as telemetry must stay subordinate to that orientation job: keep them as footer-level links into the canonical privacy/settings surfaces, and do not let them crowd out the migration -wayfinding copy. +wayfinding copy. The supporting docs CTA on that surface should likewise stay +route-oriented: use a neutral `Navigation guide` label and plain present-tense +copy that helps operators understand the current IA, rather than reviving +`Migration guide` branding that pulls the tour back into v5 historical framing. That state owner now also owns public-demo suppression: the modal must stay closed until `sessionPresentationPolicyResolved()` is true and must fail closed when `presentationPolicyIsDemoMode()` resolves true, so the public demo does diff --git a/frontend-modern/src/components/shared/__tests__/WhatsNewModal.test.tsx b/frontend-modern/src/components/shared/__tests__/WhatsNewModal.test.tsx index ea13235d3..571a75fcc 100644 --- a/frontend-modern/src/components/shared/__tests__/WhatsNewModal.test.tsx +++ b/frontend-modern/src/components/shared/__tests__/WhatsNewModal.test.tsx @@ -71,10 +71,10 @@ describe('WhatsNewModal', () => { const dialog = await screen.findByRole('dialog', { name: 'Welcome to Pulse v6' }); expect(dialog).toBeInTheDocument(); expect(within(dialog).getByText('Step 1 of 5')).toBeInTheDocument(); - expect(within(dialog).getByText('V5 to V6')).toBeInTheDocument(); - expect(within(dialog).getByText(/overview for health, alerts, capacity/i)).toBeInTheDocument(); + expect(within(dialog).getByText('Quick Tour')).toBeInTheDocument(); + expect(within(dialog).getByText(/Start here for health, alerts, capacity/i)).toBeInTheDocument(); expect(within(dialog).queryByText('Where Things Moved')).not.toBeInTheDocument(); - expect(within(dialog).getByRole('link', { name: 'Migration guide' })).toBeInTheDocument(); + expect(within(dialog).getByRole('link', { name: 'Navigation guide' })).toBeInTheDocument(); expect(within(dialog).getByRole('link', { name: 'Telemetry details' })).toBeInTheDocument(); }); @@ -128,33 +128,33 @@ describe('WhatsNewModal', () => { it('advances through the guided tour and finishes on the last step', async () => { render(() => ); - expect(await screen.findByText(/overview for health, alerts, capacity/i)).toBeInTheDocument(); + expect(await screen.findByText(/Start here for health, alerts, capacity/i)).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: 'Next' })); - expect(await screen.findByText(/Systems live here: nodes, hosts, clusters/i)).toBeInTheDocument(); + expect(await screen.findByText(/Use this for nodes, hosts, clusters/i)).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: 'Next' })); - expect(await screen.findByText(/If you looked for guests in v5/i)).toBeInTheDocument(); + expect(await screen.findByText(/Use this for VMs, containers, and pods/i)).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: 'Next' })); - expect(await screen.findByText(/Datastores, pools, disks, and capacity live here/i)).toBeInTheDocument(); + expect(await screen.findByText(/Use this for datastores, pools, disks, and capacity/i)).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: 'Next' })); - expect(await screen.findByText(/Backups, snapshots, and replication live here/i)).toBeInTheDocument(); + expect(await screen.findByText(/Use this for backups, snapshots, and replication/i)).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Done' })).toBeInTheDocument(); }); it('lets the user jump to a tour stop directly from the stop map', async () => { render(() => ); - expect(await screen.findByText(/overview for health, alerts, capacity/i)).toBeInTheDocument(); + expect(await screen.findByText(/Start here for health, alerts, capacity/i)).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: /Workloads/i })); - expect(await screen.findByText(/If you looked for guests in v5/i)).toBeInTheDocument(); + expect(await screen.findByText(/Use this for VMs, containers, and pods/i)).toBeInTheDocument(); expect(screen.getByText('Step 3 of 5')).toBeInTheDocument(); }); - it('routes the docs CTA through the migration guide', async () => { + it('routes the docs CTA through the navigation guide', async () => { render(() => ); - const docsLink = await screen.findByRole('link', { name: 'Migration guide' }); + const docsLink = await screen.findByRole('link', { name: 'Navigation guide' }); expect(docsLink).toHaveAttribute('href', '/docs/MIGRATION_UNIFIED_NAV.md'); }); }); diff --git a/frontend-modern/src/components/shared/whatsNewModalModel.ts b/frontend-modern/src/components/shared/whatsNewModalModel.ts index af4fd6342..94fb79bed 100644 --- a/frontend-modern/src/components/shared/whatsNewModalModel.ts +++ b/frontend-modern/src/components/shared/whatsNewModalModel.ts @@ -14,47 +14,47 @@ export const WHATS_NEW_PRIVACY_URL = PRIVACY_DOC_URL; export const WHATS_NEW_FEATURE_CARDS: WhatsNewFeatureCard[] = [ { accent: 'border-indigo-200 bg-indigo-50 dark:border-indigo-800 dark:bg-indigo-900', - description: 'Your new overview for health, alerts, capacity, and recent activity.', + description: 'Start here for health, alerts, capacity, and recent activity.', icon: 'dashboard', target: 'dashboard', title: 'Dashboard', }, { accent: 'border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-900', - description: 'Systems live here: nodes, hosts, clusters, and other platform roots.', + description: 'Use this for nodes, hosts, clusters, and other platform roots.', icon: 'infrastructure', target: 'infrastructure', title: 'Infrastructure', }, { accent: 'border-purple-200 bg-purple-50 dark:border-purple-800 dark:bg-purple-900', - description: 'VMs, containers, and pods live here. If you looked for guests in v5, start here.', + description: 'Use this for VMs, containers, and pods.', icon: 'workloads', target: 'workloads', title: 'Workloads', }, { accent: 'border-emerald-200 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-900', - description: 'Datastores, pools, disks, and capacity live here across platforms.', + description: 'Use this for datastores, pools, disks, and capacity.', icon: 'storage', target: 'storage', title: 'Storage', }, { accent: 'border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-amber-900', - description: 'Backups, snapshots, and replication live here.', + description: 'Use this for backups, snapshots, and replication.', icon: 'recovery', target: 'recovery', title: 'Recovery', }, ]; -export const WHATS_NEW_KICKER_LABEL = 'V5 to V6'; +export const WHATS_NEW_KICKER_LABEL = 'Quick Tour'; export const WHATS_NEW_TITLE = 'Welcome to Pulse v6'; export const WHATS_NEW_PROGRESS_PREFIX = 'Step'; export const WHATS_NEW_BACK_LABEL = 'Back'; export const WHATS_NEW_CLOSE_LABEL = 'Close'; -export const WHATS_NEW_DOCS_LABEL = 'Migration guide'; +export const WHATS_NEW_DOCS_LABEL = 'Navigation guide'; export const WHATS_NEW_DO_NOT_SHOW_LABEL = "Don't show again"; export const WHATS_NEW_NEXT_LABEL = 'Next'; export const WHATS_NEW_PRIMARY_ACTION_LABEL = 'Done'; diff --git a/tests/integration/tests/19-telemetry-disclosure.spec.ts b/tests/integration/tests/19-telemetry-disclosure.spec.ts index cc36b72e1..d61ad9e29 100644 --- a/tests/integration/tests/19-telemetry-disclosure.spec.ts +++ b/tests/integration/tests/19-telemetry-disclosure.spec.ts @@ -133,7 +133,7 @@ test.describe('Telemetry disclosure', () => { .not.toBe(initialPreview.install_id); }); - test('whats-new tour opens shipped privacy and migration guide pages', async ({ page }, testInfo) => { + test('whats-new tour opens shipped privacy and navigation guide pages', async ({ page }, testInfo) => { test.skip(testInfo.project.name.startsWith('mobile-'), 'Desktop-only telemetry disclosure coverage'); await page.addInitScript(() => { @@ -153,12 +153,12 @@ test.describe('Telemetry disclosure', () => { ); await expect(dialog).toHaveAttribute('aria-label', 'Welcome to Pulse v6'); await expect(dialog.getByText('Step 1 of 5')).toBeVisible(); - await expect(dialog.getByText('V5 to V6')).toBeVisible(); + await expect(dialog.getByText('Quick Tour')).toBeVisible(); await expect(assistantLauncher).toBeHidden(); await expect(spotlight).toHaveAttribute('data-tour-step', 'dashboard'); await expect(dialog).toHaveAttribute('data-tour-step', 'dashboard'); await expectSpotlightAround(spotlight, dashboardTab); - await expect(dialog.getByText(/overview for health, alerts, capacity/i)).toBeVisible(); + await expect(dialog.getByText(/Start here for health, alerts, capacity/i)).toBeVisible(); await expect(dialog.getByRole('link', { name: 'Telemetry details' })).toBeVisible(); const privacyLink = dialog.getByRole('link', { name: 'Telemetry details' }); @@ -170,7 +170,7 @@ test.describe('Telemetry disclosure', () => { 'Pulse currently has two usage-data scopes', ); - const docsLink = dialog.getByRole('link', { name: 'Migration guide' }); + const docsLink = dialog.getByRole('link', { name: 'Navigation guide' }); await expect(docsLink).toHaveAttribute('href', '/docs/MIGRATION_UNIFIED_NAV.md'); await expectPopupDoc( page,