Skip to content

Commit

Permalink
Merge branch 'main' into update-dependency-specificity
Browse files Browse the repository at this point in the history
  • Loading branch information
david-tejada committed Oct 5, 2024
2 parents 732ad83 + 9a409c2 commit 7fa24ae
Show file tree
Hide file tree
Showing 22 changed files with 489 additions and 1,047 deletions.
12 changes: 4 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,14 @@ jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: npx lockfile-lint --path package-lock.json --validate-https
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
env:
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true"
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install
- uses: david-tejada/puppeteer-headful@master
with:
args: npm test
- run: npm test
7 changes: 6 additions & 1 deletion .parcelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
"extends": "@parcel/config-webextension"
"extends": "@parcel/config-webextension",
"optimizers": {
"*.js": [
"@parcel/optimizer-terser"
]
}
}
3 changes: 1 addition & 2 deletions .terserrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"output": {
"beautify": true,
"indent_level": 2
"beautify": false
}
}
1 change: 1 addition & 0 deletions .xo-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"rules": {
"@typescript-eslint/switch-exhaustiveness-check": "off",
"n/prefer-global/process": "off",
"no-unused-vars": [
"error",
{
Expand Down
152 changes: 80 additions & 72 deletions Rango/Rango for Safari.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

47 changes: 23 additions & 24 deletions e2e/keyboardClicking.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { keyTap } from "@hurdlegroup/robotjs";
import { type Frame, type Page } from "puppeteer";
import { type Frame } from "puppeteer";
import { rangoCommandWithoutTarget } from "./utils/rangoCommands";
import { sleep } from "./utils/testHelpers";

async function testKeyboardClickingHighlighting(page: Page | Frame) {
await page.waitForSelector(".rango-hint");
async function testKeyboardClickingHighlighting(frame?: Frame) {
const pageOrFrame = frame ?? page;
await pageOrFrame.waitForSelector(".rango-hint");

const borderWidthBefore = await page.$eval(".rango-hint", (element) => {
const inner = element.shadowRoot!.querySelector(".inner")!;
return Number.parseInt(window.getComputedStyle(inner).borderWidth, 10);
});
const borderWidthBefore = await pageOrFrame.$eval(
".rango-hint",
(element) => {
const inner = element.shadowRoot!.querySelector(".inner")!;
return Number.parseInt(window.getComputedStyle(inner).borderWidth, 10);
}
);

keyTap("a");
await page.keyboard.type("a");
await sleep(100);

const [borderWidthAfter, borderColorAfter] = await page.$eval(
const [borderWidthAfter, borderColorAfter] = await pageOrFrame.$eval(
".rango-hint",
(element) => {
const inner = element.shadowRoot!.querySelector(".inner")!;
Expand All @@ -26,11 +29,11 @@ async function testKeyboardClickingHighlighting(page: Page | Frame) {
expect(borderWidthAfter).toBe(borderWidthBefore + 1);
expect(borderColorAfter).toMatch(/^rgba\(.+0\.7\)$/);

keyTap("a");
await page.keyboard.type("a");
await sleep(100);

const [borderWidthAfterCompletion, borderColorAfterCompletion] =
await page.$eval(".rango-hint", (element) => {
await pageOrFrame.$eval(".rango-hint", (element) => {
const inner = element.shadowRoot!.querySelector(".inner")!;
const style = window.getComputedStyle(inner);
return [Number.parseInt(style.borderWidth, 10), style.borderColor];
Expand Down Expand Up @@ -82,16 +85,14 @@ describe("With hints in main frame", () => {
});

test("Typing the hint characters clicks the link", async () => {
keyTap("a");
keyTap("a");

await page.keyboard.type("aa");
await page.waitForNavigation();

expect(page.url()).toBe("http://localhost:8080/singleLink.html#");
});

test("Typing one hint character marks the hint with a border 1px wider and opacity 0.7 and resets after typing the second character", async () => {
await testKeyboardClickingHighlighting(page);
await testKeyboardClickingHighlighting();
});
});

Expand All @@ -117,15 +118,13 @@ describe("With hints in other frames", () => {
});

test("Typing the hint characters clicks the link", async () => {
const frame = await page.$("iframe");
const contentFrame = await frame!.contentFrame();
await contentFrame.waitForSelector(".rango-hint");

keyTap("a");
keyTap("a");
const $frame = await page.$("iframe");
const frame = await $frame!.contentFrame();
await frame.waitForSelector(".rango-hint");

await contentFrame.waitForNavigation();
await page.keyboard.type("aa");
await frame.waitForNavigation();

expect(contentFrame.url()).toBe("http://localhost:8080/singleLink.html#");
expect(frame.url()).toBe("http://localhost:8080/singleLink.html#");
});
});
6 changes: 3 additions & 3 deletions e2e/noContentScript.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import clipboard from "clipboardy";
import { type ResponseToTalon } from "../src/typings/RequestFromTalon";
import {
rangoCommandWithTarget,
rangoCommandWithoutTarget,
} from "./utils/rangoCommands";
import { storageClipboard } from "./utils/serviceWorker";
import { sleep } from "./utils/testHelpers";

beforeEach(async () => {
Expand All @@ -14,7 +14,7 @@ describe("Direct clicking", () => {
test("If no content script is loaded in the current page it sends the command to talon to type the characters", async () => {
await rangoCommandWithTarget("directClickElement", ["a"]);
await sleep(300);
const clip = clipboard.readSync();
const clip = await storageClipboard.readText();
const response = JSON.parse(clip) as ResponseToTalon;
const found = response.actions.find(
(action) => action.name === "typeTargetCharacters"
Expand All @@ -27,7 +27,7 @@ describe("Direct clicking", () => {
describe("Background commands", () => {
test("Commands that don't need the content script are still able to run", async () => {
await rangoCommandWithoutTarget("copyLocationProperty", "href");
const clip = clipboard.readSync();
const clip = await storageClipboard.readText();
const response = JSON.parse(clip) as ResponseToTalon;
const action = response.actions[0]!;

Expand Down
2 changes: 2 additions & 0 deletions e2e/scroll.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
import { sleep } from "./utils/testHelpers";
import { getHintForElement } from "./utils/getHintForElement";

jest.retryTimes(3);

function getCenter(element: Element) {
const { top, height } = element.getBoundingClientRect();
return top + height / 2;
Expand Down
25 changes: 12 additions & 13 deletions e2e/utils/rangoCommands.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/* eslint-disable no-await-in-loop */
import { keyTap } from "@hurdlegroup/robotjs";
import clipboard from "clipboardy";
import { storageClipboard, runTestRequest } from "./serviceWorker";
import { sleep } from "./testHelpers";

async function waitForCompletion() {
async function waitResponseReady() {
let message: any;

while (!message || message.type !== "response") {
const clip = clipboard.readSync();
const clip = await storageClipboard.readText();

try {
message = JSON.parse(clip) as unknown;
} catch {}
} catch {
// Ignore parsing errors
}

await sleep(10);
}
Expand All @@ -32,11 +33,10 @@ export async function rangoCommandWithTarget(
},
};

const commandString = JSON.stringify(command);
const request = JSON.stringify(command);

clipboard.writeSync(commandString);
keyTap("3", ["control", "shift"]);
await waitForCompletion();
await runTestRequest(request);
await waitResponseReady();
}

export async function rangoCommandWithoutTarget(
Expand All @@ -52,9 +52,8 @@ export async function rangoCommandWithoutTarget(
},
};

const commandString = JSON.stringify(command);
const request = JSON.stringify(command);

clipboard.writeSync(commandString);
keyTap("3", ["control", "shift"]);
await waitForCompletion();
await runTestRequest(request);
await waitResponseReady();
}
41 changes: 41 additions & 0 deletions e2e/utils/serviceWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { TargetType } from "puppeteer";

async function getServiceWorker() {
const workerTarget = await browser.waitForTarget(
(target) => target.type() === TargetType.SERVICE_WORKER
);

return (await workerTarget.worker())!;
}

/**
* This is used to make headless testing possible. Because in Chrome for Testing
* `document.execCommand` doesn't work we need a way to test without using the
* real clipboard. It reads and writes from and to local storage.
*/
export const storageClipboard = {
async readText() {
const worker = await getServiceWorker();
const { clipboard } = (await worker.evaluate(async () =>
chrome.storage.local.get("clipboard")
)) as { clipboard: string };

return clipboard;
},
async writeText(text: string) {
const worker = await getServiceWorker();

await worker.evaluate(async (text) => {
await chrome.storage.local.set({ clipboard: text });
}, text);
},
};

export async function runTestRequest(request: string) {
const worker = await getServiceWorker();

await worker.evaluate(async (request) => {
await chrome.storage.local.set({ clipboard: request });
dispatchEvent(new CustomEvent("handle-test-request"));
}, request);
}
2 changes: 1 addition & 1 deletion jest-puppeteer.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ module.exports = {
launch: {
dumpio: false,
devtools: false,
headless: false,
product: "chrome",
executablePath: process.env.PUPPETEER_EXEC_PATH,
args: [
"--remote-debugging-port=9222",
"--no-sandbox",
`--disable-extensions-except=${EXTENSION_PATH}`,
`--load-extension=${EXTENSION_PATH}`,
Expand Down
Loading

0 comments on commit 7fa24ae

Please sign in to comment.