























@@ -41,9 +41,69 @@ function createMatchMediaMock(width: number) {
4141};
4242});
4343}
44+45+const mountedApps = new Set<OpenClawApp>();
46+47+function collectMountedApps() {
48+return new Set<OpenClawApp>([
49+ ...mountedApps,
50+ ...document.querySelectorAll<OpenClawApp>("openclaw-app"),
51+]);
52+}
53+54+function nextMicrotask() {
55+return Promise.resolve();
56+}
57+58+function nextTimer() {
59+return new Promise<void>((resolve) => window.setTimeout(resolve, 0));
60+}
61+62+function nextFrame() {
63+return new Promise<void>((resolve) => {
64+if (typeof window.requestAnimationFrame !== "function") {
65+window.setTimeout(resolve, 0);
66+return;
67+}
68+window.requestAnimationFrame(() => resolve());
69+});
70+}
71+72+async function waitForAppUpdates(apps: Iterable<OpenClawApp>) {
73+for (const app of apps) {
74+await app.updateComplete;
75+}
76+}
77+78+async function drainAppWork(apps: Iterable<OpenClawApp>) {
79+const snapshot = [...apps];
80+await nextMicrotask();
81+await waitForAppUpdates(snapshot);
82+await nextFrame();
83+await nextMicrotask();
84+await nextFrame();
85+await nextMicrotask();
86+await waitForAppUpdates(snapshot);
87+await nextTimer();
88+await nextMicrotask();
89+await waitForAppUpdates(snapshot);
90+}
91+92+async function cleanupMountedApps() {
93+const apps = collectMountedApps();
94+await drainAppWork(apps);
95+for (const app of apps) {
96+app.remove();
97+}
98+document.body.replaceChildren();
99+mountedApps.clear();
100+await drainAppWork(apps);
101+}
102+44103export function mountApp(pathname: string) {
45104window.history.replaceState({}, "", pathname);
46105const app = document.createElement("openclaw-app") as OpenClawApp;
106+mountedApps.add(app);
47107document.body.append(app);
48108app.connected = true;
49109app.requestUpdate();
@@ -96,12 +156,14 @@ export function registerAppMountHooks() {
96156});
9715798158afterEach(async () => {
159+await cleanupMountedApps();
99160window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = undefined;
100161getSafeLocalStorage()?.clear();
101162getSafeSessionStorage()?.clear();
102-document.body.innerHTML = "";
103163await i18n.setLocale("en");
164+vi.restoreAllMocks();
104165vi.unstubAllGlobals();
105-await new Promise<void>((resolve) => setTimeout(resolve, 0));
166+await nextTimer();
167+await nextMicrotask();
106168});
107169}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。