避免全量父页清掉老版内层深链仍依赖的 embed.session;深链问答/会商/大屏绘制由 isHostNestedSurfacePath 控制 chrome,并抽取对话历史 Tab 共享行组件。 Co-authored-by: Cursor <cursoragent@cursor.com>
198 lines
5.2 KiB
TypeScript
198 lines
5.2 KiB
TypeScript
/**
|
|
* embed-session.ts 浏览上下文隔离单测。
|
|
* npx esbuild src/core/embed/embed-session.test.ts --bundle --format=esm \
|
|
* --platform=node --outfile=.tmp-tests/embed-session.test.mjs
|
|
* node --test .tmp-tests/embed-session.test.mjs
|
|
*/
|
|
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
isChromeHidden,
|
|
isEmbedActive,
|
|
isIsolatedSession,
|
|
readEmbedSession,
|
|
syncEmbedSessionFromSearch,
|
|
} from "./embed-session";
|
|
|
|
class MemoryStorage {
|
|
#map = new Map<string, string>();
|
|
getItem(key: string): string | null {
|
|
return this.#map.has(key) ? this.#map.get(key)! : null;
|
|
}
|
|
setItem(key: string, value: string): void {
|
|
this.#map.set(key, String(value));
|
|
}
|
|
removeItem(key: string): void {
|
|
this.#map.delete(key);
|
|
}
|
|
}
|
|
|
|
type FakeWindow = {
|
|
self: FakeWindow;
|
|
top: FakeWindow;
|
|
sessionStorage: MemoryStorage;
|
|
location: { hash: string; search: string };
|
|
__deerflowTopChromeEmbed?: boolean;
|
|
};
|
|
|
|
const originalWindow = (globalThis as { window?: unknown }).window;
|
|
|
|
function withSharedTab<T>(run: (ctx: {
|
|
storage: MemoryStorage;
|
|
asTop: () => void;
|
|
asIframe: () => void;
|
|
}) => T): T {
|
|
const storage = new MemoryStorage();
|
|
const top = {
|
|
sessionStorage: storage,
|
|
location: { hash: "", search: "" },
|
|
} as FakeWindow;
|
|
top.self = top;
|
|
top.top = top;
|
|
const iframe = {
|
|
sessionStorage: storage,
|
|
location: { hash: "#/login/guest?embed=1&theme=blue&hideJump=0", search: "" },
|
|
} as FakeWindow;
|
|
iframe.self = iframe;
|
|
iframe.top = top;
|
|
|
|
const asTop = () => {
|
|
(globalThis as { window: FakeWindow }).window = top;
|
|
};
|
|
const asIframe = () => {
|
|
(globalThis as { window: FakeWindow }).window = iframe;
|
|
};
|
|
|
|
asTop();
|
|
try {
|
|
return run({ storage, asTop, asIframe });
|
|
} finally {
|
|
if (originalWindow === undefined) {
|
|
delete (globalThis as { window?: unknown }).window;
|
|
} else {
|
|
(globalThis as { window: unknown }).window = originalWindow;
|
|
}
|
|
}
|
|
}
|
|
|
|
test("nested embed=1 does not hide chrome on the same-origin top window", () => {
|
|
withSharedTab(({ storage, asTop, asIframe }) => {
|
|
asTop();
|
|
syncEmbedSessionFromSearch("");
|
|
assert.equal(isEmbedActive(), false);
|
|
|
|
asIframe();
|
|
syncEmbedSessionFromSearch("?embed=1&theme=blue&hideJump=0");
|
|
assert.equal(isEmbedActive(), true);
|
|
assert.ok(storage.getItem("embed.session.nested"));
|
|
|
|
asTop();
|
|
assert.equal(isEmbedActive(), false);
|
|
assert.equal(isChromeHidden(), false);
|
|
});
|
|
});
|
|
|
|
test("top ignores old nested embed.session without clearing it", () => {
|
|
withSharedTab(({ storage, asTop }) => {
|
|
asTop();
|
|
storage.setItem(
|
|
"embed.session",
|
|
JSON.stringify({
|
|
embed: true,
|
|
theme: "light",
|
|
hideJump: false,
|
|
hideHeader: false,
|
|
hideChrome: false,
|
|
isolate: false,
|
|
}),
|
|
);
|
|
assert.equal(isEmbedActive(), false);
|
|
assert.equal(isChromeHidden(), false);
|
|
// 内层老版仍要读到 embed=true
|
|
assert.equal(JSON.parse(storage.getItem("embed.session") || "{}").embed, true);
|
|
});
|
|
});
|
|
|
|
test("top sync does not wipe unowned embed.session", () => {
|
|
withSharedTab(({ storage, asTop }) => {
|
|
asTop();
|
|
storage.setItem(
|
|
"embed.session",
|
|
JSON.stringify({
|
|
embed: true,
|
|
theme: "light",
|
|
hideJump: false,
|
|
hideHeader: false,
|
|
hideChrome: false,
|
|
isolate: false,
|
|
}),
|
|
);
|
|
syncEmbedSessionFromSearch("");
|
|
assert.equal(isEmbedActive(), false);
|
|
assert.equal(JSON.parse(storage.getItem("embed.session") || "{}").embed, true);
|
|
});
|
|
});
|
|
|
|
test("nested iframe leaves the shared embed.session for old inner pages", () => {
|
|
withSharedTab(({ storage, asTop, asIframe }) => {
|
|
asTop();
|
|
storage.setItem(
|
|
"embed.session",
|
|
JSON.stringify({
|
|
embed: true,
|
|
theme: "light",
|
|
hideJump: false,
|
|
hideHeader: false,
|
|
hideChrome: false,
|
|
isolate: false,
|
|
}),
|
|
);
|
|
|
|
asIframe();
|
|
syncEmbedSessionFromSearch("?embed=1");
|
|
assert.equal(JSON.parse(storage.getItem("embed.session") || "{}").embed, true);
|
|
assert.ok(storage.getItem("embed.session.nested"));
|
|
|
|
asTop();
|
|
assert.equal(isEmbedActive(), false);
|
|
});
|
|
});
|
|
|
|
test("nested iframe keeps the top window's own embed session", () => {
|
|
withSharedTab(({ asTop, asIframe }) => {
|
|
asTop();
|
|
syncEmbedSessionFromSearch("?embed=1&theme=dark");
|
|
syncEmbedSessionFromSearch("");
|
|
assert.equal(isEmbedActive(), true);
|
|
assert.equal(readEmbedSession()?.topOwned, true);
|
|
|
|
asIframe();
|
|
syncEmbedSessionFromSearch("?embed=1");
|
|
|
|
asTop();
|
|
assert.equal(isEmbedActive(), true);
|
|
assert.equal(readEmbedSession()?.theme, "dark");
|
|
});
|
|
});
|
|
|
|
test("top ignore strips chrome in memory but keeps isolate", () => {
|
|
withSharedTab(({ storage, asTop }) => {
|
|
asTop();
|
|
storage.setItem(
|
|
"embed.session",
|
|
JSON.stringify({
|
|
embed: true,
|
|
theme: "light",
|
|
hideJump: false,
|
|
hideHeader: false,
|
|
hideChrome: false,
|
|
isolate: true,
|
|
}),
|
|
);
|
|
assert.equal(isEmbedActive(), false);
|
|
assert.equal(isIsolatedSession(), true);
|
|
assert.equal(JSON.parse(storage.getItem("embed.session") || "{}").embed, true);
|
|
});
|
|
});
|