返回 DeepSeek-Reasonix
remoteSurfaceDom.ts
根目录 / desktop / frontend / src / __tests__ / helpers / remoteSurfaceDom.ts
1 import { JSDOM } from "jsdom";
2
3 // installRemoteSurfaceDom publishes a jsdom window as the process globals the
4 // remote surface suite renders against. The transcript measures through the
5 // element prototype and calls the global rAF, which jsdom exposes only on a
6 // visual window, so both are stubbed here rather than per test.
7 export function installRemoteSurfaceDom(): JSDOM {
8 const dom = new JSDOM("<!doctype html><html><body><div id=\"root\"></div></body></html>", {
9 pretendToBeVisual: true,
10 url: "http://localhost/",
11 });
12 (globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
13 globalThis.window = dom.window as unknown as Window & typeof globalThis;
14 globalThis.document = dom.window.document;
15 Object.defineProperty(globalThis, "navigator", { configurable: true, value: dom.window.navigator });
16 globalThis.Node = dom.window.Node;
17 globalThis.Element = dom.window.Element;
18 globalThis.HTMLElement = dom.window.HTMLElement;
19 globalThis.Event = dom.window.Event;
20 globalThis.KeyboardEvent = dom.window.KeyboardEvent;
21 globalThis.localStorage = dom.window.localStorage;
22 globalThis.getComputedStyle = dom.window.getComputedStyle.bind(dom.window) as typeof getComputedStyle;
23 const elementProto = dom.window.HTMLElement.prototype;
24 Object.defineProperty(elementProto, "attachEvent", { configurable: true, value: () => {} });
25 Object.defineProperty(elementProto, "offsetHeight", {
26 configurable: true,
27 get(this: HTMLElement) { return this.classList.contains("transcript") ? 800 : 40; },
28 });
29 Object.defineProperty(elementProto, "offsetWidth", { configurable: true, get: () => 800 });
30 Object.defineProperty(elementProto, "clientHeight", {
31 configurable: true,
32 get(this: HTMLElement) { return this.classList.contains("transcript") ? 800 : 40; },
33 });
34 Object.defineProperty(elementProto, "clientWidth", { configurable: true, get: () => 800 });
35 (elementProto as unknown as { scrollTo: (arg?: number | ScrollToOptions) => void }).scrollTo = function (
36 this: HTMLElement,
37 arg?: number | ScrollToOptions,
38 ) {
39 this.scrollTop = typeof arg === "number" ? arg : arg?.top ?? this.scrollTop;
40 };
41 globalThis.requestAnimationFrame = dom.window.requestAnimationFrame?.bind(dom.window) ?? ((cb: FrameRequestCallback) => setTimeout(() => cb(Date.now()), 16) as unknown as number);
42 globalThis.cancelAnimationFrame = dom.window.cancelAnimationFrame?.bind(dom.window) ?? ((handle: number) => clearTimeout(handle));
43 Object.defineProperty(elementProto, "detachEvent", { configurable: true, value: () => {} });
44 return dom;
45 }
46
46 lines TYPESCRIPT