import { expect, test } from '@playwright/test'; import { expectCtaHierarchy, expectDisclosureLayer, expectFooterLinks, expectHomepageHeroCtaPair, expectHomepageHeroOrder, expectHomepageHeroRouteTargets, expectHomepageHeroStructure, expectHomepageHeroVisibleOnMobile, expectHomepageSectionOrder, expectMobileReadability, expectNavigationVsCtaDifferentiation, expectNoBodyHorizontalOverflow, expectOnwardRouteReachable, expectPageFamily, expectPrimaryNavigation, expectShell, visitPage, } from './smoke-helpers'; const forbiddenHomepageTerms = [ 'AstroDeck', 'Open Source', 'MIT Licensed', 'TenantCTRL', 'TenantPilot', 'TenantAtlas', ] as const; async function expectForbiddenHomepageResidueAbsent(page: import('@playwright/test').Page): Promise { const body = page.locator('body'); const metadata = await page.locator('head').evaluate((head) => { const title = document.title; const meta = Array.from(head.querySelectorAll('meta')) .map((element) => element.getAttribute('content') ?? '') .join(' '); const canonical = head.querySelector('link[rel="canonical"]')?.getAttribute('href') ?? ''; return `${title} ${meta} ${canonical}`; }); for (const term of forbiddenHomepageTerms) { await expect(body).not.toContainText(new RegExp(term, 'i')); expect(metadata, `Homepage metadata should not contain ${term}`).not.toMatch(new RegExp(term, 'i')); } } test('home first read positions Tenantial with one clear action hierarchy', async ({ page }) => { await visitPage(page, '/'); await expectShell(page, 'Evidence-first governance for Microsoft tenants.'); await expectPageFamily(page, 'landing'); await expectDisclosureLayer(page, '1'); await expectDisclosureLayer(page, '2'); await expectPrimaryNavigation(page); await expectNavigationVsCtaDifferentiation(page); await expectFooterLinks(page); await expectCtaHierarchy(page, 'Book a demo', 'Explore the platform'); await expect(page.getByRole('main').getByRole('link', { name: 'Book a demo' }).first()).toBeVisible(); await expect(page.getByRole('main').getByRole('link', { name: 'Explore the platform' }).first()).toBeVisible(); await expect(page.getByRole('heading', { level: 1 })).toHaveCount(1); await expectForbiddenHomepageResidueAbsent(page); const skipLink = page.getByRole('link', { name: 'Skip to content' }); await page.keyboard.press('Tab'); await expect(skipLink).toBeFocused(); }); test('homepage hero explains Tenantial, Microsoft tenant context, and required CTA routes', async ({ page }) => { await visitPage(page, '/'); await expectHomepageHeroStructure(page); await expect(page.locator('[data-homepage-hero="true"] [data-hero-eyebrow]')).toContainText( /governance that earns trust/i, ); await expect( page.locator('[data-homepage-hero="true"] [data-hero-heading]').getByRole('heading', { level: 1, name: 'Evidence-first governance for Microsoft tenants.', }), ).toBeVisible(); await expect(page.locator('[data-homepage-hero="true"] [data-hero-supporting-copy]')).toContainText( /backup and restore with confidence\. detect drift before it becomes audit work\. preserve snapshot history/i, ); await expectHomepageHeroCtaPair(page, 'Book a demo', 'Explore the platform'); await expectHomepageHeroRouteTargets(page, ['/contact', '/product']); }); test('homepage uses neutral trust statements and the six required feature pillars', async ({ page }) => { await visitPage(page, '/'); await expect(page.locator('[data-section="trustbar"]')).toBeVisible(); await expect(page.locator('[data-section="trustbar"]')).toContainText(/Microsoft tenant focused/i); await expect(page.locator('[data-section="trustbar"]')).toContainText(/Evidence-oriented workflows/i); await expect(page.locator('[data-section="trustbar"]')).toContainText(/Designed for audit review/i); await expect(page.locator('[data-section="trustbar"]')).toContainText(/Operator-led governance/i); const pillars = page.locator('[data-section="feature-pillars"]'); await expect(pillars).toBeVisible(); for (const capability of ['Backup', 'Restore', 'Drift Detection', 'Evidence', 'Audit Trail', 'Governance Reviews']) { await expect(pillars.getByRole('heading', { name: capability, exact: true })).toBeVisible(); } await expect(page.locator('body')).not.toContainText(/SOC 2|ISO\s?\d*|99\.9%|trusted by|customer logos/i); }); test('homepage dashboard preview is static, responsive, and explains status without color alone', async ({ page, }) => { await visitPage(page, '/'); const preview = page.locator('[data-dashboard-preview]').first(); await expect(preview).toBeVisible(); await expect(preview).toContainText('Static demo preview'); await expect(preview).toContainText('Demo values'); await expect(preview).toContainText('92%'); await expect(preview).toContainText('14'); await expect(preview).toContainText('7'); await expect(preview).toContainText('1,248'); await expect(preview).toContainText('98%'); for (const panel of [ 'Recent findings', 'Drift timeline', 'Backups and restores', 'Governance reviews', 'Evidence spotlight', ]) { await expect(preview.getByText(panel, { exact: true })).toBeVisible(); } for (const status of ['Healthy', 'Review required', 'Critical', 'Review-ready']) { await expect(preview.getByText(status, { exact: true }).first()).toBeVisible(); } await expect(preview).not.toContainText(/real[- ]?time|streaming|live tenant feed|May 19|Updated 2m ago/i); }); test('homepage keeps the final CTA and launch-readiness sections in order', async ({ page }) => { await visitPage(page, '/'); await expectHomepageSectionOrder(page, ['hero', 'trustbar', 'feature-pillars', 'cta']); await expect(page.locator('[data-section="cta"]')).toContainText( 'Build tenant governance on evidence, not assumptions.', ); await expectOnwardRouteReachable(page, ['/product', '/contact']); }); test.describe('homepage mobile', () => { test.use({ viewport: { width: 390, height: 844 } }); test('homepage remains readable on narrow screens without body overflow', async ({ page }) => { await visitPage(page, '/'); await expectMobileReadability(page); await expectNoBodyHorizontalOverflow(page); await expect(page.locator('[data-section="trustbar"]')).toBeVisible(); await expect(page.locator('[data-section="feature-pillars"]')).toBeVisible(); await expect(page.locator('[data-dashboard-preview]').first()).toBeVisible(); }); test('homepage hero preserves meaning order and hero route intent on narrow screens', async ({ page }) => { await visitPage(page, '/'); await expectHomepageHeroOrder(page, [ 'eyebrow', 'headline', 'supporting-copy', 'cta-pair', 'trust-subclaims', 'product-near-visual', ]); await expectHomepageHeroVisibleOnMobile(page); await expectHomepageHeroRouteTargets(page, ['/contact', '/product']); }); }); test('product keeps the connected operating model readable without collapsing into a feature list', async ({ page, }) => { await visitPage(page, '/product'); await expectShell(page, /operating model|restore posture|governance/i); await expectPageFamily(page, 'landing'); await expectDisclosureLayer(page, '1'); await expectDisclosureLayer(page, '2'); await expectPrimaryNavigation(page); await expectNavigationVsCtaDifferentiation(page); await expectFooterLinks(page); await expect( page.getByRole('heading', { name: 'Explain what the product does before asking for buyer trust.' }), ).toBeVisible(); await expectCtaHierarchy(page, 'Review the trust posture', 'Start the working session'); await expect(page.getByRole('main').getByRole('link', { name: 'Read the changelog' }).first()).toBeVisible(); });