Use page.evaluateHandle when we want to await on document promises in integration tests

For reference: https://github.com/mozilla/pdf.js/pull/17378#issuecomment-1842864939
This commit is contained in:
Calixte Denizet 2023-12-06 15:27:31 +01:00
parent f54cfe065a
commit c63af10191
4 changed files with 122 additions and 103 deletions

View File

@ -14,7 +14,9 @@
*/ */
import { import {
awaitPromise,
closePages, closePages,
createPromise,
dragAndDropAnnotation, dragAndDropAnnotation,
getEditors, getEditors,
getEditorSelector, getEditorSelector,
@ -3017,27 +3019,21 @@ describe("FreeText Editor", () => {
`${getEditorSelector(0)} .overlay.enabled` `${getEditorSelector(0)} .overlay.enabled`
); );
let promise = page.evaluate( let handle = await createPromise(page, resolve => {
() => document.addEventListener("selectionchange", resolve, {
new Promise(resolve => { once: true,
document.addEventListener("selectionchange", resolve, { });
once: true, });
});
})
);
await page.click("#pageNumber"); await page.click("#pageNumber");
await promise; await awaitPromise(handle);
promise = page.evaluate( handle = await createPromise(page, resolve => {
() => document
new Promise(resolve => { .getElementById("pageNumber")
document .addEventListener("keyup", resolve, { once: true });
.getElementById("pageNumber") });
.addEventListener("keyup", resolve, { once: true });
})
);
await page.keyboard.press("Backspace"); await page.keyboard.press("Backspace");
await promise; await awaitPromise(handle);
let content = await page.$eval("#pageNumber", el => let content = await page.$eval("#pageNumber", el =>
el.innerText.trimEnd() el.innerText.trimEnd()

View File

@ -14,7 +14,9 @@
*/ */
import { import {
awaitPromise,
closePages, closePages,
createPromise,
getEditorSelector, getEditorSelector,
getSelectedEditors, getSelectedEditors,
kbRedo, kbRedo,
@ -26,12 +28,9 @@ import {
} from "./test_utils.mjs"; } from "./test_utils.mjs";
const waitForPointerUp = page => const waitForPointerUp = page =>
page.evaluate( createPromise(page, resolve => {
() => window.addEventListener("pointerup", resolve, { once: true });
new Promise(resolve => { });
window.addEventListener("pointerup", resolve, { once: true });
})
);
const selectAll = async page => { const selectAll = async page => {
await kbSelectAll(page); await kbSelectAll(page);
@ -78,12 +77,12 @@ describe("Ink Editor", () => {
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
const x = rect.x + 100 + i * 100; const x = rect.x + 100 + i * 100;
const y = rect.y + 100 + i * 100; const y = rect.y + 100 + i * 100;
const promise = waitForPointerUp(page); const clickHandle = await waitForPointerUp(page);
await page.mouse.move(x, y); await page.mouse.move(x, y);
await page.mouse.down(); await page.mouse.down();
await page.mouse.move(x + 50, y + 50); await page.mouse.move(x + 50, y + 50);
await page.mouse.up(); await page.mouse.up();
await promise; await awaitPromise(clickHandle);
await commit(page); await commit(page);
} }
@ -114,12 +113,12 @@ describe("Ink Editor", () => {
const xStart = rect.x + 300; const xStart = rect.x + 300;
const yStart = rect.y + 300; const yStart = rect.y + 300;
const clickPromise = waitForPointerUp(page); const clickHandle = await waitForPointerUp(page);
await page.mouse.move(xStart, yStart); await page.mouse.move(xStart, yStart);
await page.mouse.down(); await page.mouse.down();
await page.mouse.move(xStart + 50, yStart + 50); await page.mouse.move(xStart + 50, yStart + 50);
await page.mouse.up(); await page.mouse.up();
await clickPromise; await awaitPromise(clickHandle);
await commit(page); await commit(page);
@ -177,12 +176,12 @@ describe("Ink Editor", () => {
const x = rect.x + 20; const x = rect.x + 20;
const y = rect.y + 20; const y = rect.y + 20;
const clickPromise = waitForPointerUp(page); const clickHandle = await waitForPointerUp(page);
await page.mouse.move(x, y); await page.mouse.move(x, y);
await page.mouse.down(); await page.mouse.down();
await page.mouse.move(x + 50, y + 50); await page.mouse.move(x + 50, y + 50);
await page.mouse.up(); await page.mouse.up();
await clickPromise; await awaitPromise(clickHandle);
await commit(page); await commit(page);
@ -222,12 +221,12 @@ describe("Ink Editor", () => {
const x = rect.x + 20; const x = rect.x + 20;
const y = rect.y + 20; const y = rect.y + 20;
const clickPromise = waitForPointerUp(page); const clickHandle = await waitForPointerUp(page);
await page.mouse.move(x, y); await page.mouse.move(x, y);
await page.mouse.down(); await page.mouse.down();
await page.mouse.move(x + 50, y + 50); await page.mouse.move(x + 50, y + 50);
await page.mouse.up(); await page.mouse.up();
await clickPromise; await awaitPromise(clickHandle);
await commit(page); await commit(page);
@ -284,12 +283,12 @@ describe("Ink Editor", () => {
const x = rect.x + 20; const x = rect.x + 20;
const y = rect.y + 20; const y = rect.y + 20;
const clickPromise = waitForPointerUp(page); const clickHandle = await waitForPointerUp(page);
await page.mouse.move(x, y); await page.mouse.move(x, y);
await page.mouse.down(); await page.mouse.down();
await page.mouse.move(x + 50, y + 50); await page.mouse.move(x + 50, y + 50);
await page.mouse.up(); await page.mouse.up();
await clickPromise; await awaitPromise(clickHandle);
page.mouse.click(rect.x - 10, rect.y + 10); page.mouse.click(rect.x - 10, rect.y + 10);
await page.waitForSelector(`${getEditorSelector(0)}.disabled`); await page.waitForSelector(`${getEditorSelector(0)}.disabled`);

View File

@ -14,6 +14,7 @@
*/ */
import { import {
awaitPromise,
closePages, closePages,
getEditorDimensions, getEditorDimensions,
getEditorSelector, getEditorSelector,
@ -81,28 +82,27 @@ const copyImage = async (page, imagePath, number) => {
let hasPasteEvent = false; let hasPasteEvent = false;
while (!hasPasteEvent) { while (!hasPasteEvent) {
// We retry to paste if nothing has been pasted before 500ms. // We retry to paste if nothing has been pasted before 500ms.
const promise = Promise.race([ const handle = await page.evaluateHandle(() => {
page.evaluate( let callback = null;
() => return [
Promise.race([
new Promise(resolve => { new Promise(resolve => {
document.addEventListener( callback = e => resolve(e.clipboardData.items.length !== 0);
"paste", document.addEventListener("paste", callback, {
e => resolve(e.clipboardData.items.length !== 0), once: true,
{ });
once: true, }),
}
);
})
),
page.evaluate(
() =>
new Promise(resolve => { new Promise(resolve => {
setTimeout(() => resolve(false), 500); setTimeout(() => {
}) document.removeEventListener("paste", callback);
), resolve(false);
]); }, 500);
}),
]),
];
});
await kbPaste(page); await kbPaste(page);
hasPasteEvent = await promise; hasPasteEvent = await awaitPromise(handle);
} }
await waitForImage(page, getEditorSelector(number)); await waitForImage(page, getEditorSelector(number));
@ -227,11 +227,11 @@ describe("Stamp Editor", () => {
`${getEditorSelector(i)} .resizers.hidden` `${getEditorSelector(i)} .resizers.hidden`
); );
const promise = waitForAnnotationEditorLayer(page); const handle = await waitForAnnotationEditorLayer(page);
await page.evaluate(() => { await page.evaluate(() => {
window.PDFViewerApplication.rotatePages(90); window.PDFViewerApplication.rotatePages(90);
}); });
await promise; await awaitPromise(handle);
await page.focus(".stampEditor"); await page.focus(".stampEditor");
await waitForSelectedEditor(page, getEditorSelector(i)); await waitForSelectedEditor(page, getEditorSelector(i));
@ -257,11 +257,11 @@ describe("Stamp Editor", () => {
.toEqual("nwse-resize"); .toEqual("nwse-resize");
} }
const promise = waitForAnnotationEditorLayer(page); const handle = await waitForAnnotationEditorLayer(page);
await page.evaluate(() => { await page.evaluate(() => {
window.PDFViewerApplication.rotatePages(90); window.PDFViewerApplication.rotatePages(90);
}); });
await promise; await awaitPromise(handle);
} }
}) })
); );
@ -410,16 +410,19 @@ describe("Stamp Editor", () => {
// We check that the alt-text button works correctly with the // We check that the alt-text button works correctly with the
// keyboard. // keyboard.
await page.evaluate(sel => { const handle = await page.evaluateHandle(sel => {
document.getElementById("viewerContainer").focus(); document.getElementById("viewerContainer").focus();
return new Promise(resolve => { return [
setTimeout(() => { new Promise(resolve => {
const el = document.querySelector(sel); setTimeout(() => {
el.addEventListener("focus", resolve, { once: true }); const el = document.querySelector(sel);
el.focus({ focusVisible: true }); el.addEventListener("focus", resolve, { once: true });
}, 0); el.focus({ focusVisible: true });
}); }, 0);
}),
];
}, buttonSelector); }, buttonSelector);
await awaitPromise(handle);
await (browserName === "chrome" await (browserName === "chrome"
? page.waitForSelector(`${buttonSelector}:focus`) ? page.waitForSelector(`${buttonSelector}:focus`)
: page.waitForSelector(`${buttonSelector}:focus-visible`)); : page.waitForSelector(`${buttonSelector}:focus-visible`));

View File

@ -54,6 +54,18 @@ function loadAndWait(filename, selector, zoom, pageSetup) {
); );
} }
function createPromise(page, callback) {
return page.evaluateHandle(
// eslint-disable-next-line no-eval
cb => [new Promise(eval(`(${cb})`))],
callback.toString()
);
}
function awaitPromise(promise) {
return promise.evaluate(([p]) => p);
}
function closePages(pages) { function closePages(pages) {
return Promise.all( return Promise.all(
pages.map(async ([_, page]) => { pages.map(async ([_, page]) => {
@ -100,23 +112,29 @@ function getSelectedEditors(page) {
} }
async function waitForEvent(page, eventName, timeout = 5000) { async function waitForEvent(page, eventName, timeout = 5000) {
const hasTimedout = await Promise.race([ const handle = await page.evaluateHandle(
// add event listener and wait for event to fire before returning (name, timeOut) => {
page.evaluate( let callback = null;
name => return [
new Promise(resolve => { Promise.race([
document.addEventListener(name, () => resolve(false), { once: true }); new Promise(resolve => {
}), // add event listener and wait for event to fire before returning
eventName callback = () => resolve(false);
), document.addEventListener(name, callback, { once: true });
page.evaluate( }),
timeOut => new Promise(resolve => {
new Promise(resolve => { setTimeout(() => {
setTimeout(() => resolve(true), timeOut); document.removeEventListener(name, callback);
}), resolve(true);
timeout }, timeOut);
), }),
]); ]),
];
},
eventName,
timeout
);
const hasTimedout = await awaitPromise(handle);
if (hasTimedout === true) { if (hasTimedout === true) {
console.log(`waitForEvent: timeout waiting for ${eventName}`); console.log(`waitForEvent: timeout waiting for ${eventName}`);
} }
@ -254,35 +272,36 @@ async function dragAndDropAnnotation(page, startX, startY, tX, tY) {
await page.waitForSelector("#viewer:not(.noUserSelect)"); await page.waitForSelector("#viewer:not(.noUserSelect)");
} }
async function waitForAnnotationEditorLayer(page) { function waitForAnnotationEditorLayer(page) {
return page.evaluate(() => { return createPromise(page, resolve => {
return new Promise(resolve => { window.PDFViewerApplication.eventBus.on(
window.PDFViewerApplication.eventBus.on( "annotationeditorlayerrendered",
"annotationeditorlayerrendered", resolve
resolve );
);
});
}); });
} }
async function waitForTextLayer(page) { async function waitForTextLayer(page) {
return page.evaluate(() => { const handle = await createPromise(page, resolve => {
return new Promise(resolve => { window.PDFViewerApplication.eventBus.on("textlayerrendered", resolve);
window.PDFViewerApplication.eventBus.on("textlayerrendered", resolve);
});
}); });
return awaitPromise(handle);
} }
async function scrollIntoView(page, selector) { async function scrollIntoView(page, selector) {
await page.evaluate(sel => { const handle = await page.evaluateHandle(
const element = document.querySelector(sel); sel => [
element.scrollIntoView({ behavior: "instant", block: "start" }); new Promise(resolve => {
return new Promise(resolve => { document
document .getElementById("viewerContainer")
.getElementById("viewerContainer") .addEventListener("scrollend", resolve, { once: true });
.addEventListener("scrollend", resolve, { once: true }); const element = document.querySelector(sel);
}); element.scrollIntoView({ behavior: "instant", block: "start" });
}, selector); }),
],
selector
);
return awaitPromise(handle);
} }
async function hover(page, selector) { async function hover(page, selector) {
@ -417,8 +436,10 @@ async function kbDeleteLastWord(page) {
} }
export { export {
awaitPromise,
clearInput, clearInput,
closePages, closePages,
createPromise,
dragAndDropAnnotation, dragAndDropAnnotation,
getAnnotationStorage, getAnnotationStorage,
getComputedStyleSelector, getComputedStyleSelector,