mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-19 14:48:08 +02:00
Merge pull request #18331 from timvandermeij/integration-test-copy-pasting
Refactor the copy/paste logic in the integration tests and fix a race condition involving the `waitForEvent` integration test helper function
This commit is contained in:
commit
6d579081c4
4 changed files with 92 additions and 99 deletions
|
@ -15,7 +15,7 @@
|
|||
|
||||
import {
|
||||
closePages,
|
||||
kbCopy,
|
||||
copy,
|
||||
kbSelectAll,
|
||||
loadAndWait,
|
||||
mockClipboard,
|
||||
|
@ -23,9 +23,11 @@ import {
|
|||
} from "./test_utils.mjs";
|
||||
|
||||
const selectAll = async page => {
|
||||
const promise = waitForEvent(page, "selectionchange");
|
||||
await kbSelectAll(page);
|
||||
await promise;
|
||||
await waitForEvent({
|
||||
page,
|
||||
eventName: "selectionchange",
|
||||
action: () => kbSelectAll(page),
|
||||
});
|
||||
|
||||
await page.waitForFunction(() => {
|
||||
const selection = document.getSelection();
|
||||
|
@ -55,10 +57,7 @@ describe("Copy and paste", () => {
|
|||
);
|
||||
await selectAll(page);
|
||||
|
||||
const promise = waitForEvent(page, "copy");
|
||||
await kbCopy(page);
|
||||
await promise;
|
||||
|
||||
await copy(page);
|
||||
await page.waitForFunction(
|
||||
`document.querySelector('#viewerContainer').style.cursor !== "wait"`
|
||||
);
|
||||
|
@ -159,10 +158,7 @@ describe("Copy and paste", () => {
|
|||
);
|
||||
await selectAll(page);
|
||||
|
||||
const promise = waitForEvent(page, "copy");
|
||||
await kbCopy(page);
|
||||
await promise;
|
||||
|
||||
await copy(page);
|
||||
await page.waitForFunction(
|
||||
`document.querySelector('#viewerContainer').style.cursor !== "wait"`
|
||||
);
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
import {
|
||||
awaitPromise,
|
||||
closePages,
|
||||
copy,
|
||||
copyToClipboard,
|
||||
createPromise,
|
||||
dragAndDropAnnotation,
|
||||
firstPageOnTop,
|
||||
|
@ -30,21 +32,19 @@ import {
|
|||
kbBigMoveLeft,
|
||||
kbBigMoveRight,
|
||||
kbBigMoveUp,
|
||||
kbCopy,
|
||||
kbGoToBegin,
|
||||
kbGoToEnd,
|
||||
kbModifierDown,
|
||||
kbModifierUp,
|
||||
kbPaste,
|
||||
kbRedo,
|
||||
kbSelectAll,
|
||||
kbUndo,
|
||||
loadAndWait,
|
||||
paste,
|
||||
pasteFromClipboard,
|
||||
scrollIntoView,
|
||||
switchToEditor,
|
||||
waitForAnnotationEditorLayer,
|
||||
waitForEvent,
|
||||
waitForSelectedEditor,
|
||||
waitForSerialized,
|
||||
waitForStorageEntries,
|
||||
|
@ -53,16 +53,6 @@ import {
|
|||
} from "./test_utils.mjs";
|
||||
import { PNG } from "pngjs";
|
||||
|
||||
const copyPaste = async page => {
|
||||
let promise = waitForEvent(page, "copy");
|
||||
await kbCopy(page);
|
||||
await promise;
|
||||
|
||||
promise = waitForEvent(page, "paste");
|
||||
await kbPaste(page);
|
||||
await promise;
|
||||
};
|
||||
|
||||
const selectAll = async page => {
|
||||
await kbSelectAll(page);
|
||||
await page.waitForFunction(
|
||||
|
@ -187,7 +177,8 @@ describe("FreeText Editor", () => {
|
|||
);
|
||||
|
||||
await waitForSelectedEditor(page, getEditorSelector(0));
|
||||
await copyPaste(page);
|
||||
await copy(page);
|
||||
await paste(page);
|
||||
await page.waitForSelector(getEditorSelector(1), {
|
||||
visible: true,
|
||||
});
|
||||
|
@ -203,7 +194,8 @@ describe("FreeText Editor", () => {
|
|||
|
||||
expect(pastedContent).withContext(`In ${browserName}`).toEqual(content);
|
||||
|
||||
await copyPaste(page);
|
||||
await copy(page);
|
||||
await paste(page);
|
||||
await page.waitForSelector(getEditorSelector(2), {
|
||||
visible: true,
|
||||
});
|
||||
|
@ -263,7 +255,8 @@ describe("FreeText Editor", () => {
|
|||
);
|
||||
|
||||
await waitForSelectedEditor(page, getEditorSelector(3));
|
||||
await copyPaste(page);
|
||||
await copy(page);
|
||||
await paste(page);
|
||||
await page.waitForSelector(getEditorSelector(4), {
|
||||
visible: true,
|
||||
});
|
||||
|
@ -276,9 +269,7 @@ describe("FreeText Editor", () => {
|
|||
);
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const promise = waitForEvent(page, "paste");
|
||||
await kbPaste(page);
|
||||
await promise;
|
||||
await paste(page);
|
||||
await page.waitForSelector(getEditorSelector(5 + i));
|
||||
}
|
||||
|
||||
|
@ -597,7 +588,8 @@ describe("FreeText Editor", () => {
|
|||
.withContext(`In ${browserName}`)
|
||||
.toEqual([0, 1, 3]);
|
||||
|
||||
await copyPaste(page);
|
||||
await copy(page);
|
||||
await paste(page);
|
||||
await page.waitForSelector(getEditorSelector(6), {
|
||||
visible: true,
|
||||
});
|
||||
|
@ -1275,7 +1267,8 @@ describe("FreeText Editor", () => {
|
|||
);
|
||||
await waitForSelectedEditor(page, getEditorSelector(1));
|
||||
|
||||
await copyPaste(page);
|
||||
await copy(page);
|
||||
await paste(page);
|
||||
await page.waitForSelector(getEditorSelector(6), {
|
||||
visible: true,
|
||||
});
|
||||
|
@ -3425,14 +3418,11 @@ describe("FreeText Editor", () => {
|
|||
);
|
||||
|
||||
await select(0);
|
||||
await pasteFromClipboard(
|
||||
page,
|
||||
{
|
||||
"text/html": "<b>Bold Foo</b>",
|
||||
"text/plain": "Foo",
|
||||
},
|
||||
`${editorSelector} .internal`
|
||||
);
|
||||
await copyToClipboard(page, {
|
||||
"text/html": "<b>Bold Foo</b>",
|
||||
"text/plain": "Foo",
|
||||
});
|
||||
await pasteFromClipboard(page, `${editorSelector} .internal`);
|
||||
|
||||
let lastText = data;
|
||||
|
||||
|
@ -3442,14 +3432,11 @@ describe("FreeText Editor", () => {
|
|||
expect(text).withContext(`In ${browserName}`).toEqual(lastText);
|
||||
|
||||
await select(3);
|
||||
await pasteFromClipboard(
|
||||
page,
|
||||
{
|
||||
"text/html": "<b>Bold Bar</b><br><b>Oof</b>",
|
||||
"text/plain": "Bar\nOof",
|
||||
},
|
||||
`${editorSelector} .internal`
|
||||
);
|
||||
await copyToClipboard(page, {
|
||||
"text/html": "<b>Bold Bar</b><br><b>Oof</b>",
|
||||
"text/plain": "Bar\nOof",
|
||||
});
|
||||
await pasteFromClipboard(page, `${editorSelector} .internal`);
|
||||
|
||||
await waitForTextChange(lastText, editorSelector);
|
||||
text = await getText(editorSelector);
|
||||
|
@ -3457,13 +3444,8 @@ describe("FreeText Editor", () => {
|
|||
expect(text).withContext(`In ${browserName}`).toEqual(lastText);
|
||||
|
||||
await select(0);
|
||||
await pasteFromClipboard(
|
||||
page,
|
||||
{
|
||||
"text/html": "<b>basic html</b>",
|
||||
},
|
||||
`${editorSelector} .internal`
|
||||
);
|
||||
await copyToClipboard(page, { "text/html": "<b>basic html</b>" });
|
||||
await pasteFromClipboard(page, `${editorSelector} .internal`);
|
||||
|
||||
// Nothing should change, so it's hard to wait on something.
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
|
@ -3477,15 +3459,12 @@ describe("FreeText Editor", () => {
|
|||
const prevHTML = await getHTML();
|
||||
|
||||
// Try to paste an image.
|
||||
await pasteFromClipboard(
|
||||
page,
|
||||
{
|
||||
"image/png":
|
||||
// 1x1 transparent png.
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==",
|
||||
},
|
||||
`${editorSelector} .internal`
|
||||
);
|
||||
await copyToClipboard(page, {
|
||||
"image/png":
|
||||
// 1x1 transparent png.
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==",
|
||||
});
|
||||
await pasteFromClipboard(page, `${editorSelector} .internal`);
|
||||
|
||||
// Nothing should change, so it's hard to wait on something.
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
|
@ -3505,14 +3484,11 @@ describe("FreeText Editor", () => {
|
|||
});
|
||||
|
||||
const fooBar = "Foo\nBar\nOof";
|
||||
await pasteFromClipboard(
|
||||
page,
|
||||
{
|
||||
"text/html": "<b>html</b>",
|
||||
"text/plain": fooBar,
|
||||
},
|
||||
`${editorSelector} .internal`
|
||||
);
|
||||
await copyToClipboard(page, {
|
||||
"text/html": "<b>html</b>",
|
||||
"text/plain": fooBar,
|
||||
});
|
||||
await pasteFromClipboard(page, `${editorSelector} .internal`);
|
||||
|
||||
await waitForTextChange("", editorSelector);
|
||||
text = await getText(editorSelector);
|
||||
|
|
|
@ -17,6 +17,8 @@ import {
|
|||
applyFunctionToEditor,
|
||||
awaitPromise,
|
||||
closePages,
|
||||
copy,
|
||||
copyToClipboard,
|
||||
getEditorDimensions,
|
||||
getEditorSelector,
|
||||
getFirstSerialized,
|
||||
|
@ -24,11 +26,10 @@ import {
|
|||
getSerialized,
|
||||
kbBigMoveDown,
|
||||
kbBigMoveRight,
|
||||
kbCopy,
|
||||
kbPaste,
|
||||
kbSelectAll,
|
||||
kbUndo,
|
||||
loadAndWait,
|
||||
paste,
|
||||
pasteFromClipboard,
|
||||
scrollIntoView,
|
||||
serializeBitmapDimensions,
|
||||
|
@ -78,12 +79,10 @@ const copyImage = async (page, imagePath, number) => {
|
|||
const data = fs
|
||||
.readFileSync(path.join(__dirname, imagePath))
|
||||
.toString("base64");
|
||||
await pasteFromClipboard(
|
||||
page,
|
||||
{ "image/png": `data:image/png;base64,${data}` },
|
||||
"",
|
||||
500
|
||||
);
|
||||
|
||||
await copyToClipboard(page, { "image/png": `data:image/png;base64,${data}` });
|
||||
await pasteFromClipboard(page);
|
||||
|
||||
await waitForImage(page, getEditorSelector(number));
|
||||
};
|
||||
|
||||
|
@ -570,13 +569,13 @@ describe("Stamp Editor", () => {
|
|||
await page1.click("#editorStamp");
|
||||
|
||||
await copyImage(page1, "../images/firefox_logo.png", 0);
|
||||
await kbCopy(page1);
|
||||
await copy(page1);
|
||||
|
||||
const [, page2] = pages2[i];
|
||||
await page2.bringToFront();
|
||||
await page2.click("#editorStamp");
|
||||
|
||||
await kbPaste(page2);
|
||||
await paste(page2);
|
||||
|
||||
await waitForImage(page2, getEditorSelector(0));
|
||||
}
|
||||
|
@ -831,8 +830,8 @@ describe("Stamp Editor", () => {
|
|||
);
|
||||
await page.waitForSelector(`${getEditorSelector(0)} .altText.done`);
|
||||
|
||||
await kbCopy(page);
|
||||
await kbPaste(page);
|
||||
await copy(page);
|
||||
await paste(page);
|
||||
await page.waitForSelector(`${getEditorSelector(1)} .altText.done`);
|
||||
await waitForSerialized(page, 2);
|
||||
|
||||
|
|
|
@ -186,13 +186,14 @@ async function getSpanRectFromText(page, pageNumber, text) {
|
|||
);
|
||||
}
|
||||
|
||||
async function waitForEvent(
|
||||
async function waitForEvent({
|
||||
page,
|
||||
eventName,
|
||||
action,
|
||||
selector = null,
|
||||
validator = null,
|
||||
timeout = 5000
|
||||
) {
|
||||
timeout = 5000,
|
||||
}) {
|
||||
const handle = await page.evaluateHandle(
|
||||
(name, sel, validate, timeOut) => {
|
||||
let callback = null,
|
||||
|
@ -227,13 +228,15 @@ async function waitForEvent(
|
|||
validator ? validator.toString() : null,
|
||||
timeout
|
||||
);
|
||||
|
||||
await action();
|
||||
|
||||
const success = await awaitPromise(handle);
|
||||
if (success === null) {
|
||||
console.log(`waitForEvent: ${eventName} didn't trigger within the timeout`);
|
||||
} else if (!success) {
|
||||
console.log(`waitForEvent: ${eventName} triggered, but validation failed`);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
async function waitForStorageEntries(page, nEntries) {
|
||||
|
@ -292,7 +295,15 @@ async function mockClipboard(pages) {
|
|||
);
|
||||
}
|
||||
|
||||
async function pasteFromClipboard(page, data, selector, timeout = 100) {
|
||||
async function copy(page) {
|
||||
await waitForEvent({
|
||||
page,
|
||||
eventName: "copy",
|
||||
action: () => kbCopy(page),
|
||||
});
|
||||
}
|
||||
|
||||
async function copyToClipboard(page, data) {
|
||||
await page.evaluate(async dat => {
|
||||
const items = Object.create(null);
|
||||
for (const [type, value] of Object.entries(dat)) {
|
||||
|
@ -305,15 +316,25 @@ async function pasteFromClipboard(page, data, selector, timeout = 100) {
|
|||
}
|
||||
await navigator.clipboard.write([new ClipboardItem(items)]);
|
||||
}, data);
|
||||
}
|
||||
|
||||
async function paste(page) {
|
||||
await waitForEvent({
|
||||
page,
|
||||
eventName: "paste",
|
||||
action: () => kbPaste(page),
|
||||
});
|
||||
}
|
||||
|
||||
async function pasteFromClipboard(page, selector = null) {
|
||||
const validator = e => e.clipboardData.items.length !== 0;
|
||||
let hasPasteEvent = false;
|
||||
while (!hasPasteEvent) {
|
||||
// We retry to paste if nothing has been pasted before the timeout.
|
||||
const promise = waitForEvent(page, "paste", selector, validator);
|
||||
await kbPaste(page);
|
||||
hasPasteEvent = await promise;
|
||||
}
|
||||
await waitForEvent({
|
||||
page,
|
||||
eventName: "paste",
|
||||
action: () => kbPaste(page),
|
||||
selector,
|
||||
validator,
|
||||
});
|
||||
}
|
||||
|
||||
async function getSerialized(page, filter = undefined) {
|
||||
|
@ -634,6 +655,8 @@ export {
|
|||
clearInput,
|
||||
closePages,
|
||||
closeSinglePage,
|
||||
copy,
|
||||
copyToClipboard,
|
||||
createPromise,
|
||||
dragAndDropAnnotation,
|
||||
firstPageOnTop,
|
||||
|
@ -654,7 +677,6 @@ export {
|
|||
kbBigMoveLeft,
|
||||
kbBigMoveRight,
|
||||
kbBigMoveUp,
|
||||
kbCopy,
|
||||
kbDeleteLastWord,
|
||||
kbFocusNext,
|
||||
kbFocusPrevious,
|
||||
|
@ -662,12 +684,12 @@ export {
|
|||
kbGoToEnd,
|
||||
kbModifierDown,
|
||||
kbModifierUp,
|
||||
kbPaste,
|
||||
kbRedo,
|
||||
kbSelectAll,
|
||||
kbUndo,
|
||||
loadAndWait,
|
||||
mockClipboard,
|
||||
paste,
|
||||
pasteFromClipboard,
|
||||
scrollIntoView,
|
||||
serializeBitmapDimensions,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue