Skip to content

Commit

Permalink
fixup! Fix flickering on text selection
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed May 6, 2024
1 parent 6c95052 commit 80fda81
Showing 1 changed file with 84 additions and 37 deletions.
121 changes: 84 additions & 37 deletions test/integration/text_layer_spec.mjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
/* Copyright 2024 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, getSpanRectFromText, loadAndWait } from "./test_utils.mjs";
import { startBrowser } from "../test.mjs";

describe("Text layer", () => {
describe("Text selection", () => {
// page.mouse.move(x, y, { steps: ... }) doesn't work in Firefox, because
// puppeteer will send through the CDP protocol fractional intermediate
// positions and Firefox doesn't support them. Use this function to
// round each intermediate position to an integer.
// puppeteer will send fractional intermediate positions and Firefox doesn't
// support them. Use this function to round each intermediate position to an
// integer.
async function moveInSteps(page, from, to, steps) {
const deltaX = to.x - from.x;
const deltaY = to.y - from.y;
Expand All @@ -17,26 +32,63 @@ describe("Text layer", () => {
}
}

function getSelectedText(page) {
return page.evaluate(() => window.getSelection().toString());
}

function middlePosition(rect) {
return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };
}

function middleLeftPosition(rect) {
return { x: rect.x, y: rect.y + rect.height / 2 };
}

function middleBottomPosition(rect) {
return { x: rect.x + rect.width / 2, y: rect.y + rect.height };
return { x: rect.x + 1, y: rect.y + rect.height / 2 };
}

function belowEndPosition(rect) {
return { x: rect.x + rect.width, y: rect.y + rect.height * 1.5 };
}

beforeAll(() => {
jasmine.addAsyncMatchers({
// Check that a page has a selection containing the given text, with
// some tolerance for extra characters before/after.
toHaveRoughlySelected({ pp }) {
return {
async compare(page, expected) {
const TOLERANCE = 10;

const actual = await page.evaluate(() =>
window.getSelection().toString()
);

let start, end;
if (expected instanceof RegExp) {
const match = expected.exec(actual);
start = -1;
if (match) {
start = match.index;
end = start + match[0].length;
}
} else {
start = actual.indexOf(expected);
if (start !== -1) end = start + expected.length;

Check failure on line 70 in test/integration/text_layer_spec.mjs

View workflow job for this annotation

GitHub Actions / Lint (lts/*)

Expected { after 'if' condition
}

const pass =
start !== -1 &&
start < TOLERANCE &&
end > actual.length - TOLERANCE;

return {
pass,
message: `Expected ${pp(
actual.length > 200
? actual.slice(0, 100) + "[...]" + actual.slice(-100)
: actual
)} to ${pass ? "not " : ""}roughly match ${pp(expected)}.`,
};
},
};
},
});
});

describe("using mouse", () => {
let pages;

Expand Down Expand Up @@ -71,14 +123,11 @@ describe("Text layer", () => {
await moveInSteps(page, positionStart, positionEnd, 20);
await page.mouse.up();

expect(await getSelectedText(page))
await expectAsync(page)
.withContext(`In ${browserName}`)
.toBe(
browserName === "chrome"
? "code sequences, records\n" +
"them, and compiles them to fast native code. We call such a se-"
: "ecode sequences, records\n" +
"them, and compiles them to fast native code. We call such "
.toHaveRoughlySelected(
"code sequences, records\n" +
"them, and compiles them to fast native code. We call suc"
);
})
);
Expand Down Expand Up @@ -116,7 +165,7 @@ describe("Text layer", () => {
page,
2,
"Hence, recording and compiling a trace"
).then(middleBottomPosition),
).then(middlePosition),
getSpanRectFromText(
page,
2,
Expand All @@ -130,23 +179,19 @@ describe("Text layer", () => {
await moveInSteps(page, positionStartPage1, positionEndPage1, 20);
await moveInSteps(page, positionEndPage1, positionStartPage2, 20);

expect(await getSelectedText(page))
await expectAsync(page)
.withContext(`In ${browserName}, first selection`)
.toMatch(
browserName === "chrome"
? /^e path through the program .*Hence, recording an$/s
: /^ path through the program .*Hence, recording an$/s
.toHaveRoughlySelected(
/path through the program .*Hence, recording a/s
);

await moveInSteps(page, positionStartPage2, positionEndPage2, 20);
await page.mouse.up();

expect(await getSelectedText(page))
await expectAsync(page)
.withContext(`In ${browserName}, second selection`)
.toMatch(
browserName === "chrome"
? /^e path through.*Hence, recording and .* tracing, and give up$/s
: /^ path through.*Hence, recording and .* tracing, and give $/s
.toHaveRoughlySelected(
/path through.*Hence, recording and .* tracing, and give/s
);
})
);
Expand All @@ -158,6 +203,8 @@ describe("Text layer", () => {
let page;

beforeAll(async () => {
// Chrome does not support simluating caret-based selection, so this
// test only runs in Firefox.
browser = await startBrowser({
browserName: "firefox",
startUrl: "",
Expand All @@ -180,7 +227,7 @@ describe("Text layer", () => {
await browser.close();
});

it("doesn't jump when moving selection", async () => {
fit("doesn't jump when moving selection", async () => {

Check failure on line 230 in test/integration/text_layer_spec.mjs

View workflow job for this annotation

GitHub Actions / Lint (lts/*)

Unexpected fit
const [initialStart, initialEnd, finalEnd] = await Promise.all([
getSpanRectFromText(
page,
Expand All @@ -204,9 +251,9 @@ describe("Text layer", () => {
await moveInSteps(page, initialStart, initialEnd, 20);
await page.mouse.up();

expect(await getSelectedText(page))
await expectAsync(page)
.withContext(`first selection`)
.toBe("(frequently executed) byt");
.toHaveRoughlySelected("(frequently executed) byt");

const initialCaretPos = {
x: initialEnd.x,
Expand All @@ -226,17 +273,17 @@ describe("Text layer", () => {
await moveInSteps(page, initialCaretPos, intermediateCaretPos, 20);
await page.mouse.up();

expect(await getSelectedText(page))
await expectAsync(page)
.withContext(`second selection`)
.toMatch(/^\(frequently .* We call such a se-$/s);
.toHaveRoughlySelected(/\(frequently .* We call such a se/s);

await page.mouse.down();
await moveInSteps(page, intermediateCaretPos, finalCaretPos, 20);
await page.mouse.up();

expect(await getSelectedText(page))
await expectAsync(page)
.withContext(`third selection`)
.toMatch(/^\(frequently .* We call such a se-$/s);
.toHaveRoughlySelected(/\(frequently .* We call such a se/s);
});
});
});
Expand Down

0 comments on commit 80fda81

Please sign in to comment.