test: add DOM methods to leftover test windows
This commit is contained in:
1 parent
6189a3ec56
commit
f7d7e8e72c
6 files changed
+70
-19
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { Editor } from "@tiptap/core";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import { ensureTestWindowDom } from "../../lib/restore-test-global.mjs";
|
||||
import {
|
||||
filterNoteLinkSuggestions,
|
||||
insertSuggestedNoteLink,
|
||||
@@ -31,6 +32,7 @@ describe("note link suggestion", () => {
|
||||
});
|
||||
|
||||
test("replaces the @ query with the existing internal-note link format", () => {
|
||||
ensureTestWindowDom();
|
||||
const editor = new Editor({
|
||||
extensions: [StarterKit],
|
||||
content: {
|
||||
@@ -64,6 +66,7 @@ describe("note link suggestion", () => {
|
||||
});
|
||||
|
||||
test("uses the untitled fallback for an empty title", () => {
|
||||
ensureTestWindowDom();
|
||||
const editor = new Editor({
|
||||
extensions: [StarterKit],
|
||||
content: {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test";
|
||||
import { Editor } from "@tiptap/core";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import { FileAttachment, PdfAttachment } from "@edgeever/shared";
|
||||
import { ensureTestWindowDom } from "../../lib/restore-test-global.mjs";
|
||||
import { findAttachmentRange, removeAttachmentAt, renameAttachmentAt } from "./attachment-editor-range.ts";
|
||||
|
||||
const videoUrl = "edgeever-resource://resource/res_video";
|
||||
@@ -35,10 +36,13 @@ const pdfNode = (url, filename) => ({
|
||||
|
||||
const paragraph = (...content) => ({ type: "paragraph", content });
|
||||
|
||||
const makeEditor = (content) => new Editor({
|
||||
extensions: [StarterKit, FileAttachment, PdfAttachment],
|
||||
content: { type: "doc", content },
|
||||
});
|
||||
const makeEditor = (content) => {
|
||||
ensureTestWindowDom();
|
||||
return new Editor({
|
||||
extensions: [StarterKit, FileAttachment, PdfAttachment],
|
||||
content: { type: "doc", content },
|
||||
});
|
||||
};
|
||||
|
||||
describe("attachment editor range", () => {
|
||||
test("removes a video file-attachment node whose hover URL is the API blob path", () => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test";
|
||||
import { Editor } from "@tiptap/core";
|
||||
import { createEdgeEverDocumentExtensions } from "@edgeever/shared";
|
||||
import { createEdgeEverMathematics } from "@edgeever/shared/mathematics";
|
||||
import { ensureTestWindowDom } from "../../lib/restore-test-global.mjs";
|
||||
import {
|
||||
applyMathFormula,
|
||||
deleteMathFormula,
|
||||
@@ -9,12 +10,15 @@ import {
|
||||
selectedTextAsLatex,
|
||||
} from "./math-formula.ts";
|
||||
|
||||
const createEditor = (content) => new Editor({
|
||||
extensions: createEdgeEverDocumentExtensions({
|
||||
mathematics: createEdgeEverMathematics(),
|
||||
}),
|
||||
content,
|
||||
});
|
||||
const createEditor = (content) => {
|
||||
ensureTestWindowDom();
|
||||
return new Editor({
|
||||
extensions: createEdgeEverDocumentExtensions({
|
||||
mathematics: createEdgeEverMathematics(),
|
||||
}),
|
||||
content,
|
||||
});
|
||||
};
|
||||
|
||||
describe("math formula commands", () => {
|
||||
test("inserts inline math at the caret", () => {
|
||||
|
||||
@@ -20,9 +20,16 @@ describe("PDF document sources", () => {
|
||||
});
|
||||
|
||||
test("recovers leaked desktop resource URLs in the web runtime", async () => {
|
||||
await expect(loadPdfDocumentSource("edgeever-resource://resource/res_web", undefined)).resolves.toEqual({
|
||||
url: "/api/v1/resources/res_web/blob",
|
||||
});
|
||||
const current = globalThis.window;
|
||||
const previousBridge = current?.edgeeverDesktop;
|
||||
if (current) current.edgeeverDesktop = undefined;
|
||||
try {
|
||||
await expect(loadPdfDocumentSource("edgeever-resource://resource/res_web")).resolves.toEqual({
|
||||
url: "/api/v1/resources/res_web/blob",
|
||||
});
|
||||
} finally {
|
||||
if (current) current.edgeeverDesktop = previousBridge;
|
||||
}
|
||||
});
|
||||
|
||||
test("loads synced desktop resources through the native bridge", async () => {
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
const restoreUnconditionally = Symbol("restore-unconditionally");
|
||||
const noop = () => {};
|
||||
|
||||
// Linux Bun exposes `document` without a `window` binding. Test files then
|
||||
// install plain objects. ProseMirror and TipTap read `window.MutationObserver`
|
||||
// and `window.addEventListener` from that object, so a leftover stub needs
|
||||
// those methods. Do not create a window when none is installed: assigning one
|
||||
// is unnecessary on hosts whose editor already resolves `window` elsewhere.
|
||||
export const ensureTestWindowDom = () => {
|
||||
const current = globalThis.window;
|
||||
if (!current || typeof current !== "object") return;
|
||||
if (typeof current.addEventListener !== "function") current.addEventListener = noop;
|
||||
if (typeof current.removeEventListener !== "function") current.removeEventListener = noop;
|
||||
if (typeof current.getComputedStyle !== "function") current.getComputedStyle = () => ({ listStyle: "" });
|
||||
if (typeof current.setTimeout !== "function") current.setTimeout = globalThis.setTimeout.bind(globalThis);
|
||||
if (typeof current.clearTimeout !== "function") current.clearTimeout = globalThis.clearTimeout.bind(globalThis);
|
||||
};
|
||||
|
||||
export const restoreTestGlobal = (key, original, installed = restoreUnconditionally) => {
|
||||
if (installed !== restoreUnconditionally && globalThis[key] !== installed) return;
|
||||
@@ -6,10 +22,12 @@ export const restoreTestGlobal = (key, original, installed = restoreUnconditiona
|
||||
globalThis[key] = original;
|
||||
return;
|
||||
}
|
||||
// Linux Bun provides document without a window binding. Assigning
|
||||
// undefined shadows it, and deleting it makes ProseMirror throw
|
||||
// `window is not defined` while reading MutationObserver. Keep the
|
||||
// stub object when there was no previous window.
|
||||
if (key === "window") return;
|
||||
// Assigning undefined shadows the host binding, and deleting window makes
|
||||
// ProseMirror throw `window is not defined`. Keep the stub and make it
|
||||
// safe for a later editor test.
|
||||
if (key === "window") {
|
||||
ensureTestWindowDom();
|
||||
return;
|
||||
}
|
||||
delete globalThis[key];
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { restoreTestGlobal } from "./restore-test-global.mjs";
|
||||
import { ensureTestWindowDom, restoreTestGlobal } from "./restore-test-global.mjs";
|
||||
|
||||
test("restoreTestGlobal keeps a window object when nothing was there before", () => {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(globalThis, "window");
|
||||
@@ -8,6 +8,8 @@ test("restoreTestGlobal keeps a window object when nothing was there before", ()
|
||||
globalThis.window = stub;
|
||||
restoreTestGlobal("window", undefined, stub);
|
||||
expect(globalThis.window).toBe(stub);
|
||||
expect(typeof globalThis.window.addEventListener).toBe("function");
|
||||
expect(typeof globalThis.window.removeEventListener).toBe("function");
|
||||
if (descriptor) Object.defineProperty(globalThis, "window", descriptor);
|
||||
else delete globalThis.window;
|
||||
});
|
||||
@@ -23,3 +25,16 @@ test("restoreTestGlobal leaves a global that another file replaced", () => {
|
||||
if (descriptor) Object.defineProperty(globalThis, "document", descriptor);
|
||||
else delete globalThis.document;
|
||||
});
|
||||
|
||||
test("ensureTestWindowDom fills event methods on a leftover window", () => {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(globalThis, "window");
|
||||
const stub = { edgeeverDesktop: { isAvailable: true } };
|
||||
globalThis.window = stub;
|
||||
ensureTestWindowDom();
|
||||
expect(typeof stub.addEventListener).toBe("function");
|
||||
expect(typeof stub.getComputedStyle).toBe("function");
|
||||
expect(stub.edgeeverDesktop.isAvailable).toBe(true);
|
||||
ensureTestWindowDom();
|
||||
if (descriptor) Object.defineProperty(globalThis, "window", descriptor);
|
||||
else delete globalThis.window;
|
||||
});
|
||||
Reference in new issue
Block a user