diff --git a/src/display/editor/tools.js b/src/display/editor/tools.js index 910ded4ce..1d1212a53 100644 --- a/src/display/editor/tools.js +++ b/src/display/editor/tools.js @@ -53,6 +53,9 @@ class IdManager { Object.defineProperty(this, "reset", { value: () => (this.#id = 0), }); + Object.defineProperty(this, "getNextId", { + value: () => this.#id, + }); } } @@ -906,6 +909,9 @@ class AnnotationEditorUIManager { this.#idManager.reset(); }, }); + Object.defineProperty(this, "getNextEditorId", { + value: () => this.#idManager.getNextId(), + }); } } diff --git a/test/integration/comment_spec.mjs b/test/integration/comment_spec.mjs index 09b7f4ba5..ed67f006a 100644 --- a/test/integration/comment_spec.mjs +++ b/test/integration/comment_spec.mjs @@ -20,7 +20,7 @@ import { dragAndDrop, getEditorSelector, getRect, - getSpanRectFromText, + highlightSpan, loadAndWait, scrollIntoView, selectEditor, @@ -35,14 +35,6 @@ const switchToStamp = switchToEditor.bind(null, "Stamp"); const switchToComment = switchToEditor.bind(null, "Comment"); const switchToFreeText = switchToEditor.bind(null, "FreeText"); -const highlightSpan = async (page, pageIndex, text) => { - const rect = await getSpanRectFromText(page, pageIndex, text); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(getEditorSelector(0)); -}; - const editComment = async (page, editorSelector, comment) => { const commentButtonSelector = `${editorSelector} button.comment`; await waitAndClick(page, commentButtonSelector); @@ -82,16 +74,7 @@ describe("Comment", () => { await switchToHighlight(page); await scrollIntoView(page, ".textLayer span:last-of-type"); - const rect = await getSpanRectFromText(page, 1, "..."); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - // Here and elsewhere, we add a small delay between press and release - // to make sure that a pointerup event is triggered after - // selectionchange. - // It works with a value of 1ms, but we use 100ms to be sure. - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(getEditorSelector(0)); - + await highlightSpan(page, 1, "..."); const commentButtonSelector = `${getEditorSelector(0)} button.comment`; await waitAndClick(page, commentButtonSelector); @@ -137,12 +120,7 @@ describe("Comment", () => { await switchToHighlight(page); await scrollIntoView(page, ".textLayer span:nth-of-type(4)"); - const rect = await getSpanRectFromText(page, 1, "World"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(getEditorSelector(0)); - + await highlightSpan(page, 1, "World"); const commentButtonSelector = `${getEditorSelector(0)} button.comment`; await waitAndClick(page, commentButtonSelector); @@ -272,7 +250,7 @@ describe("Comment", () => { pages = await loadAndWait( "tracemonkey.pdf", ".annotationEditorLayer", - "page-width", + "page-fit", null, { enableComment: true } ); @@ -286,12 +264,7 @@ describe("Comment", () => { await Promise.all( pages.map(async ([browserName, page]) => { await switchToHighlight(page); - - const rect = await getSpanRectFromText(page, 1, "Languages"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(getEditorSelector(0)); + await highlightSpan(page, 1, "Languages"); let commentButtonSelector = `${getEditorSelector(0)} button.comment`; await page.waitForSelector(commentButtonSelector, { visible: true }); @@ -329,12 +302,7 @@ describe("Comment", () => { await Promise.all( pages.map(async ([browserName, page]) => { await switchToHighlight(page); - - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(getEditorSelector(0)); + await highlightSpan(page, 1, "Abstract"); const comment = "Hello world!"; await editComment(page, getEditorSelector(0), comment); @@ -426,12 +394,7 @@ describe("Comment", () => { await Promise.all( pages.map(async ([browserName, page]) => { await switchToHighlight(page); - - const rect = await getSpanRectFromText(page, 1, "Languages"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(getEditorSelector(0)); + await highlightSpan(page, 1, "Languages"); const commentButtonSelector = `${getEditorSelector(0)} button.comment`; await waitAndClick(page, commentButtonSelector); @@ -539,7 +502,7 @@ describe("Comment", () => { pages = await loadAndWait( "comments.pdf", ".annotationEditorLayer", - "page-width", + "page-fit", null, { enableComment: true } ); @@ -607,7 +570,6 @@ describe("Comment", () => { await switchToHighlight(page); await highlightSpan(page, 1, "Languages"); const editorSelector = getEditorSelector(9); - await page.waitForSelector(editorSelector); const commentButtonSelector = `${editorSelector} button.comment`; await waitAndClick(page, commentButtonSelector); @@ -662,7 +624,7 @@ describe("Comment", () => { pages = await loadAndWait( "tracemonkey.pdf", ".annotationEditorLayer", - "page-width", + "page-fit", null, { enableComment: true } ); diff --git a/test/integration/highlight_editor_spec.mjs b/test/integration/highlight_editor_spec.mjs index c0a32108d..094ef2b9f 100644 --- a/test/integration/highlight_editor_spec.mjs +++ b/test/integration/highlight_editor_spec.mjs @@ -23,6 +23,7 @@ import { getSerialized, getSpanRectFromText, getXY, + highlightSpan, kbBigMoveLeft, kbBigMoveUp, kbFocusNext, @@ -69,17 +70,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - // Here and elsewhere, we add a small delay between press and release - // to make sure that a pointerup event is triggered after - // selectionchange. - // It works with a value of 1ms, but we use 100ms to be sure. - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(`${getEditorSelector(0)}`); - + await highlightSpan(page, 1, "Abstract"); await page.waitForFunction( `document.getElementById("viewer-alert").textContent === "Highlight added"` ); @@ -119,12 +110,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(`${getEditorSelector(0)}`); + await highlightSpan(page, 1, "Abstract"); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); @@ -169,12 +155,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(`${getEditorSelector(0)}`); + await highlightSpan(page, 1, "Abstract"); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); @@ -214,12 +195,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - let rect = await getSpanRectFromText(page, 1, "Abstract"); - let x = rect.x + rect.width / 2; - let y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(`${getEditorSelector(0)}`); + await highlightSpan(page, 1, "Abstract"); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); @@ -237,13 +213,8 @@ describe("Highlight Editor", () => { `.page[data-page-number = "14"] .textLayer .endOfContent` ); - rect = await getSpanRectFromText(page, 14, "References"); - x = rect.x + rect.width / 2; - y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - + await highlightSpan(page, 14, "References"); const editorSelector = getEditorSelector(1); - await page.waitForSelector(editorSelector); await page.waitForSelector( `.page[data-page-number = "14"] svg.highlightOutline.selected` ); @@ -302,12 +273,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(`${getEditorSelector(0)}`); + await highlightSpan(page, 1, "Abstract"); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); @@ -363,12 +329,7 @@ describe("Highlight Editor", () => { await switchToHighlight(page); const sel = getEditorSelector(0); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(sel); + await highlightSpan(page, 1, "Abstract"); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); @@ -473,13 +434,8 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); @@ -521,12 +477,7 @@ describe("Highlight Editor", () => { await switchToHighlight(page); const sel = getEditorSelector(0); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(sel); + await highlightSpan(page, 1, "Abstract"); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); @@ -536,7 +487,8 @@ describe("Highlight Editor", () => { await page.waitForSelector( `${sel} .editToolbar button[title = "Red"]` ); - await page.mouse.click(x, y - rect.height); + const rect = await getSpanRectFromText(page, 1, "Abstract"); + await page.mouse.click(rect.x, rect.y - rect.height); await page.waitForSelector( `${sel} .editToolbar button.colorPicker .dropdown.hidden` ); @@ -562,17 +514,16 @@ describe("Highlight Editor", () => { await switchToHighlight(page); const sel = getEditorSelector(0); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(sel); + await highlightSpan(page, 1, "Abstract"); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); await page.waitForSelector(`${sel} .editToolbar button.colorPicker`); + + const rect = await getSpanRectFromText(page, 1, "Abstract"); + const x = rect.x + rect.width / 2; + const y = rect.y + rect.height / 2; await page.mouse.click(x, y - rect.height); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline:not(.selected)` @@ -831,16 +782,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText( - page, - 1, - "Questions courantes" - ); - const x = rect.x + 0.75 * rect.width; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - await page.waitForSelector(`${getEditorSelector(0)}`); + await highlightSpan(page, 1, "Questions courantes", 0.75, 0.5); const usedColor = await page.evaluate(() => { const highlight = document.querySelector( `.page[data-page-number = "1"] .canvasWrapper > svg.highlight` @@ -1015,13 +957,8 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); await unselectEditor(page, editorSelector); await setCaretAt( @@ -1160,13 +1097,8 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -1195,17 +1127,10 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - let rect = await getSpanRectFromText(page, 1, "Abstract"); - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2, - { count: 2, delay: 100 } - ); - + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); - rect = await getRect(page, ".annotationEditorLayer"); + const rect = await getRect(page, ".annotationEditorLayer"); const clickHandle = await waitForPointerUp(page); await page.mouse.move(rect.x + 5, rect.y + 5); @@ -1250,14 +1175,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Languages"); - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2, - { count: 2, delay: 100 } - ); - - await page.waitForSelector(getEditorSelector(0)); + await highlightSpan(page, 1, "Languages"); await waitForSerialized(page, 1); const quadPoints = await getFirstSerialized(page, e => e.quadPoints); // Expected quadPoints tL, tR, bL, bR with bL coordinate. @@ -1286,14 +1204,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Hello World"); - await page.mouse.click( - rect.x + rect.width / 4, - rect.y + rect.height / 2, - { count: 2, delay: 100 } - ); - - await page.waitForSelector(getEditorSelector(0)); + await highlightSpan(page, 1, "Hello World", 0.25); await waitForSerialized(page, 1); const quadPoints = await getFirstSerialized(page, e => e.quadPoints); // Expected quadPoints tL, tR, bL, bR with bL coordinate. @@ -1322,13 +1233,8 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); await page.focus(`${editorSelector} button.colorPicker`); await page.keyboard.press("Escape"); @@ -1392,7 +1298,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - let rect = await getRect(page, ".annotationEditorLayer"); + const rect = await getRect(page, ".annotationEditorLayer"); const clickHandle = await waitForPointerUp(page); await page.mouse.move(rect.x + 20, rect.y + 20); await page.mouse.down(); @@ -1403,15 +1309,8 @@ describe("Highlight Editor", () => { const firstEditorSelector = getEditorSelector(0); await page.waitForSelector(firstEditorSelector); - rect = await getSpanRectFromText(page, 1, "Languages"); - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2, - { count: 2, delay: 100 } - ); - + await highlightSpan(page, 1, "Languages"); const secondEditorSelector = getEditorSelector(1); - await page.waitForSelector(secondEditorSelector); await page.click("#editorHighlightShowAll"); await page.waitForSelector(`${firstEditorSelector}.hidden`); @@ -1513,19 +1412,10 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - let rect = await getSpanRectFromText(page, 1, "Abstract"); - let x = rect.x + rect.width / 2; - let y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(getEditorSelector(0)); - - rect = await getSpanRectFromText(page, 1, "Languages"); - x = rect.x + rect.width / 2; - y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); + await highlightSpan(page, 1, "Abstract"); + await highlightSpan(page, 1, "Languages"); const editorSelector = getEditorSelector(1); - await page.waitForSelector(editorSelector); await page.focus(editorSelector); await kbFocusPrevious(page); @@ -1556,13 +1446,8 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -1602,13 +1487,8 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -1664,13 +1544,8 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -1789,17 +1664,15 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); + await highlightSpan(page, 1, "Abstract"); const editorSelector = getEditorSelector(0); - const x = rect.x + rect.width / 2; - let y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); await waitForSerialized(page, 1); await unselectEditor(page, editorSelector); const clickHandle = await waitForPointerUp(page); - y = rect.y - rect.height; + const rect = await getSpanRectFromText(page, 1, "Abstract"); + const x = rect.x + rect.width / 2; + let y = rect.y - rect.height; await page.mouse.move(x, y); const counterHandle = await page.evaluateHandle(sel => { @@ -2201,11 +2074,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2231,11 +2100,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2257,11 +2122,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2283,24 +2144,20 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`); - await waitForSerialized(page, 0); await page.waitForSelector("#editorUndoBar", { visible: true }); - const newRect = await getSpanRectFromText(page, 1, "Introduction"); - const newX = newRect.x + newRect.width / 2; - const newY = newRect.y + newRect.height / 2; - await page.mouse.click(newX, newY, { count: 2, delay: 100 }); + // TODO: remove the timeout and try to figure out a way to ensure that + // the previous operations are fully processed before creating a new + // highlight. + // eslint-disable-next-line no-restricted-syntax + await waitForTimeout(100); - await page.waitForSelector(getEditorSelector(1)); + await highlightSpan(page, 1, "Introduction"); await page.waitForSelector("#editorUndoBar", { hidden: true }); }) ); @@ -2311,11 +2168,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2334,11 +2187,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2357,11 +2206,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2380,11 +2225,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2404,11 +2245,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2427,11 +2264,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2487,11 +2320,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2520,17 +2349,8 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - let rect = await getSpanRectFromText(page, 1, "Abstract"); - let x = rect.x + rect.width / 2; - let y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); - - rect = await getSpanRectFromText(page, 1, "Languages"); - x = rect.x + rect.width / 2; - y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(getEditorSelector(1)); + await highlightSpan(page, 1, "Abstract"); + await highlightSpan(page, 1, "Languages"); await selectAll(page); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2564,11 +2384,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2611,11 +2427,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await waitForSerialized(page, 1); await page.waitForSelector(`${editorSelector} button.deleteButton`); @@ -2738,10 +2550,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); + await highlightSpan(page, 1, "Abstract"); const highlightSelector = `.page[data-page-number = "1"] .canvasWrapper > svg.highlight`; await page.waitForSelector(`${highlightSelector}[fill = "#AB0000"]`); @@ -2782,13 +2591,7 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - const rect = await getSpanRectFromText(page, 1, "Abstract"); - const x = rect.x + rect.width / 2; - const y = rect.y + rect.height / 2; - await page.mouse.click(x, y, { count: 2, delay: 100 }); - - const editorSelector = getEditorSelector(0); - await page.waitForSelector(editorSelector); + await highlightSpan(page, 1, "Abstract"); await page.waitForSelector( `.page[data-page-number = "1"] svg.highlightOutline.selected` ); @@ -2977,27 +2780,15 @@ describe("Highlight Editor", () => { pages.map(async ([browserName, page]) => { await switchToHighlight(page); - let rect = await getSpanRectFromText(page, 1, "Languages"); - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2, - { count: 2, delay: 100 } - ); + await highlightSpan(page, 1, "Languages"); const editorSelector0 = getEditorSelector(0); - await page.waitForSelector(editorSelector0); - rect = await getSpanRectFromText(page, 1, "Abstract"); - await page.mouse.click( - rect.x + rect.width / 2, - rect.y + rect.height / 2, - { count: 2, delay: 100 } - ); + await highlightSpan(page, 1, "Abstract"); const editorSelector1 = getEditorSelector(1); - await page.waitForSelector(editorSelector1); await switchToEditor("Ink", page); - rect = await getSpanRectFromText( + const rect = await getSpanRectFromText( page, 1, "University of California, Irvine" diff --git a/test/integration/test_utils.mjs b/test/integration/test_utils.mjs index 579da577b..820690efd 100644 --- a/test/integration/test_utils.mjs +++ b/test/integration/test_utils.mjs @@ -887,6 +887,30 @@ async function moveEditor(page, selector, n, pressKey) { } } +async function getNextEditorId(page) { + return page.evaluate(() => + window.PDFViewerApplication.pdfViewer._layerProperties.annotationEditorUIManager.getNextEditorId() + ); +} + +async function highlightSpan( + page, + pageIndex, + text, + xRatio = 0.5, + yRatio = 0.5 +) { + const nextId = await getNextEditorId(page); + const rect = await getSpanRectFromText(page, pageIndex, text); + const x = rect.x + rect.width * xRatio; + const y = rect.y + rect.height * yRatio; + // We add a small delay between press and release to make sure that a + // pointerup event is triggered after selectionchange. + // It works with a value of 1ms, but we use 100ms to be sure. + await page.mouse.click(x, y, { count: 2, delay: 100 }); + await page.waitForSelector(getEditorSelector(nextId)); +} + // Unicode bidi isolation characters, Fluent adds these markers to the text. const FSI = "\u2068"; const PDI = "\u2069"; @@ -917,6 +941,7 @@ export { getSerialized, getSpanRectFromText, getXY, + highlightSpan, isCanvasMonochrome, kbBigMoveDown, kbBigMoveLeft,