返回 DeepSeek-Reasonix
capabilities-test-helpers.ts
根目录 / desktop / frontend / src / __tests__ / capabilities-test-helpers.ts
1 import { JSDOM } from "jsdom";
2 import { act } from "react";
3
4 export function flush(): Promise<void> {
5 return new Promise((resolve) => setTimeout(resolve, 0));
6 }
7
8 export async function waitFor(label: string, predicate: () => boolean) {
9 for (let attempt = 0; attempt < 20; attempt += 1) {
10 await act(async () => {
11 await flush();
12 });
13 if (predicate()) return;
14 }
15 throw new Error(`timed out waiting for ${label}`);
16 }
17
18 export function installDom() {
19 const dom = new JSDOM("<!doctype html><html><body><div id=\"root\"></div></body></html>", {
20 pretendToBeVisual: true,
21 url: "http://localhost/",
22 });
23 (globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
24 globalThis.window = dom.window as unknown as Window & typeof globalThis;
25 globalThis.document = dom.window.document;
26 Object.defineProperty(globalThis, "navigator", { configurable: true, value: dom.window.navigator });
27 globalThis.Node = dom.window.Node;
28 globalThis.HTMLElement = dom.window.HTMLElement;
29 globalThis.HTMLButtonElement = dom.window.HTMLButtonElement;
30 globalThis.HTMLInputElement = dom.window.HTMLInputElement;
31 globalThis.Event = dom.window.Event;
32 globalThis.KeyboardEvent = dom.window.KeyboardEvent;
33 globalThis.MouseEvent = dom.window.MouseEvent;
34 globalThis.localStorage = dom.window.localStorage;
35 globalThis.requestAnimationFrame = dom.window.requestAnimationFrame.bind(dom.window);
36 globalThis.cancelAnimationFrame = dom.window.cancelAnimationFrame.bind(dom.window);
37 Object.defineProperty(window, "matchMedia", {
38 configurable: true,
39 value: () => ({
40 matches: true,
41 media: "(prefers-reduced-motion: reduce)",
42 onchange: null,
43 addEventListener() {},
44 removeEventListener() {},
45 addListener() {},
46 removeListener() {},
47 dispatchEvent: () => false,
48 }),
49 });
50 return dom;
51 }
52
53 export function findButton(label: string): HTMLButtonElement | undefined {
54 return Array.from(document.querySelectorAll("button")).find((button) => button.textContent?.trim() === label) as HTMLButtonElement | undefined;
55 }
56
57 export function setInputValue(input: HTMLInputElement, value: string) {
58 const win = input.ownerDocument.defaultView;
59 const previous = input.value;
60 const setter = Object.getOwnPropertyDescriptor((win?.HTMLInputElement ?? HTMLInputElement).prototype, "value")?.set;
61 setter?.call(input, value);
62 (input as HTMLInputElement & { _valueTracker?: { setValue: (next: string) => void } })._valueTracker?.setValue(previous);
63 const eventCtor = win?.Event ?? Event;
64 input.dispatchEvent(new eventCtor("input", { bubbles: true }));
65 input.dispatchEvent(new eventCtor("change", { bubbles: true }));
66 }
67
67 lines TYPESCRIPT