From b5b821365ed67aa2f468128b3a3b4f3967b07dd9 Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Sat, 18 Oct 2025 17:19:21 +0200 Subject: [PATCH] Introduce a helper function to create a freetext editor in the integration tests Doing so has a number of advantages: - it removes code duplication, thereby improving readability; - it removes hardcoded editor IDs, by using the `getNextEditorId` helper function that was previously introduced for the highlight editor integration tests, thereby improving readability and reusability; - it removes potential for intermittent failures by not proceeding until the freetext editor is fully created and all assertions pass, which didn't happen consistently before because the code wasn't centralized. --- test/integration/freetext_editor_spec.mjs | 616 +++++++++++----------- test/integration/test_utils.mjs | 17 + 2 files changed, 319 insertions(+), 314 deletions(-) diff --git a/test/integration/freetext_editor_spec.mjs b/test/integration/freetext_editor_spec.mjs index ca062b023..b8a5cb4e6 100644 --- a/test/integration/freetext_editor_spec.mjs +++ b/test/integration/freetext_editor_spec.mjs @@ -19,6 +19,8 @@ import { closePages, copy, copyToClipboard, + countSerialized, + countStorageEntries, createPromise, dragAndDrop, firstPageOnTop, @@ -26,6 +28,7 @@ import { getEditors, getEditorSelector, getFirstSerialized, + getNextEditorId, getRect, getSerialized, isCanvasMonochrome, @@ -85,6 +88,34 @@ const cancelFocusIn = async (page, selector) => { }, selector); }; +const createFreeTextEditor = async ({ + page, + x, + y, + data = null, + noFocusIn = false, +}) => { + const editorSelector = getEditorSelector(await getNextEditorId(page)); + const serializedCount = await countSerialized(page); + const storageEntriesCount = await countStorageEntries(page); + + await page.mouse.click(x, y); + await page.waitForSelector(editorSelector, { visible: true }); + if (data) { + await page.type(`${editorSelector} .internal`, data); + } + if (noFocusIn) { + await cancelFocusIn(page, editorSelector); + } + await commit(page); + + await waitForSelectedEditor(page, editorSelector); + await waitForStorageEntries(page, storageEntriesCount + 1); + await waitForSerialized(page, serializedCount + 1); + + return editorSelector; +}; + describe("FreeText Editor", () => { describe("FreeText", () => { let pages; @@ -103,15 +134,13 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - - await waitForSelectedEditor(page, editorSelector); - await waitForStorageEntries(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data, + }); await page.waitForFunction( `document.getElementById("viewer-alert").textContent === "Text added"` @@ -143,13 +172,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const firstEditorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(firstEditorSelector, { visible: true }); - await page.type(`${firstEditorSelector} .internal`, data); - await commit(page); - await waitForStorageEntries(page, 1); + const firstEditorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await selectEditor(page, firstEditorSelector); await copy(page); @@ -187,13 +215,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const firstEditorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(firstEditorSelector, { visible: true }); - await page.type(`${firstEditorSelector} .internal`, data); - await commit(page); - await waitForStorageEntries(page, 1); + const firstEditorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await page.evaluate(() => { window.PDFViewerApplication.eventBus.dispatch( @@ -240,12 +267,12 @@ describe("FreeText Editor", () => { const rect = await getRect(page, ".annotationEditorLayer"); for (const n of [0, 1, 2]) { - const editorSelector = getEditorSelector(n); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100 * n, rect.y + 100 * n); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100 * n, + y: rect.y + 100 * n, + data: "Hello PDF.js World !!", + }); const hasEditor = await page.evaluate( sel => !!document.querySelector(sel), @@ -275,12 +302,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - let editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + let editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await selectEditor(page, editorSelector); await copy(page); @@ -317,12 +344,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); expect(await getEditors(page, "selected")) .withContext(`In ${browserName}`) @@ -460,12 +487,12 @@ describe("FreeText Editor", () => { const editorCenters = []; let lastX = rect.x + rect.width / 10; for (let i = 0; i < 4; i++) { - const editorSelector = getEditorSelector(i); - const data = `FreeText ${i}`; - await page.mouse.click(lastX, rect.y + rect.height / 10); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: lastX, + y: rect.y + rect.height / 10, + data: `FreeText ${i}`, + }); const editorRect = await getRect(page, editorSelector); lastX = editorRect.x + editorRect.width + 10; @@ -627,16 +654,13 @@ describe("FreeText Editor", () => { ); expect(oldAriaOwns).withContext(`In ${browserName}`).toEqual(null); - const editorSelector = getEditorSelector(0); const rect = await getRect(page, `span[pdfjs="true"]`); - const data = "Hello PDF.js World !!"; - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2 - ); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + await createFreeTextEditor({ + page, + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2, + data: "Hello PDF.js World !!", + }); const newAriaOwns = await page.$eval(`span[pdfjs="true"]`, el => el.getAttribute("aria-owns") @@ -664,7 +688,6 @@ describe("FreeText Editor", () => { await Promise.all( pages.map(async ([browserName, page]) => { await switchToFreeText(page); - let currentId = 0; const expected = []; const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1); @@ -682,23 +705,19 @@ describe("FreeText Editor", () => { } const rect = await getRect(page, annotationLayerSelector); - const editorSelector = getEditorSelector(currentId); const data = `Hello PDF.js World !! on page ${pageNumber}`; expected.push(data); - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - - await waitForSelectedEditor(page, editorSelector); - await waitForStorageEntries(page, currentId + 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data, + }); const content = await page.$eval(editorSelector, el => el.innerText.trimEnd() ); expect(content).withContext(`In ${browserName}`).toEqual(data); - - currentId += 1; } const serialize = proprName => @@ -808,19 +827,16 @@ describe("FreeText Editor", () => { await Promise.all( pages.map(async ([browserName, page]) => { await switchToFreeText(page); - let currentId = 0; for (let step = 0; step < 3; step++) { await firstPageOnTop(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(currentId); - const data = `Hello ${step}`; - const x = Math.max(rect.x + 0.1 * rect.width, 10); - const y = Math.max(rect.y + 0.1 * rect.height, 10); - await page.mouse.click(x, y); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + await createFreeTextEditor({ + page, + x: Math.max(rect.x + 0.1 * rect.width, 10), + y: Math.max(rect.y + 0.1 * rect.height, 10), + data: `Hello ${step}`, + }); const promise = await waitForAnnotationEditorLayer(page); await page.evaluate(() => { @@ -828,7 +844,6 @@ describe("FreeText Editor", () => { }); await awaitPromise(promise); - currentId += 1; await page.waitForSelector( ".page[data-page-number='1'] .canvasWrapper", { @@ -1353,12 +1368,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); // Make Chrome happy. await page.waitForFunction(() => { @@ -1445,9 +1460,8 @@ describe("FreeText Editor", () => { await Promise.all( pages.map(async ([browserName, page]) => { await switchToFreeText(page); - let currentId = 0; - const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1); + const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1); for (const pageNumber of oneToFourteen) { const pageSelector = `.page[data-page-number = "${pageNumber}"]`; @@ -1462,14 +1476,12 @@ describe("FreeText Editor", () => { } const rect = await getRect(page, annotationLayerSelector); - const editorSelector = getEditorSelector(currentId); - const data = `Hello PDF.js World !! on page ${pageNumber}`; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - - currentId += 1; + await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: `Hello PDF.js World !! on page ${pageNumber}`, + }); } await selectAll(page); @@ -1804,12 +1816,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await page.focus("#editorFreeTextColor"); await kbUndo(page); @@ -1848,13 +1860,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - - const data = "Hello PDF.js World !!"; - const editorSelector = getEditorSelector(0); - await page.mouse.click(rect.x + 200, rect.y + 200); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 200, + y: rect.y + 200, + data: "Hello PDF.js World !!", + }); const [pageX, pageY] = await getFirstSerialized(page, x => x.rect); @@ -1911,12 +1922,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const data = "Hello PDF.js World !!"; - const editorSelector = getEditorSelector(0); - await page.mouse.click(rect.x + 200, rect.y + 200); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 200, + y: rect.y + 200, + data: "Hello PDF.js World !!", + }); await selectAll(page); await page.focus("#editorFreeTextFontSize"); @@ -1950,16 +1961,17 @@ describe("FreeText Editor", () => { const rect = await getRect(page, ".annotationEditorLayer"); const data = "Hello PDF.js World !!"; - let editorSelector = getEditorSelector(0); - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data, + }); const [pageX, pageY] = await getFirstSerialized(page, x => x.rect); await clearAll(page); - editorSelector = getEditorSelector(1); + const editorSelector = getEditorSelector(1); await page.mouse.click(rect.x + 100, rect.y + 100); await page.waitForSelector(editorSelector, { visible: true }); @@ -2023,13 +2035,13 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await cancelFocusIn(page, editorSelector); - await commit(page); + await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + noFocusIn: true, + }); const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1); @@ -2076,23 +2088,21 @@ describe("FreeText Editor", () => { await switchToFreeText(page); let rect = await getRect(page, ".annotationEditorLayer"); - - const firstEditorSelector = getEditorSelector(0); - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(firstEditorSelector, { visible: true }); - await page.type(`${firstEditorSelector} .internal`, "A"); - await commit(page); + const firstEditorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "A", + }); // Create a new editor. rect = await getRect(page, firstEditorSelector); - const secondEditorSelector = getEditorSelector(1); - await page.mouse.click( - rect.x + 5 * rect.width, - rect.y + 5 * rect.height - ); - await page.waitForSelector(secondEditorSelector, { visible: true }); - await page.type(`${secondEditorSelector} .internal`, "B"); - await commit(page); + const secondEditorSelector = await createFreeTextEditor({ + page, + x: rect.x + 5 * rect.width, + y: rect.y + 5 * rect.height, + data: "B", + }); // Select the second editor. await selectEditor(page, secondEditorSelector); @@ -2155,15 +2165,12 @@ describe("FreeText Editor", () => { const allPositions = []; for (let i = 0; i < 10; i++) { - const editorSelector = getEditorSelector(i); - await page.mouse.click(rect.x + 10 + 30 * i, rect.y + 100 + 5 * i); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type( - `${editorSelector} .internal`, - String.fromCharCode(65 + i) - ); - await commit(page); - + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 10 + 30 * i, + y: rect.y + 100 + 5 * i, + data: String.fromCharCode(65 + i), + }); allPositions.push(await getRect(page, editorSelector)); } @@ -2214,13 +2221,13 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await cancelFocusIn(page, editorSelector); - await commit(page); + await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + noFocusIn: true, + }); await page.evaluate(() => { window.editingEvents = []; @@ -2267,12 +2274,13 @@ describe("FreeText Editor", () => { const page1Selector = `.page[data-page-number = "1"] > .annotationEditorLayer.freetextEditing`; let rect = await getRect(page, page1Selector); - const firstEditorSelector = getEditorSelector(0); - await page.mouse.click(rect.x + 10, rect.y + 10); - await page.waitForSelector(firstEditorSelector, { visible: true }); - await page.type(`${firstEditorSelector} .internal`, "Hello"); - await cancelFocusIn(page, firstEditorSelector); - await commit(page); + const firstEditorSelector = await createFreeTextEditor({ + page, + x: rect.x + 10, + y: rect.y + 10, + data: "Hello", + noFocusIn: true, + }); // Unselect. await unselectEditor(page, firstEditorSelector); @@ -2290,11 +2298,12 @@ describe("FreeText Editor", () => { }); rect = await getRect(page, page14Selector); - const secondEditorSelector = getEditorSelector(1); - await page.mouse.click(rect.x + 10, rect.y + 10); - await page.waitForSelector(secondEditorSelector, { visible: true }); - await page.type(`${secondEditorSelector} .internal`, "World"); - await commit(page); + await createFreeTextEditor({ + page, + x: rect.x + 10, + y: rect.y + 10, + data: "World", + }); for (let i = 0; i < 13; i++) { await page.keyboard.press("P"); @@ -2336,12 +2345,13 @@ describe("FreeText Editor", () => { const page1Selector = `.page[data-page-number = "1"] > .annotationEditorLayer.freetextEditing`; const rect = await getRect(page, page1Selector); - const editorSelector = getEditorSelector(0); - await page.mouse.click(rect.x + 10, rect.y + 10); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, "Hello"); - await cancelFocusIn(page, editorSelector); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 10, + y: rect.y + 10, + data: "Hello", + noFocusIn: true, + }); // Unselect. await unselectEditor(page, editorSelector); @@ -2394,7 +2404,6 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const parentId = "p3R_mc8"; - const editorSelector = getEditorSelector(0); const rect = await page.evaluate(id => { const parent = document.getElementById(id); let span = null; @@ -2407,15 +2416,13 @@ describe("FreeText Editor", () => { const { x, y, width, height } = span.getBoundingClientRect(); return { x, y, width, height }; }, parentId); - await page.mouse.click( - rect.x + rect.width + 5, - rect.y + rect.height / 2 - ); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, "Hello Wolrd"); - await commit(page); - await waitForStorageEntries(page, 1); + await createFreeTextEditor({ + page, + x: rect.x + rect.width + 5, + y: rect.y + rect.height / 2, + data: "Hello World", + }); const id = await getFirstSerialized(page, x => x.structTreeParentId); expect(id).withContext(`In ${browserName}`).toEqual(parentId); @@ -2441,21 +2448,19 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - const internalEditorSelector = `${editorSelector} .internal`; - await page.type(internalEditorSelector, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data, + }); await page.click(editorSelector, { count: 2 }); await page.waitForSelector( `${editorSelector} .overlay:not(.enabled)` ); - await page.click(internalEditorSelector, { - count: 3, - }); + await page.click(`${editorSelector} .internal`, { count: 3 }); const selection = await page.evaluate(() => document.getSelection().toString() ); @@ -2588,12 +2593,13 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data, + }); let handle = await createPromise(page, resolve => { document.addEventListener("selectionchange", resolve, { @@ -2642,12 +2648,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); // Delete it in using the button. await page.click(`${editorSelector} button.deleteButton`); @@ -2685,38 +2691,39 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); + const firstEditorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); + const secondEditorSelector = await createFreeTextEditor({ + page, + x: rect.x + 200, + y: rect.y + 200, + data: "Hello PDF.js World !!", + }); - const data = "Hello PDF.js World !!"; - - for (let i = 1; i <= 2; i++) { - const editorSelector = getEditorSelector(i - 1); - await page.mouse.click(rect.x + i * 100, rect.y + i * 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - } - - // Select the editor created previously. - const editorSelector = getEditorSelector(0); - await selectEditor(page, editorSelector); + // Select the first editor. + await selectEditor(page, firstEditorSelector); await selectAll(page); // Delete it in using the button. - await page.focus(`${editorSelector} button.deleteButton`); + await page.focus(`${firstEditorSelector} button.deleteButton`); await page.keyboard.press("Enter"); await page.waitForFunction( sel => !document.querySelector(sel), {}, - editorSelector + firstEditorSelector ); await waitForStorageEntries(page, 0); // Undo. await kbUndo(page); await waitForSerialized(page, 2); - await page.waitForSelector(editorSelector, { visible: true }); - await page.waitForSelector(getEditorSelector(1), { visible: true }); + await page.waitForSelector(firstEditorSelector, { visible: true }); + await page.waitForSelector(secondEditorSelector, { visible: true }); }) ); }); @@ -2801,14 +2808,14 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); const data = "Hello\nPDF.js\nWorld\n!!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data, + }); - await waitForSerialized(page, 1); const serialized = (await getSerialized(page))[0]; expect(serialized.value) .withContext(`In ${browserName}`) @@ -2835,12 +2842,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await page.evaluate(() => { window.PDFViewerApplication.eventBus.dispatch( @@ -2936,13 +2943,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - await waitForSerialized(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`); @@ -2986,13 +2992,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - await waitForSerialized(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`); @@ -3031,13 +3036,13 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - - let editorSelector = getEditorSelector(0); const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + let editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data, + }); const waitForTextChange = (previous, edSelector) => page.waitForFunction( @@ -3300,7 +3305,6 @@ describe("FreeText Editor", () => { describe("Undo deletion popup has the expected behaviour", () => { let pages; - const editorSelector = getEditorSelector(0); beforeEach(async () => { pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer"); @@ -3316,12 +3320,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - await waitForSerialized(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`); @@ -3344,12 +3348,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - await waitForSerialized(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`); @@ -3377,12 +3381,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); let rect = await getRect(page, ".annotationEditorLayer"); - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - await waitForSerialized(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`); @@ -3390,13 +3394,12 @@ describe("FreeText Editor", () => { await page.waitForSelector("#editorUndoBar", { visible: true }); rect = await getRect(page, ".annotationEditorLayer"); - const secondEditorSelector = getEditorSelector(1); - const newData = "This is a new text box!"; - await page.mouse.click(rect.x + 150, rect.y + 150); - await page.waitForSelector(secondEditorSelector, { visible: true }); - await page.type(`${secondEditorSelector} .internal`, newData); - await commit(page); - await waitForSerialized(page, 1); + await createFreeTextEditor({ + page, + x: rect.x + 150, + y: rect.y + 150, + data: "This is a new text box!", + }); await page.waitForSelector("#editorUndoBar", { hidden: true }); }) ); @@ -3420,14 +3423,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - - const data = "Hello PDF.js World !!"; - await page.mouse.click(rect.x + 100, rect.y + 100); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - await waitForSerialized(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + 100, + y: rect.y + 100, + data: "Hello PDF.js World !!", + }); let alignment = await page.$eval( `${editorSelector} .internal`, @@ -3468,17 +3469,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - - const data = "Hello PDF.js World !!"; - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2 - ); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - await waitForSerialized(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2, + data: "Hello PDF.js World !!", + }); await switchToFreeText(page, /* disable */ true); @@ -3508,17 +3504,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - - const data = "Hello PDF.js World !!"; - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2 - ); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); - await waitForSerialized(page, 1); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2, + data: "Hello PDF.js World !!", + }); await switchToFreeText(page, /* disable */ true); await switchToEditor("Ink", page); @@ -3573,15 +3564,12 @@ describe("FreeText Editor", () => { await switchToFreeText(page); const rect = await getRect(page, ".annotationEditorLayer"); - const editorSelector = getEditorSelector(0); - const data = "Hello PDF.js World !!"; - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2 - ); - await page.waitForSelector(editorSelector, { visible: true }); - await page.type(`${editorSelector} .internal`, data); - await commit(page); + const editorSelector = await createFreeTextEditor({ + page, + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2, + data: "Hello PDF.js World !!", + }); const colorPickerSelector = `${editorSelector} input.basicColorPicker`; await page.waitForSelector(colorPickerSelector, { visible: true }); diff --git a/test/integration/test_utils.mjs b/test/integration/test_utils.mjs index 820690efd..630eb6275 100644 --- a/test/integration/test_utils.mjs +++ b/test/integration/test_utils.mjs @@ -310,6 +310,12 @@ async function waitForEvent({ } } +async function countStorageEntries(page) { + return page.evaluate( + () => window.PDFViewerApplication.pdfDocument.annotationStorage.size + ); +} + async function waitForStorageEntries(page, nEntries) { return page.waitForFunction( n => window.PDFViewerApplication.pdfDocument.annotationStorage.size === n, @@ -318,6 +324,14 @@ async function waitForStorageEntries(page, nEntries) { ); } +async function countSerialized(page) { + return page.evaluate( + () => + window.PDFViewerApplication.pdfDocument.annotationStorage.serializable.map + ?.size ?? 0 + ); +} + async function waitForSerialized(page, nEntries) { return page.waitForFunction( n => { @@ -924,6 +938,8 @@ export { closeSinglePage, copy, copyToClipboard, + countSerialized, + countStorageEntries, createPromise, dragAndDrop, firstPageOnTop, @@ -935,6 +951,7 @@ export { getEditors, getEditorSelector, getFirstSerialized, + getNextEditorId, getQuerySelector, getRect, getSelector,