test(i18n): qualify CV singular captions and preserved editor behavior

This commit is contained in:
cesnimda
2026-11-04 13:21:23 +01:00
parent 122956b6a3
commit e70c7098cd
93 changed files with 2341 additions and 7 deletions
+14 -4
View File
@@ -10,14 +10,16 @@ const { translations } = await import(`data:text/javascript;base64,${Buffer.from
const visualMatrix = process.env.A3_VISUAL_MATRIX === '1';
const evidenceOnly = process.env.A3_EVIDENCE_REVIEW === '1';
const cvJourney = process.env.A3_CV_JOURNEY === '1';
const countOnly = process.env.A3_CV_COUNTS === '1';
assert.ok(!countOnly || !(cvJourney || evidenceOnly || process.env.A3_BOUNDARY), 'CV count presentation is a separate read-only scope.');
assert.ok(!cvJourney || !(evidenceOnly || visualMatrix || process.env.A3_BOUNDARY), 'CV journey is a separate representative workflow scope.');
assert.ok(!evidenceOnly || !process.env.A3_BOUNDARY, 'Evidence review does not repeat editor boundary qualification.');
const out = path.resolve(import.meta.dirname, cvJourney ? '../../docs/ui-modernisation/visual-correction/evidence/cv-journey' : evidenceOnly ? '../../docs/ui-modernisation/visual-correction/evidence/career-evidence' : visualMatrix ? '../../docs/ui-modernisation/visual-correction/evidence/career' : '../../docs/ui-modernisation/evidence/career/browser');
const out = path.resolve(import.meta.dirname, countOnly ? '../../docs/ui-modernisation/visual-correction/evidence/cv-counts' : cvJourney ? '../../docs/ui-modernisation/visual-correction/evidence/cv-journey' : evidenceOnly ? '../../docs/ui-modernisation/visual-correction/evidence/career-evidence' : visualMatrix ? '../../docs/ui-modernisation/visual-correction/evidence/career' : '../../docs/ui-modernisation/evidence/career/browser');
fs.mkdirSync(out, { recursive: true });
const report = { screens: [], journeys: [], errors: [], unexpectedWrites: [], mockedWrites: [], exportRequests: [], downloads: [], renderReads: 0, unavailableReads: [], blockedExternal: [] };
const browser = await chromium.launch();
try {
const configurations = process.env.A3_BOUNDARY ? [320, 390, 768, 1000, 1001, 1440].map(width => [width, 'en', 'light']) : process.env.A3_PILOT ? (cvJourney ? [[390, 'en', 'light'], [1440, 'en', 'light']] : evidenceOnly ? [[320, 'en', 'light'], [1440, 'en', 'light']] : [[320, 'en', 'light']]) : (cvJourney ? [390, 1440] : visualMatrix || evidenceOnly ? [320, 360, 390, 430, 768, 1024, 1280, 1440, 1920] : [320, 390, 768, 1440]).flatMap(width => ['en', 'nb'].flatMap(language => ['light', 'dark'].map(mode => [width, language, mode])));
const configurations = process.env.A3_BOUNDARY ? [320, 390, 768, 1000, 1001, 1440].map(width => [width, 'en', 'light']) : process.env.A3_PILOT ? (cvJourney ? [[390, 'en', 'light'], [1440, 'en', 'light']] : evidenceOnly ? [[320, 'en', 'light'], [1440, 'en', 'light']] : [[320, 'en', 'light']]) : (cvJourney ? [390, 1440] : visualMatrix || evidenceOnly || countOnly ? [320, 360, 390, 430, 768, 1024, 1280, 1440, 1920] : [320, 390, 768, 1440]).flatMap(width => ['en', 'nb'].flatMap(language => ['light', 'dark'].map(mode => [width, language, mode])));
for (const [width, language, mode] of configurations) {
console.log(`Checking ${width}/${language}/${mode}`);
const t = key => { assert.ok(translations[language][key], key); return translations[language][key]; };
@@ -39,12 +41,13 @@ try {
const evidenceItems = [{ id: 1, category: 'achievement', title: 'Recorded nurse mentoring', statement: 'Mentored new colleagues in a synthetic training scenario.', tags: ['Training', 'Communication'], sourceReference: 'Synthetic review' }, { id: 2, category: 'project', title: 'Recorded electrician project', statement: 'Documented a synthetic installation handover.', tags: ['Safety'], sourceReference: 'Synthetic project notes' }];
await page.route('**/*', route => {
const req = route.request(), url = new URL(req.url()), p = url.pathname;
if ((evidenceOnly || cvJourney) && url.origin !== 'http://localhost:4338' && !(url.origin === 'http://localhost:5202' && p.startsWith('/api/'))) { report.blockedExternal.push(url.origin); return route.abort(); }
if ((evidenceOnly || cvJourney || countOnly) && url.origin !== 'http://localhost:4338' && !(url.origin === 'http://localhost:5202' && p.startsWith('/api/'))) { report.blockedExternal.push(url.origin); return route.abort(); }
if (!['localhost', '127.0.0.1'].includes(url.hostname)) { report.blockedExternal.push(url.origin); return route.abort(); }
if (!p.startsWith('/api/')) return route.continue();
const answer = data => route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(data) });
const note = action => report.mockedWrites.push({ width, language, mode, action });
if (evidenceOnly && req.method() !== 'GET') { report.unexpectedWrites.push(p); return route.abort(); }
if (countOnly && req.method() !== 'GET' && !(req.method() === 'POST' && p === '/api/cv/preview')) { report.unexpectedWrites.push(p); return route.abort(); }
if (evidenceOnly && p === '/api/career/evidence') return evidenceState === 'error' ? route.fulfill({ status: 503, contentType: 'application/json', body: '{}' }) : answer(evidenceState === 'empty' ? [] : evidenceItems);
if (cvJourney && req.method() === 'POST' && p === '/api/cv/variants') {
const body = req.postDataJSON(); assert.equal(created, false); assert.equal(body.name, 'Teacher career CV'); assert.equal(body.settings.includeProfileContact, true); assert.equal(body.settings.sectionsExplicit, true); assert.deepEqual(body.settings.sections, [{ key: 'summary' }]);
@@ -99,6 +102,13 @@ try {
if (width >= 600) await page.getByRole('tab', { name: t(key), exact: true }).click();
else { await page.getByRole('combobox', { name: t('careerWorkspaceNavigation'), exact: true }).click(); await page.getByRole('option', { name: t(key), exact: true }).click(); }
};
if (countOnly) {
await page.goto('http://localhost:4338/career/builder/3'); await expect(page.getByRole('region', { name: t('cvEditorEditingRegion'), exact: true })).toBeVisible();
const caption = page.getByText(language === 'en' ? /\b1 entry\b/ : /\b1 oppføring\b/); await expect(caption).toBeVisible(); await scan('section-count', caption);
if (width < 768) await page.getByRole('button', { name: t('cvEditorPreview'), exact: true }).click();
const preview = page.getByRole('region', { name: t('cvEditorLivePreview'), exact: true }); await expect(preview).toBeVisible(); await expect(page.getByText(language === 'en' ? '1-page CV' : 'CV på 1 side', { exact: true })).toBeVisible(); await scan('page-count', preview);
report.journeys.push({ width, language, mode, singularEntryAndPageCount: 'PASS', creationSaveImportExport: 'NOT RUN' }); await context.close(); continue;
}
if (cvJourney) {
await page.goto('http://localhost:4338/career/builder'); await expect(page.getByRole('button', { name: t('cvDashboardNewCv'), exact: true })).toBeEnabled(); await scan('library');
await page.getByRole('button', { name: t('cvDashboardNewCv'), exact: true }).click();
@@ -174,7 +184,7 @@ try {
report.journeys.push({ width, language, mode, all14KeyboardEditTargets: 'PASS', canonicalSaveStableIds: 'PASS', legacyImportComparisonSelectionNoApply: 'PASS', libraryKeyboardOpen: 'PASS', cvResponsiveRename: 'PASS', letterResponsiveManualSave: 'PASS' });
await context.close();
}
assert.equal(report.screens.length, configurations.length * (cvJourney ? 5 : 6)); assert.equal(report.journeys.length, configurations.length); assert.equal(report.mockedWrites.length, evidenceOnly ? 0 : configurations.length * (cvJourney ? 2 : 3)); assert.equal(report.exportRequests.length, cvJourney ? configurations.length : 0); assert.equal(report.downloads.length, cvJourney ? configurations.length : 0);
assert.equal(report.screens.length, configurations.length * (countOnly ? 2 : cvJourney ? 5 : 6)); assert.equal(report.journeys.length, configurations.length); assert.equal(report.mockedWrites.length, evidenceOnly || countOnly ? 0 : configurations.length * (cvJourney ? 2 : 3)); assert.equal(report.exportRequests.length, cvJourney ? configurations.length : 0); assert.equal(report.downloads.length, cvJourney ? configurations.length : 0);
assert.deepEqual(report.errors, []); assert.deepEqual(report.unexpectedWrites, []); assert.ok(report.blockedExternal.every(origin => origin === 'https://fonts.googleapis.com'));
console.log(`PASS:${report.journeys.length} controlled journeys,${report.screens.length} axe scans/captures,${report.mockedWrites.length} fixture mutations.`);
} finally {