fix(cv): align preview pagination with native PDF
This commit is contained in:
@@ -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(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user