返回 DeepSeek-Reasonix
session-loading.mjs
根目录 / desktop / frontend / bench / session-loading.mjs
1 import assert from "node:assert/strict";
2 import { mkdir } from "node:fs/promises";
3 import path from "node:path";
4 import { fileURLToPath } from "node:url";
5 import { createServer } from "vite";
6
7 const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
8 process.env.PLAYWRIGHT_BROWSERS_PATH ??= path.join(root, ".pw-browsers");
9 const { chromium } = await import("playwright");
10 const evidence = process.env.REASONIX_LOADING_EVIDENCE ?? "/tmp/reasonix-session-loading-evidence";
11 const server = await createServer({ root, logLevel: "error", server: { host: "127.0.0.1", port: 0 } });
12 await server.listen();
13 let browser;
14 try {
15 browser = await chromium.launch({ headless: true });
16 const page = await browser.newPage({ viewport: { width: 1280, height: 800 }, reducedMotion: "reduce" });
17 const errors = [];
18 page.on("pageerror", error => errors.push(error.message));
19 const address = server.httpServer.address();
20 await page.goto(`http://127.0.0.1:${address.port}/bench/session-loading.html`);
21 await page.waitForFunction(() => typeof window.paintLoading === "function");
22 await page.clock.install();
23 await page.clock.pauseAt(new Date(Date.now() + 1000));
24 const paint = input => page.evaluate(input => window.paintLoading(input), input);
25 const feedback = page.locator(".session-loading-indicator");
26 const userNode = page.locator('.chat-node[data-chat-kind="user"]');
27 await mkdir(evidence, { recursive: true });
28 for (const surface of ["local", "remote", "transcript"]) {
29 const input = { surface, identity: `${surface}-A`, phase: "loading" };
30 await paint(input);
31 await page.clock.runFor(249);
32 assert.equal(await feedback.count(), 0, `${surface}: no loading UI for fast requests`);
33 assert.equal(await page.locator(".session-recovery,.session-recovery-placeholder").count(), 0);
34 await page.clock.runFor(1);
35 assert.equal(await feedback.count(), 1, `${surface}: one delayed indicator`);
36 const mainBefore = await page.locator(surface === "transcript" ? ".chat-transcript" : ".main").boundingBox();
37 const shortText = await feedback.innerText();
38 await page.clock.runFor(1750);
39 assert.notEqual(await feedback.innerText(), shortText);
40 assert.deepEqual(await page.locator(surface === "transcript" ? ".chat-transcript" : ".main").boundingBox(), mainBefore,
41 "loading detail does not change the pane geometry");
42 assert.equal(await feedback.evaluate(el => getComputedStyle(el).position), "absolute");
43 assert.equal(await feedback.locator("svg").evaluate(el => getComputedStyle(el).animationName), "none", "respects reduced motion");
44 await page.screenshot({ path: path.join(evidence, `${surface}-slow.png`) });
45
46 await paint({ ...input, phase: "ready" });
47 await page.clock.runFor(32);
48 assert.equal(await feedback.count(), 0);
49 assert.match(await userNode.innerText(), new RegExp(`Content ${input.identity}`));
50 const nodeBefore = await userNode.boundingBox();
51 await userNode.evaluate(el => { window.retainedLoadingNode = el; });
52 await paint({ ...input, cached: true });
53 await page.clock.runFor(2000);
54 assert.equal(await userNode.evaluate(el => el === window.retainedLoadingNode), true);
55 assert.deepEqual(await userNode.boundingBox(), nodeBefore, "cached content never shifts for loading feedback");
56 assert.equal(await feedback.count(), 1);
57 await page.screenshot({ path: path.join(evidence, `${surface}-cached.png`) });
58
59 await paint({ ...input, identity: `${surface}-B` });
60 assert.equal(await feedback.count(), 0, "switching hides the previous session's pending indicator");
61 assert.equal(await page.locator(".chat-node").count(), 0, "the previous session never appears under a new identity");
62 await page.clock.runFor(100);
63 await paint({ ...input, identity: `${surface}-B`, phase: "ready" });
64 await page.clock.runFor(2500);
65 assert.equal(await feedback.count(), 0, "old deadlines cannot appear after completion");
66 if (surface !== "transcript") {
67 await paint({ ...input, phase: "error" });
68 assert.equal(await page.locator('.session-recovery[role="alert"]').count(), 1);
69 assert.equal(await feedback.count(), 0);
70 }
71 console.log(`PASS ${surface}: delayed feedback, immediate readiness, stable cached layout, session isolation and recovery`);
72 }
73 assert.deepEqual(errors, []);
74 console.log(`Browser evidence: ${evidence}`);
75 } finally {
76 await browser?.close();
77 await server.close();
78 }
79
79 lines Plain Text