test(a11y): demonstrate clipped initial mobile CV preview

This commit is contained in:
cesnimda
2026-10-10 21:02:38 +02:00
parent 6fb440aa23
commit 84e3bb5b44
9 changed files with 144 additions and 7 deletions
@@ -1,4 +1,5 @@
import AxeBuilder from '@axe-core/playwright';
import { writeFile } from 'node:fs/promises';
import { expect, test as base, type APIRequestContext, type BrowserContext, type Page, type TestInfo } from '@playwright/test';
import { translations } from '../src/i18n/translations';
@@ -308,6 +309,42 @@ test('[P5-15-02 W08 J10] keyboard upload and import controls open the native fil
await info.attach('native-keyboard-file-chooser', { body: JSON.stringify({ outcomes, fileDataWritten: false }), contentType: 'application/json' });
});
test('[P5-15-02 C06 C09 C12] mobile edit-to-preview retains physical document measurement', async ({ page, owner }, info) => {
test.setTimeout(60_000);
const t = translations.en;
await enter(page, owner, { area: 'cv', path: `/career/builder/${owner.cvId}`, width: 390, height: 844, language: 'en', theme: 'light' });
const metrics = () => page.locator('iframe').evaluateAll(frames => frames.filter(frame => (frame as HTMLIFrameElement).contentDocument?.querySelector('.page')).map(frame => {
const doc = (frame as HTMLIFrameElement).contentDocument!;
const sheet = doc.querySelector('.page')!;
return { title: frame.getAttribute('title'), hiddenMeasurement: frame.getAttribute('aria-hidden') === 'true', frameVisible: frame.getBoundingClientRect().width > 0,
measuredWidth: Number(doc.documentElement.dataset.cvPreviewWidth), measuredPages: Number(doc.documentElement.dataset.cvPreviewPages), ready: doc.documentElement.dataset.cvPreviewReady,
physicalPageWidth: sheet.getBoundingClientRect().width, flowWidth: doc.querySelector('[data-cv-preview-flow]')?.getBoundingClientRect().width };
}));
const inEdit = await metrics();
await page.getByRole('button', { name: t.cvEditorPreview, exact: true }).press('Enter');
const preview = page.getByRole('region', { name: t.cvEditorLivePreview, exact: true });
await expect(preview).toBeVisible();
await expect(preview).toHaveAttribute('aria-busy', 'false');
await page.evaluate(async () => { await document.fonts.ready; await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))); });
const inPreview = await metrics();
const screenshot = info.outputPath('mobile-preview-measurement-390-en-light.png');
await page.screenshot({ path: screenshot, animations: 'disabled' });
await info.attach('mobile-preview-measurement', { path: screenshot, contentType: 'image/png' });
await info.attach('mobile-preview-physical-measurement', { body: JSON.stringify({ inEdit, inPreview, pageCountText: await page.getByRole('status').allTextContents(), method: 'native DOM measurements before axe; A4 physical width 210mm =793.7008CSSpx at96dpi' }), contentType: 'application/json' });
const pdf = await page.request.post(`${apiUrl}/cv/variants/${owner.cvId}/export-pdf`, { headers: owner.headers });
expect(pdf.status()).toBe(200);
const exportPath = info.outputPath('mobile-preview-export.pdf');
await writeFile(exportPath, await pdf.body());
await info.attach('mobile-preview-native-export', { path: exportPath, contentType: 'application/pdf' });
const measurement = inPreview.find(frame => frame.hiddenMeasurement)!;
expect(measurement.measuredWidth, 'hidden mobile pane must not publish a zero-width document').toBeGreaterThan(790);
expect(measurement.measuredWidth).toBeLessThan(798);
for (const frame of inPreview.filter(frame => frame.frameVisible)) {
expect(frame.flowWidth, `${frame.title} content flow matches physical paper width`).toBeGreaterThan(790);
expect(frame.flowWidth).toBeLessThan(798);
}
});
test.describe('Chromium emulated touch; not physical-device acceptance', () => {
test.use({ hasTouch: true });
test('[P5-15-02] emulated taps preserve CV modes and navigation across portrait/landscape viewport changes', async ({ page, owner }, info) => {