From f251e600d24669daf8cbfdf059b02b6de45df221 Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Sun, 25 May 2025 15:26:36 +0200 Subject: [PATCH] Fix intermittent failure in the "supports specifying a custom origin" viewer integration test The problem in the original code is that `getTextAt` is called too early and therefore returns unexpected text content. This can happen because we call `increaseScale` and then wait for the page's text layer to be visible, but it can take some time before the zoom actually occurs/completes in the viewer and in the meantime the old (pre-zoom) text layer may still be visible, causing us to continue too soon because we don't validate that we're dealing with the post-zoom text layer. This commit fixes the issue by simply waiting for the expected text to show up at the given origin coordinates, which makes the test work independent of viewer actions/timing. --- test/integration/viewer_spec.mjs | 72 ++++++++++++++------------------ 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/test/integration/viewer_spec.mjs b/test/integration/viewer_spec.mjs index 20a53759b..40634dc0d 100644 --- a/test/integration/viewer_spec.mjs +++ b/test/integration/viewer_spec.mjs @@ -42,23 +42,40 @@ describe("PDF viewer", () => { await closePages(pages); }); - async function getTextAt(page, pageNumber, coordX, coordY) { - await page.waitForFunction( - pageNum => - !document.querySelector( - `.page[data-page-number="${pageNum}"] > .textLayer` - ).hidden, - {}, - pageNumber + async function waitForTextAfterZoom(page, originX, originY, scale, text) { + const handlePromise = await createPromise(page, resolve => { + const callback = e => { + if (e.pageNumber === 2) { + window.PDFViewerApplication.eventBus.off( + "textlayerrendered", + callback + ); + resolve(); + } + }; + window.PDFViewerApplication.eventBus.on("textlayerrendered", callback); + }); + + await page.evaluate( + (scaleFactor, origin) => { + window.PDFViewerApplication.pdfViewer.updateScale({ + drawingDelay: 0, + scaleFactor, + origin, + }); + }, + scale, + [originX, originY] ); - return page.evaluate( - (x, y) => document.elementFromPoint(x, y)?.textContent, - coordX, - coordY + + await awaitPromise(handlePromise); + + await page.waitForFunction( + `document.elementFromPoint(${originX}, ${originY})?.textContent === "${text}"` ); } - it("supports specifiying a custom origin", async () => { + it("supports specifying a custom origin", async () => { await Promise.all( pages.map(async ([browserName, page]) => { // We use this text span of page 2 because: @@ -72,33 +89,8 @@ describe("PDF viewer", () => { const originX = rect.x + rect.width / 2; const originY = rect.y + rect.height / 2; - await page.evaluate( - origin => { - window.PDFViewerApplication.pdfViewer.increaseScale({ - scaleFactor: 2, - origin, - }); - }, - [originX, originY] - ); - const textAfterZoomIn = await getTextAt(page, 2, originX, originY); - expect(textAfterZoomIn) - .withContext(`In ${browserName}, zoom in`) - .toBe(text); - - await page.evaluate( - origin => { - window.PDFViewerApplication.pdfViewer.decreaseScale({ - scaleFactor: 0.8, - origin, - }); - }, - [originX, originY] - ); - const textAfterZoomOut = await getTextAt(page, 2, originX, originY); - expect(textAfterZoomOut) - .withContext(`In ${browserName}, zoom out`) - .toBe(text); + await waitForTextAfterZoom(page, originX, originY, 2, text); + await waitForTextAfterZoom(page, originX, originY, 0.8, text); }) ); });