import { test, expect } from '@playwright/test'; test.describe('smoke — both locales render (TECH_SPEC §9.3)', () => { test('English home', async ({ page }) => { await page.goto('/'); await expect(page).toHaveTitle(/Systems Developer/); await expect(page.locator('h1')).toHaveText('Connor Babbington'); await expect(page.locator('html')).toHaveAttribute('lang', 'en-GB'); // decision facts present in the first view (chip) await expect(page.getByText('Tønsberg, Norway', { exact: true }).first()).toBeVisible(); }); test('Norwegian home', async ({ page }) => { await page.goto('/no/'); await expect(page).toHaveTitle(/Systemutvikler/); await expect(page.locator('html')).toHaveAttribute('lang', 'nb-NO'); await expect(page.getByText('Gyldig oppholdstillatelse')).toBeVisible(); }); test('hreflang alternates emitted', async ({ page }) => { await page.goto('/'); await expect(page.locator('link[hreflang="en"]')).toHaveCount(1); await expect(page.locator('link[hreflang="nb"]')).toHaveCount(1); await expect(page.locator('link[hreflang="x-default"]')).toHaveCount(1); }); test('case study shows architecture and decisions', async ({ page }) => { await page.goto('/projects/jobtrack/'); await expect(page.locator('h1')).toHaveText('JobTrack'); await expect(page.locator('#architecture svg[role="img"]')).toBeVisible(); await expect(page.locator('#decisions')).toBeVisible(); }); test('skip link is the first focusable element', async ({ page }) => { await page.goto('/'); await page.keyboard.press('Tab'); const focused = page.locator(':focus'); await expect(focused).toHaveText(/Skip to content/); }); });