Skip to content

Commit

Permalink
Add browser emulation tests.
Browse files Browse the repository at this point in the history
This includes a regression test for #167
  • Loading branch information
lgarron committed Apr 24, 2024
1 parent f362afa commit 7950bcd
Show file tree
Hide file tree
Showing 13 changed files with 341 additions and 27 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 19.4
- uses: oven-sh/setup-bun@v1
- run: npm install
- run: make build
- run: make build-demo
- run: make lint
- run: make test-no-es6-browser-globals
- run: make test-bun
- run: make mock-test
- run: make format
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://github.com/lgarron/Makefile-scripts

# Note: the first command becomes the default `make` target.
NPM_COMMANDS = build build-demo test mock-test test-no-es6-browser-globals dev lint format clean prepack
NPM_COMMANDS = build build-demo test mock-test test-no-es6-browser-globals test-bun dev lint format clean prepack

.PHONY: $(NPM_COMMANDS)
$(NPM_COMMANDS):
Expand Down
108 changes: 91 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 5 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"type": "module",
"devDependencies": {
"@biomejs/biome": "^1.1.0",
"@types/node": "^18.11.18",
"@types/bun": "^1.1.0",
"barely-a-dev-server": "^0.6.0",
"esbuild": "^0.19.11",
"typescript": "^4.9.4"
"typescript": "^5.4.5"
},
"repository": {
"type": "git",
Expand All @@ -31,17 +31,14 @@
"bugs": {
"url": "https://github.com/lgarron/clipboard-polyfill/issues"
},
"files": [
"/dist",
"/overwrite-globals",
"README.md"
],
"files": ["/dist", "/overwrite-globals", "README.md"],
"scripts": {
"build": "node script/build.js && npx tsc --project tsconfig.json",
"build-demo": "node script/build-demo.js",
"test": "npm run build && npm run build-demo && npm run lint && npm run test-no-es6-browser-globals",
"test": "npm run build && npm run build-demo && npm run lint && npm run test-bun && npm run test-no-es6-browser-globals",
"mock-test": "./script/mock-test.bash",
"test-no-es6-browser-globals": "node dist/es6/clipboard-polyfill.es6.js",
"test-bun": "bun script/test-bun.ts",
"dev": "node script/dev.js",
"lint": "npx @biomejs/biome check ./script ./src",
"format": "npx @biomejs/biome format --write ./script ./src",
Expand Down
18 changes: 18 additions & 0 deletions script/test-bun.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { basename } from "node:path";
import { Glob, spawn } from "bun";

const glob = new Glob("**/*.test.ts");

console.log("Running bun test files individually");

// Scans the current working directory and each of its sub-directories recursively
for await (const file of glob.scan(".")) {
if (basename(file) === "bun-test-cannot-run-all-tests.test.ts") {
continue;
}
console.log(`Running: bun test "${file}"`);

if ((await spawn(["bun", "test", file], {}).exited) !== 0) {
throw new Error(`Bun test failed for file: ${file}`);
}
}
11 changes: 11 additions & 0 deletions src/clipboard-polyfill/implementations/text.blank-document.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { test, expect } from "bun:test";

(globalThis as any).document = {};

test("writeText(…) failure in an unsupported browser", async () => {
const { writeText } = await import("./text");

expect(async () => writeText("hello")).toThrowError(
"document.addEventListener is not a function.",
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { setDebugLog } from "../debug";
import { test, expect, mock } from "bun:test";

const consoleLogMock = mock(console.log);
setDebugLog(consoleLogMock);

test("writeText(…) failure in a blank environmnent", async () => {
const { writeText } = await import("./text");

expect(async () => writeText("hello")).toThrowError(
"Can't find variable: document",
);
expect(consoleLogMock).toHaveBeenCalledTimes(0);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
createDocumentMock,
createDebugLogConsoleMock,
createWriteTextMock,
} from "../../test/mocks";
import { test, expect, mock } from "bun:test";

const debugLogConsoleMock = createDebugLogConsoleMock();
const { documentMock, eventMock } = createDocumentMock();

test("writeText(…) execCommand fallback", async () => {
const { writeText } = await import("./text");

expect(() => writeText("hello execCommand fallback")).not.toThrow();

expect(debugLogConsoleMock.mock.calls).toEqual([
["listener called"],
["regular execCopy worked"],
]);

expect(documentMock.execCommand.mock.calls).toEqual([["copy"]]);

expect(documentMock.addEventListener).toHaveBeenCalledTimes(1);
expect(documentMock.removeEventListener).toHaveBeenCalledTimes(1);

expect(eventMock.preventDefault).toHaveBeenCalledTimes(1);
expect(eventMock.clipboardData.setData.mock.calls).toEqual([
["text/plain", "hello execCommand fallback"],
]);

expect(eventMock.clipboardData.getData.mock.calls).toEqual([["text/plain"]]);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
createDocumentMock,
createDebugLogConsoleMock,
createWriteTextMock,
} from "../../test/mocks";
import { test, expect, mock } from "bun:test";

const debugLogConsoleMock = createDebugLogConsoleMock();
const writeTextMock = createWriteTextMock(async () => {
throw new Error("writeText(…) is disabled");
});
const { documentMock, eventMock } = createDocumentMock();

// Regression test for https://github.com/lgarron/clipboard-polyfill/issues/167
test("writeText(…) success in a modern browser with the async API disabled", async () => {
const { writeText } = await import("./text");

expect(() =>
writeText("hello modern browser with async API disabled"),
).not.toThrow();

expect(debugLogConsoleMock.mock.calls).toEqual([
["Using `navigator.clipboard.writeText()`."],
["listener called"],
["regular execCopy worked"],
]);

expect(writeTextMock.mock.calls).toEqual([
["hello modern browser with async API disabled"],
]);

expect(documentMock.execCommand.mock.calls).toEqual([["copy"]]);

expect(documentMock.addEventListener).toHaveBeenCalledTimes(1);
expect(documentMock.removeEventListener).toHaveBeenCalledTimes(1);

expect(eventMock.preventDefault).toHaveBeenCalledTimes(1);
expect(eventMock.clipboardData.setData.mock.calls).toEqual([
["text/plain", "hello modern browser with async API disabled"],
]);

expect(eventMock.clipboardData.getData.mock.calls).toEqual([["text/plain"]]);
});
26 changes: 26 additions & 0 deletions src/clipboard-polyfill/implementations/text.modern-browser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
createDocumentMock,
createDebugLogConsoleMock,
createWriteTextMock,
} from "../../test/mocks";
import { test, expect, mock } from "bun:test";

const debugLogConsoleMock = createDebugLogConsoleMock();
const writeTextMock = createWriteTextMock();
const { documentMock } = createDocumentMock();

test("writeText(…) success", async () => {
const { writeText } = await import("./text");

expect(() => writeText("hello modern browser")).not.toThrow();

expect(debugLogConsoleMock.mock.calls).toEqual([
["Using `navigator.clipboard.writeText()`."],
]);

expect(writeTextMock.mock.calls).toEqual([["hello modern browser"]]);

expect(documentMock.execCommand).toHaveBeenCalledTimes(0);
expect(documentMock.addEventListener).toHaveBeenCalledTimes(0);
expect(documentMock.removeEventListener).toHaveBeenCalledTimes(0);
});
8 changes: 8 additions & 0 deletions src/test/bun-test-cannot-run-all-tests.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { test, expect } from "bun:test";

test("`bun test` must be run one file at a time", () => {
console.log(
"\n\n\n\n⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️\n\n\n\n[clipboard-polyfill] Each test file requires a fresh global environment before importing library code. Run `make test-bun` to run test files one at a time instead.\n\n\n\n⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️\n\n\n\n",
);
expect(true).toBe(false);
});
Loading

0 comments on commit 7950bcd

Please sign in to comment.