fix(cv): align preview pagination with native PDF

This commit is contained in:
cesnimda
2026-10-07 08:46:43 +02:00
parent 046dc304aa
commit efc9e7bdd4
182 changed files with 16092 additions and 47 deletions
+11 -5
View File
@@ -71,13 +71,16 @@ test("[PRES-C06 C08 C09 C12] native preview/PDF fidelity corpus records unchange
await page.goto(`/career/builder/${variant.id}`);
await expect(page.getByTitle("CV preview page 1", { exact: true })).toBeVisible();
const iframe = page.getByTitle("CV preview", { exact: true });
await expect.poll(async () => iframe.evaluate(element => !!(element as HTMLIFrameElement).contentDocument?.querySelector(".name"))).toBe(true);
await expect.poll(async () => iframe.evaluate(element => (element as HTMLIFrameElement).contentDocument?.documentElement?.dataset.cvPreviewReady)).toBe("true");
const measured = await iframe.evaluate(async element => {
const frame = element as HTMLIFrameElement;
const doc = frame.contentDocument!;
await doc.fonts.ready;
await new Promise<void>(resolve => frame.contentWindow!.requestAnimationFrame(() => frame.contentWindow!.requestAnimationFrame(() => resolve())));
const win = frame.contentWindow!;
const geometry = doc.documentElement.dataset;
const physicalWidth = Number(geometry.cvPreviewWidth);
const physicalHeight = Number(geometry.cvPreviewHeight);
const css = (selector: string) => {
const node = doc.querySelector(selector);
if (!node) return null;
@@ -93,12 +96,15 @@ test("[PRES-C06 C08 C09 C12] native preview/PDF fidelity corpus records unchange
for (const match of (node.textContent || "").matchAll(/\b[SEBPR]\d{2}\b/g)) {
const range = doc.createRange();
range.setStart(node, match.index!); range.setEnd(node, match.index! + match[0].length);
const rect = range.getBoundingClientRect();
const rect = range.getClientRects()[0];
const style = win.getComputedStyle(node.parentElement!);
tokens.push({ token: match[0], x: rect.x, y: rect.y, width: rect.width, height: rect.height, fontSize: style.fontSize, fontFamily: style.fontFamily, color: style.color });
// Native screen columns are horizontal. Normalize to the same physical-page
// coordinate system used by the unchanged PDF oracle, retaining raw evidence.
const pageIndex = Math.floor(rect.x / physicalWidth);
tokens.push({ token: match[0], x: rect.x - pageIndex * physicalWidth, y: rect.y + pageIndex * physicalHeight, rawX: rect.x, rawY: rect.y, page: pageIndex + 1, width: rect.width, height: rect.height, fontSize: style.fontSize, fontFamily: style.fontFamily, color: style.color });
}
}
return { width: frame.clientWidth, contentHeight: Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight), text: doc.body.innerText, tokens, body: css("body"), page: css(".page"), header: css(".header,.hero"), main: css(".main"), sidebar: css(".sidebar"), parsedRules: Array.from(doc.styleSheets).flatMap(sheet => Array.from(sheet.cssRules).map(rule => rule.cssText)), sections: Array.from(doc.querySelectorAll(".section")).map(node => ({ key: node.className, title: node.querySelector("h2")?.textContent, y: node.getBoundingClientRect().y })), effectiveMargin: win.getComputedStyle(doc.documentElement).getPropertyValue("--cv-page-margin"), userAgent: win.navigator.userAgent };
return { width: physicalWidth, contentHeight: Number(geometry.cvPreviewPages) * physicalHeight, usableHeight: Number(geometry.cvPreviewUsableHeight), layoutDurationMs: Number(geometry.cvPreviewDurationMs), text: doc.body.innerText, tokens, body: css("body"), page: css(".page"), header: css(".header,.hero"), main: css(".main"), sidebar: css(".sidebar"), parsedRules: Array.from(doc.styleSheets).flatMap(sheet => Array.from(sheet.cssRules).map(rule => rule.cssText)), sections: Array.from(doc.querySelectorAll(".section")).map(node => ({ key: node.className, title: node.querySelector("h2")?.textContent, fragments: Array.from(node.getClientRects()).map(rect => ({ x: rect.x, y: rect.y, width: rect.width, height: rect.height })) })), effectiveMargin: win.getComputedStyle(doc.documentElement).getPropertyValue("--cv-page-margin"), userAgent: win.navigator.userAgent };
});
expect(measured.text, fixture.key).not.toContain("HIDDEN-MARKER");
const pdf = await page.request.post(`${apiUrl}/cv/variants/${variant.id}/export-pdf`, { headers });
@@ -117,7 +123,7 @@ test("[PRES-C06 C08 C09 C12] native preview/PDF fidelity corpus records unchange
const capture = await browser.newPage({ viewport: { width: Math.ceil(measured.width), height: Math.ceil(height) } });
try {
await capture.setContent(srcDoc!);
await capture.evaluate(async () => { await document.fonts.ready; await new Promise<void>(resolve => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))); });
await expect.poll(() => capture.evaluate(() => document.documentElement.dataset.cvPreviewReady)).toBe("true");
await capture.screenshot({ path: path.join(directory, `preview-${index}.png`) });
} finally { await capture.close(); }
}