pdf.js/test/integration/copy_paste_spec.mjs
Tim van der Meij 55ba4aa66a
Refactor the copy/paste logic in the integration tests
The integration tests are currently not consistent in how they do
copy/pasting: some tests use the `kbCopy`/`kbPaste` functions with
waiting for the event inline, some have their own helper function to
combine those actions and some even call `kbCopy`/`kbPaste` without
waiting for the event at all (which can cause intermittent failures).

This commit fixes the issues by providing a set of four helper functions
that all tests use and that abstract e.g. waiting for the event away
from the caller. This makes the invididual tests simpler and consistent,
reduces code duplication and fixes possible intermittent failures
due to not waiting for events to trigger.
2024-06-26 14:48:42 +02:00

180 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Copyright 2023 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
closePages,
copy,
kbSelectAll,
loadAndWait,
mockClipboard,
waitForEvent,
} from "./test_utils.mjs";
const selectAll = async page => {
const promise = waitForEvent(page, "selectionchange");
await kbSelectAll(page);
await promise;
await page.waitForFunction(() => {
const selection = document.getSelection();
const hiddenCopyElement = document.getElementById("hiddenCopyElement");
return selection.containsNode(hiddenCopyElement);
});
};
describe("Copy and paste", () => {
describe("all text", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait("tracemonkey.pdf", "#hiddenCopyElement", 100);
await mockClipboard(pages);
});
afterAll(async () => {
await closePages(pages);
});
it("must check that we've all the contents on copy/paste", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await page.waitForSelector(
".page[data-page-number='1'] .textLayer .endOfContent"
);
await selectAll(page);
await copy(page);
await page.waitForFunction(
`document.querySelector('#viewerContainer').style.cursor !== "wait"`
);
await page.waitForFunction(
async () =>
!!(await navigator.clipboard.readText())?.includes(
"Dynamic languages such as JavaScript"
)
);
const text = await page.evaluate(() =>
navigator.clipboard.readText()
);
expect(
text.includes("This section provides an overview of our system")
)
.withContext(`In ${browserName}`)
.toEqual(true);
expect(
text.includes(
"are represented by function calls. This makes the LIR used by"
)
)
.withContext(`In ${browserName}`)
.toEqual(true);
expect(
text.includes("When compiling loops, we consult the oracle before")
)
.withContext(`In ${browserName}`)
.toEqual(true);
expect(text.includes("Nested Trace Tree Formation"))
.withContext(`In ${browserName}`)
.toEqual(true);
expect(
text.includes(
"An important detail is that the call to the inner trace"
)
)
.withContext(`In ${browserName}`)
.toEqual(true);
expect(text.includes("When trace recording is completed, nanojit"))
.withContext(`In ${browserName}`)
.toEqual(true);
expect(
text.includes(
"SpiderMonkey, like many VMs, needs to preempt the user program"
)
)
.withContext(`In ${browserName}`)
.toEqual(true);
expect(
text.includes(
"Using similar computations, we find that trace recording takes"
)
)
.withContext(`In ${browserName}`)
.toEqual(true);
expect(
text.includes(
"specialization algorithm. We also described our trace compiler"
)
)
.withContext(`In ${browserName}`)
.toEqual(true);
expect(
text.includes(
"dynamic optimization system. In Proceedings of the ACM SIGPLAN"
)
)
.withContext(`In ${browserName}`)
.toEqual(true);
})
);
});
});
describe("Copy/paste and ligatures", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait(
"copy_paste_ligatures.pdf",
"#hiddenCopyElement",
100
);
await mockClipboard(pages);
});
afterAll(async () => {
await closePages(pages);
});
it("must check that the ligatures have been removed when the text has been copied", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await page.waitForSelector(
".page[data-page-number='1'] .textLayer .endOfContent"
);
await selectAll(page);
await copy(page);
await page.waitForFunction(
`document.querySelector('#viewerContainer').style.cursor !== "wait"`
);
await page.waitForFunction(
async () => !!(await navigator.clipboard.readText())
);
const text = await page.evaluate(() =>
navigator.clipboard.readText()
);
expect(text)
.withContext(`In ${browserName}`)
.toEqual("abcdeffffiflffifflſtstghijklmno");
})
);
});
});
});