From 145d66090f304b651670b30bf75e054e51ffea7f Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Thu, 23 May 2024 17:53:58 +0200 Subject: [PATCH] Introduce a `getRect` utility function for the integration tests Over time the number of integration tests that get the rectangle for a given selector has increased quite a bit, and the code to do so has consequently become duplicated. This commit refactors the integration tests to move the rectangle fetching code to a single place, which reduces the code by over 400 lines and makes the individual tests simpler. --- test/integration/caret_browsing_spec.mjs | 13 +- test/integration/freetext_editor_spec.mjs | 388 ++++----------------- test/integration/highlight_editor_spec.mjs | 85 ++--- test/integration/ink_editor_spec.mjs | 66 +--- test/integration/stamp_editor_spec.mjs | 36 +- test/integration/test_utils.mjs | 15 +- 6 files changed, 136 insertions(+), 467 deletions(-) diff --git a/test/integration/caret_browsing_spec.mjs b/test/integration/caret_browsing_spec.mjs index c7c591cc3cdec..b6247f1ce9d41 100644 --- a/test/integration/caret_browsing_spec.mjs +++ b/test/integration/caret_browsing_spec.mjs @@ -13,7 +13,7 @@ * limitations under the License. */ -import { closePages, loadAndWait } from "./test_utils.mjs"; +import { closePages, getRect, loadAndWait } from "./test_utils.mjs"; const waitForSelectionChange = (page, selection) => page.waitForFunction( @@ -38,13 +38,10 @@ describe("Caret browsing", () => { it("must move the caret down and check the selection", async () => { await Promise.all( pages.map(async ([browserName, page]) => { - const spanRect = await page.evaluate(() => { - const span = document.querySelector( - `.page[data-page-number="1"] > .textLayer > span` - ); - const { x, y, width, height } = span.getBoundingClientRect(); - return { x, y, width, height }; - }); + const spanRect = await getRect( + page, + `.page[data-page-number="1"] > .textLayer > span` + ); await page.mouse.click( spanRect.x + 1, spanRect.y + spanRect.height / 2, diff --git a/test/integration/freetext_editor_spec.mjs b/test/integration/freetext_editor_spec.mjs index 36c9409a2a5b0..a32edab883d2f 100644 --- a/test/integration/freetext_editor_spec.mjs +++ b/test/integration/freetext_editor_spec.mjs @@ -22,6 +22,7 @@ import { getEditors, getEditorSelector, getFirstSerialized, + getRect, getSelectedEditors, getSerialized, hover, @@ -81,11 +82,11 @@ const switchToFreeText = async page => { await page.waitForSelector(".annotationEditorLayer.freetextEditing"); }; -const getXY = (page, selector) => - page.evaluate(sel => { - const bbox = document.querySelector(sel).getBoundingClientRect(); - return `${bbox.x}::${bbox.y}`; - }, selector); +const getXY = async (page, selector) => { + const rect = await getRect(page, selector); + return `${rect.x}::${rect.y}`; +}; + const waitForPositionChange = (page, selector, xy) => page.waitForFunction( (sel, currentXY) => { @@ -128,12 +129,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -142,15 +138,7 @@ describe("FreeText Editor", () => { }); await page.type(`${getEditorSelector(0)} .internal`, data); - const editorRect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { - x, - y, - width, - height, - }; - }); + const editorRect = await getRect(page, getEditorSelector(0)); // Commit. await page.mouse.click( @@ -192,10 +180,7 @@ describe("FreeText Editor", () => { it("must copy/paste", async () => { // Run sequentially to avoid clipboard issues. for (const [browserName, page] of pages) { - const editorRect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, getEditorSelector(0)); // Select the editor created previously. await page.mouse.click( @@ -255,10 +240,7 @@ describe("FreeText Editor", () => { it("must check that a paste has been undone", async () => { // Run sequentially to avoid clipboard issues. for (const [, page] of pages) { - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -267,10 +249,7 @@ describe("FreeText Editor", () => { }); await page.type(`${getEditorSelector(3)} .internal`, data); - const editorRect = await page.$eval(getEditorSelector(3), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, getEditorSelector(3)); // Commit. await page.mouse.click( @@ -331,12 +310,9 @@ describe("FreeText Editor", () => { await scrollIntoView(page, `span[pdfjs="true"]`); - const [stacksRect, oldAriaOwns] = await page.$eval( - `span[pdfjs="true"]`, - el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return [{ x, y, width, height }, el.getAttribute("aria-owns")]; - } + const stacksRect = await getRect(page, `span[pdfjs="true"]`); + const oldAriaOwns = await page.$eval(`span[pdfjs="true"]`, el => + el.getAttribute("aria-owns") ); expect(oldAriaOwns).withContext(`In ${browserName}`).toEqual(null); @@ -373,10 +349,7 @@ describe("FreeText Editor", () => { it("must check that right click doesn't select", async () => { await Promise.all( pages.map(async ([browserName, page]) => { - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); await clearAll(page); @@ -387,10 +360,7 @@ describe("FreeText Editor", () => { }); await page.type(`${getEditorSelector(8)} .internal`, data); - const editorRect = await page.$eval(getEditorSelector(8), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, getEditorSelector(8)); // Commit. await page.keyboard.press("Escape"); @@ -438,10 +408,7 @@ describe("FreeText Editor", () => { it("must check that text change can be undone/redone", async () => { // Run sequentially to avoid clipboard issues. for (const [browserName, page] of pages) { - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); await clearAll(page); @@ -454,10 +421,7 @@ describe("FreeText Editor", () => { for (let i = 0; i < 5; i++) { await page.type(`${editorSelector} .internal`, "A"); - const editorRect = await page.$eval(editorSelector, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, editorSelector); // Commit. await page.mouse.click( @@ -536,10 +500,7 @@ describe("FreeText Editor", () => { expect(text).withContext(`In ${browserName}`).toEqual("A"); // Add a new A. - let editorRect = await page.$eval(editorSelector, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + let editorRect = await getRect(page, editorSelector); await page.mouse.click( editorRect.x + editorRect.width / 2, editorRect.y + editorRect.height / 2, @@ -548,10 +509,7 @@ describe("FreeText Editor", () => { await page.waitForSelector(`${editorSelector} .overlay:not(.enabled)`); await page.type(`${editorSelector} .internal`, "A"); - editorRect = await page.$eval(editorSelector, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + editorRect = await getRect(page, editorSelector); // Commit. await page.mouse.click( @@ -582,12 +540,7 @@ describe("FreeText Editor", () => { for (const [browserName, page] of pages) { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const editorCenters = []; let lastX = rect.x + rect.width / 10; @@ -599,15 +552,7 @@ describe("FreeText Editor", () => { }); await page.type(`${getEditorSelector(i)} .internal`, data); - const editorRect = await page.$eval(getEditorSelector(i), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { - x, - y, - width, - height, - }; - }); + const editorRect = await getRect(page, getEditorSelector(i)); lastX = editorRect.x + editorRect.width + 10; editorCenters.push({ x: editorRect.x + editorRect.width / 2, @@ -782,12 +727,7 @@ describe("FreeText Editor", () => { continue; } - const rect = await page.$eval(annotationLayerSelector, el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, annotationLayerSelector); const data = `Hello PDF.js World !! on page ${pageNumber}`; expected.push(data); @@ -925,12 +865,7 @@ describe("FreeText Editor", () => { for (let step = 0; step < 3; step++) { await firstPageOnTop(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = `Hello ${step}`; const x = Math.max(rect.x + 0.1 * rect.width, 10); @@ -1027,10 +962,7 @@ describe("FreeText Editor", () => { const serialized = await getSerialized(page); expect(serialized).withContext(`In ${browserName}`).toEqual([]); - const editorRect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, getEditorSelector(0)); // Select the annotation we want to move. await page.mouse.click(editorRect.x + 2, editorRect.y + 2); @@ -1068,10 +1000,7 @@ describe("FreeText Editor", () => { let editorIds = await getEditors(page, "freeText"); expect(editorIds.length).withContext(`In ${browserName}`).toEqual(6); - const editorRect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, getEditorSelector(0)); await page.mouse.click( editorRect.x + editorRect.width / 2, editorRect.y + editorRect.height / 2, @@ -1191,10 +1120,7 @@ describe("FreeText Editor", () => { }); const editorSelector = getEditorSelector(1); - const editorRect = await page.$eval(editorSelector, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, editorSelector); await page.mouse.click( editorRect.x + editorRect.width / 2, editorRect.y + editorRect.height / 2, @@ -1286,10 +1212,7 @@ describe("FreeText Editor", () => { let editorIds = await getEditors(page, "freeText"); expect(editorIds.length).withContext(`In ${browserName}`).toEqual(6); - const editorRect = await page.$eval(getEditorSelector(3), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, getEditorSelector(3)); await page.mouse.click( editorRect.x + editorRect.width / 2, editorRect.y + editorRect.height / 2 @@ -1356,10 +1279,7 @@ describe("FreeText Editor", () => { const editorIds = await getEditors(page, "freeText"); expect(editorIds.length).withContext(`In ${browserName}`).toEqual(6); - const editorRect = await page.$eval(getEditorSelector(1), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, getEditorSelector(1)); await page.mouse.click( editorRect.x + editorRect.width / 2, editorRect.y + editorRect.height / 2 @@ -1517,10 +1437,7 @@ describe("FreeText Editor", () => { ); await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -1529,15 +1446,7 @@ describe("FreeText Editor", () => { }); await page.type(`${getEditorSelector(0)} .internal`, data); - const editorRect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { - x, - y, - width, - height, - }; - }); + const editorRect = await getRect(page, getEditorSelector(0)); // Commit. await page.mouse.click( @@ -1573,9 +1482,9 @@ describe("FreeText Editor", () => { await selectAll(page); - const prevWidth = await page.$eval( - ".selectedEditor .internal", - el => el.getBoundingClientRect().width + const { width: prevWidth } = await getRect( + page, + ".selectedEditor .internal" ); page.evaluate(() => { @@ -1649,12 +1558,7 @@ describe("FreeText Editor", () => { continue; } - const rect = await page.$eval(annotationLayerSelector, el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, annotationLayerSelector); const data = `Hello PDF.js World !! on page ${pageNumber}`; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -1767,12 +1671,7 @@ describe("FreeText Editor", () => { }; for (const n of [0, 1, 2, 3, 4]) { - const rect = await page.$eval(getEditorSelector(n), el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const rect = await getRect(page, getEditorSelector(n)); const editorPng = await page.screenshot({ clip: rect, type: "png", @@ -1937,12 +1836,7 @@ describe("FreeText Editor", () => { [2, "TR"], [3, "TL"], ]) { - const rect = await page.$eval(getEditorSelector(n), el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const rect = await getRect(page, getEditorSelector(n)); const editorPng = await page.screenshot({ clip: rect, type: "png", @@ -2014,10 +1908,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -2026,15 +1917,7 @@ describe("FreeText Editor", () => { }); await page.type(`${getEditorSelector(0)} .internal`, data); - const editorRect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { - x, - y, - width, - height, - }; - }); + const editorRect = await getRect(page, getEditorSelector(0)); // Commit. await page.mouse.click( @@ -2081,10 +1964,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; const selectorEditor = getEditorSelector(0); @@ -2094,15 +1974,7 @@ describe("FreeText Editor", () => { }); await page.type(`${selectorEditor} .internal`, data); - const editorRect = await page.$eval(selectorEditor, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { - x, - y, - width, - height, - }; - }); + const editorRect = await getRect(page, selectorEditor); // Commit. await page.mouse.click( @@ -2210,10 +2082,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await clearAll(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; let selectorEditor = getEditorSelector(1); @@ -2223,15 +2092,7 @@ describe("FreeText Editor", () => { }); await page.type(`${selectorEditor} .internal`, data); - const editorRect = await page.$eval(selectorEditor, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { - x, - y, - width, - height, - }; - }); + const editorRect = await getRect(page, selectorEditor); // Commit. await page.mouse.click( @@ -2337,10 +2198,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -2399,10 +2257,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - let rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + let rect = await getRect(page, ".annotationEditorLayer"); await page.mouse.click(rect.x + 100, rect.y + 100); await page.waitForSelector(getEditorSelector(0), { @@ -2416,10 +2271,7 @@ describe("FreeText Editor", () => { `${getEditorSelector(0)} .overlay.enabled` ); - rect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + rect = await getRect(page, getEditorSelector(0)); await page.mouse.click( rect.x + 5 * rect.width, @@ -2436,10 +2288,7 @@ describe("FreeText Editor", () => { `${getEditorSelector(1)} .overlay.enabled` ); - rect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + rect = await getRect(page, getEditorSelector(0)); await page.mouse.click( rect.x + 5 * rect.width, @@ -2463,20 +2312,10 @@ describe("FreeText Editor", () => { .withContext(`In ${browserName}`) .toEqual(1); - const getY = selector => - page.evaluate( - sel => document.querySelector(sel).getBoundingClientRect().y, - selector - ); - const height = await page.evaluate( - sel => document.querySelector(sel).getBoundingClientRect().height, - getEditorSelector(0) - ); - - const y0 = await getY(getEditorSelector(0)); + const { y: y0, height } = await getRect(page, getEditorSelector(0)); const selectorEditor = getEditorSelector(1); let xy = await getXY(page, selectorEditor); - while ((await getY(selectorEditor)) > y0 - height) { + while ((await getRect(page, selectorEditor)).y > y0 - height) { await kbBigMoveUp(page); await waitForPositionChange(page, selectorEditor, xy); xy = await getXY(page, selectorEditor); @@ -2513,10 +2352,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const allPositions = []; @@ -2536,22 +2372,14 @@ describe("FreeText Editor", () => { `${getEditorSelector(i)} .overlay.enabled` ); - allPositions.push( - await page.$eval(getEditorSelector(i), el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }) - ); + allPositions.push(await getRect(page, getEditorSelector(i))); } await selectAll(page); await dragAndDropAnnotation(page, rect.x + 161, rect.y + 126, 39, 74); for (let i = 0; i < 10; i++) { - const pos = await page.$eval(getEditorSelector(i), el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const pos = await getRect(page, getEditorSelector(i)); const oldPos = allPositions[i]; expect(Math.abs(Math.round(pos.x - oldPos.x) - 39)) .withContext(`In ${browserName}`) @@ -2599,10 +2427,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -2662,10 +2487,7 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const page1Selector = `.page[data-page-number = "1"] > .annotationEditorLayer.freetextEditing`; - let rect = await page.$eval(page1Selector, el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + let rect = await getRect(page, page1Selector); const selectorEditor = getEditorSelector(0); await page.mouse.click(rect.x + 10, rect.y + 10); await page.waitForSelector(selectorEditor, { @@ -2682,10 +2504,7 @@ describe("FreeText Editor", () => { await page.keyboard.press("Escape"); await waitForUnselectedEditor(page, selectorEditor); - const editorRect = await page.$eval(selectorEditor, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, selectorEditor); // Select the editor created previously. await page.mouse.click( @@ -2702,10 +2521,7 @@ describe("FreeText Editor", () => { timeout: 0, }); - rect = await page.$eval(page14Selector, el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + rect = await getRect(page, page14Selector); await page.mouse.click(rect.x + 10, rect.y + 10); await page.waitForSelector(getEditorSelector(1), { visible: true, @@ -2732,15 +2548,7 @@ describe("FreeText Editor", () => { visible: true, }); - rect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { - x, - y, - width, - height, - }; - }); + rect = await getRect(page, getEditorSelector(0)); await page.mouse.click( rect.x + rect.width / 2, rect.y + rect.height / 2 @@ -2774,10 +2582,7 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const page1Selector = `.page[data-page-number = "1"] > .annotationEditorLayer.freetextEditing`; - const rect = await page.$eval(page1Selector, el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, page1Selector); const selectorEditor = getEditorSelector(0); await page.mouse.click(rect.x + 10, rect.y + 10); await page.waitForSelector(selectorEditor, { @@ -2794,10 +2599,7 @@ describe("FreeText Editor", () => { await page.keyboard.press("Escape"); await waitForUnselectedEditor(page, selectorEditor); - const editorRect = await page.$eval(selectorEditor, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, selectorEditor); // Select the editor created previously. await page.mouse.click( @@ -2907,12 +2709,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -3105,12 +2902,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -3171,12 +2963,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -3228,12 +3015,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; @@ -3251,10 +3033,7 @@ describe("FreeText Editor", () => { } // Select the editor created previously. - const editorRect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, getEditorSelector(0)); await page.mouse.click( editorRect.x + editorRect.width / 2, editorRect.y + editorRect.height / 2 @@ -3369,12 +3148,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello\nPDF.js\nWorld\n!!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -3415,12 +3189,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -3528,10 +3297,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -3588,10 +3354,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; await page.mouse.click(rect.x + 100, rect.y + 100); @@ -3643,10 +3406,7 @@ describe("FreeText Editor", () => { pages.map(async ([browserName, page]) => { await switchToFreeText(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); let editorSelector = getEditorSelector(0); const data = "Hello PDF.js World !!"; @@ -3655,10 +3415,7 @@ describe("FreeText Editor", () => { visible: true, }); await page.type(`${editorSelector} .internal`, data); - const editorRect = await page.$eval(editorSelector, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, editorSelector); // Commit. await page.keyboard.press("Escape"); @@ -3811,10 +3568,7 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const editorSelector = getEditorSelector(0); - const editorRect = await page.$eval(editorSelector, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const editorRect = await getRect(page, editorSelector); await page.mouse.click( editorRect.x + editorRect.width / 2, editorRect.y + editorRect.height / 2, diff --git a/test/integration/highlight_editor_spec.mjs b/test/integration/highlight_editor_spec.mjs index 3bc202719a08c..927536e6ab1f7 100644 --- a/test/integration/highlight_editor_spec.mjs +++ b/test/integration/highlight_editor_spec.mjs @@ -19,6 +19,7 @@ import { createPromise, getEditorSelector, getFirstSerialized, + getRect, getSerialized, getSpanRectFromText, kbBigMoveLeft, @@ -44,11 +45,10 @@ const waitForPointerUp = page => window.addEventListener("pointerup", resolve, { once: true }); }); -const getXY = (page, selector) => - page.evaluate(sel => { - const bbox = document.querySelector(sel).getBoundingClientRect(); - return `${bbox.x}::${bbox.y}`; - }, selector); +const getXY = async (page, selector) => { + const rect = await getRect(page, selector); + return `${rect.x}::${rect.y}`; +}; describe("Highlight Editor", () => { describe("Editor must be removed without exception", () => { @@ -609,12 +609,7 @@ describe("Highlight Editor", () => { await page.click("#editorHighlight"); await page.waitForSelector(".annotationEditorLayer.highlightEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); for (let i = 0; i < 3; i++) { const x = rect.x + 120 + i * 120; @@ -638,8 +633,8 @@ describe("Highlight Editor", () => { await selectAll(page); - const prevWidth = await page.evaluate( - sel => document.querySelector(sel).getBoundingClientRect().width, + const { width: prevWidth } = await getRect( + page, getEditorSelector(0) ); @@ -692,13 +687,10 @@ describe("Highlight Editor", () => { await page.waitForSelector(".annotationEditorLayer.highlightEditing"); const sel = getEditorSelector(0); - const spanRect = await page.evaluate(() => { - const span = document.querySelector( - `.page[data-page-number="1"] > .textLayer > span` - ); - const { x, y, width, height } = span.getBoundingClientRect(); - return { x, y, width, height }; - }); + const spanRect = await getRect( + page, + `.page[data-page-number="1"] > .textLayer > span` + ); await page.keyboard.down("Shift"); await page.mouse.click( spanRect.x + 1, @@ -757,12 +749,7 @@ describe("Highlight Editor", () => { await page.click("#editorHighlight"); await page.waitForSelector(".annotationEditorLayer.highlightEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const clickHandle = await waitForPointerUp(page); await page.mouse.move(rect.x + 120, rect.y + 120); @@ -781,8 +768,8 @@ describe("Highlight Editor", () => { ); await selectAll(page); - const prevWidth = await page.evaluate( - sel => document.querySelector(sel).getBoundingClientRect().width, + const { width: prevWidth } = await getRect( + page, getEditorSelector(0) ); @@ -806,15 +793,8 @@ describe("Highlight Editor", () => { getEditorSelector(0) ); - const rectDiv = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); - - const rectSVG = await page.$eval("svg.highlight.free", el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const rectDiv = await getRect(page, getEditorSelector(0)); + const rectSVG = await getRect(page, "svg.highlight.free"); expect(Math.abs(rectDiv.x - rectSVG.x) <= 2) .withContext(`In ${browserName}`) @@ -902,14 +882,8 @@ describe("Highlight Editor", () => { await page.click("#editorHighlight"); await page.waitForSelector(".annotationEditorLayer.highlightEditing"); - const rect1 = await page.$eval("#pdfjs_internal_id_5R", el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); - const rect2 = await page.$eval("#pdfjs_internal_id_16R", el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const rect1 = await getRect(page, "#pdfjs_internal_id_5R"); + const rect2 = await getRect(page, "#pdfjs_internal_id_16R"); const x1 = rect1.x + rect1.width / 2; const y1 = rect1.y + rect1.height / 2; @@ -1281,10 +1255,7 @@ describe("Highlight Editor", () => { await page.waitForSelector(getEditorSelector(0)); - rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + rect = await getRect(page, ".annotationEditorLayer"); const clickHandle = await waitForPointerUp(page); await page.mouse.move(rect.x + 5, rect.y + 5); @@ -1403,10 +1374,7 @@ describe("Highlight Editor", () => { await page.click("#editorHighlight"); await page.waitForSelector(".annotationEditorLayer.highlightEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const clickHandle = await waitForPointerUp(page); await page.mouse.move(rect.x + 1, rect.y + 50); @@ -1416,10 +1384,8 @@ describe("Highlight Editor", () => { await awaitPromise(clickHandle); await page.waitForSelector(getEditorSelector(0)); - const editorX = await page.$eval( - getEditorSelector(0), - el => el.getBoundingClientRect().x - ); + + const { x: editorX } = await getRect(page, getEditorSelector(0)); expect(editorX < rect.x) .withContext(`In ${browserName}`) @@ -1446,10 +1412,7 @@ describe("Highlight Editor", () => { await page.click("#editorHighlight"); await page.waitForSelector(".annotationEditorLayer.highlightEditing"); - let rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + let rect = await getRect(page, ".annotationEditorLayer"); const clickHandle = await waitForPointerUp(page); await page.mouse.move(rect.x + 20, rect.y + 20); await page.mouse.down(); diff --git a/test/integration/ink_editor_spec.mjs b/test/integration/ink_editor_spec.mjs index 6af452324af38..6c758b01390d8 100644 --- a/test/integration/ink_editor_spec.mjs +++ b/test/integration/ink_editor_spec.mjs @@ -18,6 +18,7 @@ import { closePages, createPromise, getEditorSelector, + getRect, getSelectedEditors, kbRedo, kbSelectAll, @@ -68,12 +69,7 @@ describe("Ink Editor", () => { pages.map(async ([browserName, page]) => { await page.click("#editorInk"); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); for (let i = 0; i < 3; i++) { const x = rect.x + 100 + i * 100; @@ -105,12 +101,7 @@ describe("Ink Editor", () => { pages.map(async ([browserName, page]) => { await clearAll(page); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const xStart = rect.x + 300; const yStart = rect.y + 300; @@ -123,10 +114,7 @@ describe("Ink Editor", () => { await commit(page); - const rectBefore = await page.$eval(".inkEditor canvas", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rectBefore = await getRect(page, ".inkEditor canvas"); for (let i = 0; i < 30; i++) { await kbUndo(page); @@ -135,10 +123,7 @@ describe("Ink Editor", () => { await waitForStorageEntries(page, 1); } - const rectAfter = await page.$eval(".inkEditor canvas", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rectAfter = await getRect(page, ".inkEditor canvas"); expect(Math.round(rectBefore.x)) .withContext(`In ${browserName}`) @@ -168,12 +153,7 @@ describe("Ink Editor", () => { pages.map(async ([browserName, page]) => { await page.click("#editorInk"); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const x = rect.x + 20; const y = rect.y + 20; @@ -213,12 +193,7 @@ describe("Ink Editor", () => { await page.click("#editorInk"); await page.waitForSelector(".annotationEditorLayer.inkEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const x = rect.x + 20; const y = rect.y + 20; @@ -275,12 +250,7 @@ describe("Ink Editor", () => { await page.click("#editorInk"); await page.waitForSelector(".annotationEditorLayer.inkEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const x = rect.x + 20; const y = rect.y + 20; @@ -315,10 +285,7 @@ describe("Ink Editor", () => { await page.click("#editorInk"); await page.waitForSelector(".annotationEditorLayer.inkEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const xStart = rect.x + 300; const yStart = rect.y + 300; @@ -362,10 +329,7 @@ describe("Ink Editor", () => { await page.click("#editorInk"); await page.waitForSelector(".annotationEditorLayer.inkEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const xStart = rect.x + 300; const yStart = rect.y + 300; @@ -422,10 +386,7 @@ describe("Ink Editor", () => { await page.click("#editorInk"); await page.waitForSelector(".annotationEditorLayer.inkEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); const xStart = rect.x + 300; const yStart = rect.y + 300; @@ -477,10 +438,7 @@ describe("Ink Editor", () => { await page.click("#editorInk"); await page.waitForSelector(".annotationEditorLayer.inkEditing"); - const rect = await page.$eval(".annotationEditorLayer", el => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }); + const rect = await getRect(page, ".annotationEditorLayer"); let xStart = rect.x + 10; const yStart = rect.y + 10; diff --git a/test/integration/stamp_editor_spec.mjs b/test/integration/stamp_editor_spec.mjs index a632963a4f18d..050a48fff8c77 100644 --- a/test/integration/stamp_editor_spec.mjs +++ b/test/integration/stamp_editor_spec.mjs @@ -19,6 +19,7 @@ import { getEditorDimensions, getEditorSelector, getFirstSerialized, + getRect, kbBigMoveDown, kbBigMoveRight, kbCopy, @@ -215,16 +216,14 @@ describe("Stamp Editor", () => { `${getEditorSelector(i)} .resizers:not(.hidden)` ); - const [name, cursor] = await page.evaluate(() => { - const { x, y } = document - .querySelector(".stampEditor") - .getBoundingClientRect(); - const el = document.elementFromPoint(x, y); + const stampRect = await getRect(page, ".stampEditor"); + const [name, cursor] = await page.evaluate(rect => { + const el = document.elementFromPoint(rect.x, rect.y); const cornerName = Array.from(el.classList).find( c => c !== "resizer" ); return [cornerName, window.getComputedStyle(el).cursor]; - }); + }, stampRect); expect(name).withContext(`In ${browserName}`).toEqual(names[j]); expect(cursor) @@ -722,12 +721,7 @@ describe("Stamp Editor", () => { await waitForSerialized(page, 1); const serializedRect = await getFirstSerialized(page, x => x.rect); - const rect = await page.$eval(".resizer.bottomRight", el => { - // With Chrome something is wrong when serializing a DomRect, - // hence we extract the values and just return them. - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const rect = await getRect(page, ".resizer.bottomRight"); const centerX = rect.x + rect.width / 2; const centerY = rect.y + rect.height / 2; @@ -743,20 +737,16 @@ describe("Stamp Editor", () => { (x, y) => x !== y ); - const canvasRect = await page.$eval( - `${getEditorSelector(0)} canvas`, - el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return [x, y, width, height]; - } + const canvasRect = await getRect( + page, + `${getEditorSelector(0)} canvas` ); - const stampRect = await page.$eval(getEditorSelector(0), el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return [x, y, width, height]; - }); + const stampRect = await getRect(page, getEditorSelector(0)); expect( - canvasRect.every((x, i) => Math.abs(x - stampRect[i]) <= 10) + ["x", "y", "width", "height"].every( + key => Math.abs(canvasRect[key] - stampRect[key]) <= 10 + ) ).toBeTrue(); }) ); diff --git a/test/integration/test_utils.mjs b/test/integration/test_utils.mjs index c3d06773424ce..9078674bbc57a 100644 --- a/test/integration/test_utils.mjs +++ b/test/integration/test_utils.mjs @@ -124,6 +124,15 @@ function getSelector(id) { return `[data-element-id="${id}"]`; } +async function getRect(page, selector) { + // In Chrome something is wrong when serializing a `DomRect`, + // so we extract the values and return them ourselves. + return page.$eval(selector, el => { + const { x, y, width, height } = el.getBoundingClientRect(); + return { x, y, width, height }; + }); +} + function getQuerySelector(id) { return `document.querySelector('${getSelector(id)}')`; } @@ -427,10 +436,7 @@ async function firstPageOnTop(page) { } async function hover(page, selector) { - const rect = await page.$eval(selector, el => { - const { x, y, width, height } = el.getBoundingClientRect(); - return { x, y, width, height }; - }); + const rect = await getRect(page, selector); await page.mouse.move(rect.x + rect.width / 2, rect.y + rect.height / 2); } @@ -589,6 +595,7 @@ export { getEditorSelector, getFirstSerialized, getQuerySelector, + getRect, getSelectedEditors, getSelector, getSerialized,