import { test, expect } from '@playwright/test'; import { translations } from '../src/i18n/translations'; for (const language of ['en', 'nb'] as const) { test(`[P9 PRES-E01 E08] ${language} wrapped landing headings keep separate text lines`, async ({ page, context }, info) => { test.setTimeout(90000); await context.route('**/*', route => { const url = new URL(route.request().url()); return ['localhost', '127.0.0.1'].includes(url.hostname) || ['data:', 'blob:', 'about:'].includes(url.protocol) ? route.continue() : route.abort(); }); await context.addInitScript(language => localStorage.setItem('uiLanguage', language), language); const observations = []; for (const theme of ['light', 'dark']) for (const width of [320, 390, 768, 1440]) { await page.setViewportSize({ width, height: 900 }); await page.goto('/'); await page.evaluate(theme => localStorage.setItem('jobtracker.themeMode', theme), theme); await page.reload(); await expect(page.getByRole('heading', { name: translations[language].landingPreviewTitle, exact: true })).toBeVisible(); await page.evaluate(() => document.fonts.ready); const headings = await page.locator('h2').or(page.getByText(translations[language].landingReadyTitle, { exact: true })).evaluateAll(nodes => nodes.map(node => { const range = document.createRange(); range.selectNodeContents(node); const lines = [...range.getClientRects()].filter(rect => rect.width > 0).map(rect => ({ top: rect.top, bottom: rect.bottom })); return { text: node.textContent, lineHeight: getComputedStyle(node).lineHeight, lines }; })); expect(headings.length).toBeGreaterThanOrEqual(5); expect(headings.some(heading => heading.text === translations[language].landingReadyTitle)).toBe(true); if (width === 320) expect(headings.some(heading => heading.lines.length > 1)).toBe(true); for (const heading of headings) for (let index = 1; index < heading.lines.length; index++) { expect.soft(heading.lines[index].top, `${width}/${theme}: ${heading.text}`).toBeGreaterThanOrEqual(heading.lines[index - 1].bottom - 1); } expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(width + 1); observations.push({ width, theme, language, headings }); if (width === 320) await info.attach(`landing-${language}-${theme}-${width}`, { body: await page.screenshot({ fullPage: true, animations: 'disabled' }), contentType: 'image/png' }); } await info.attach('landing-line-geometry', { body: JSON.stringify(observations, null, 2), contentType: 'application/json' }); }); }