返回 DeepSeek-Reasonix
maintenance-submit.mjs
根目录 / desktop / frontend / bench / maintenance-submit.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_MAINTENANCE_EVIDENCE ?? "/tmp/reasonix-maintenance-submit-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 let page;
15 try {
16 browser = await chromium.launch({ headless: true });
17 page = await browser.newPage({ viewport: { width: 1280, height: 900 } });
18 page.setDefaultTimeout(15000);
19 const errors = [];
20 page.on("pageerror", error => errors.push(error.message));
21 await page.goto(`http://127.0.0.1:${server.httpServer.address().port}/bench/maintenance-submit.html?mock=1`);
22 await page.waitForFunction(() => Boolean(window.maintenanceProbe));
23 const input = page.locator("textarea").first();
24 await page.evaluate(() => window.maintenanceProbe.holdAdmission());
25 await input.fill("/compact");
26 await input.press("Enter");
27 await page.locator(".composer-run-strip__state").filter({ hasText: "Preparing compaction" }).waitFor();
28 assert.equal(await page.locator(".composer-run-strip__metrics").count(), 0);
29 await input.fill("Next message draft");
30 assert.match(await page.locator(".composer-run-strip__state").innerText(), /Preparing compaction/);
31 await page.getByRole("button", { name: "Switch session" }).click();
32 assert.equal(await page.locator(".composer-run-strip__state").count(), 0);
33 await input.fill("Session B draft");
34 await page.getByRole("button", { name: "Switch session" }).click();
35 assert.equal(await input.inputValue(), "Next message draft");
36 assert.match(await page.locator(".composer-run-strip__state").innerText(), /Preparing compaction/);
37 await page.getByRole("button", { name: "Switch session" }).click();
38 await page.evaluate(() => window.maintenanceProbe.releaseAdmission());
39 await page.waitForFunction(() => window.maintenanceProbe.stats().starts === 1);
40 assert.equal(await page.locator(".composer-run-strip__state").count(), 0, "background admission must not change session B's submission state");
41 assert.equal(await input.inputValue(), "Session B draft");
42 await page.getByRole("button", { name: "Switch session" }).click();
43 assert.equal(await input.inputValue(), "Next message draft", "admission must preserve edits made while submitting");
44 await page.locator(".compaction__spinner").waitFor();
45 assert.match(await page.locator(".compaction--pending").innerText(), /Generating summary/);
46 assert.equal(await page.locator(".compaction--pending").getAttribute("role"), "status");
47 await page.locator(".composer-run-strip__state").filter({ hasText: "Compacting conversation" }).waitFor();
48 assert.equal(await page.locator(".composer-run-strip__metrics").count(), 0);
49 assert.equal(await page.locator(".compaction__spinner").evaluate(element => getComputedStyle(element).animationName), "spin");
50 await page.emulateMedia({ reducedMotion: "reduce" });
51 assert.equal(await page.locator(".compaction__spinner").evaluate(element => getComputedStyle(element).animationName), "none");
52 await page.emulateMedia({ reducedMotion: "no-preference" });
53 for (const command of ["/compact", "/compact keep decisions"]) {
54 await input.fill(command);
55 await input.press("Enter");
56 await page.waitForFunction(() => document.querySelector("textarea").value === "", null, { timeout: 15000 });
57 }
58 assert.deepEqual(await page.evaluate(() => window.maintenanceProbe.stats()), { starts: 1, submissions: 3 }, "known-running duplicate uses management admission rather than the follow-up queue");
59 assert.equal(await page.locator(".compaction").count(), 1);
60 assert.match(await page.locator("body").innerText(), /already in progress/);
61 assert.equal(await page.locator(".msg__send-failed").count(), 0);
62 // Exercise the production paste folding handler without touching the user's clipboard.
63 const focus = "preserve architecture decisions\n".repeat(100);
64 await input.fill("/compact ");
65 await input.evaluate((element, text) => {
66 const data = new DataTransfer(); data.setData("text/plain", text);
67 element.dispatchEvent(new ClipboardEvent("paste", { bubbles: true, cancelable: true, clipboardData: data }));
68 }, focus);
69 assert.match(await input.inputValue(), /Pasted/);
70 await input.press("Enter");
71 await page.waitForFunction(() => window.maintenanceProbe.stats().submissions === 4);
72 assert.deepEqual(await page.evaluate(() => window.maintenanceProbe.stats()), { starts: 1, submissions: 4 });
73 assert.ok((await page.evaluate(() => window.maintenanceProbe.lastInput())).includes(focus));
74 assert.equal(await page.locator(".msg__send-failed").count(), 0);
75 await mkdir(evidence, { recursive: true });
76 await page.screenshot({ path: path.join(evidence, "duplicate-compact.png") });
77 await page.getByRole("button", { name: "Switch session" }).click();
78 assert.equal(await page.locator("[data-active-session]").innerText(), "B");
79 await page.evaluate(() => window.maintenanceProbe.complete());
80 assert.equal(await page.locator(".compaction").count(), 0, "background completion cannot appear in another session");
81 await page.getByRole("button", { name: "Switch session" }).click();
82 await page.locator(".compaction button").click();
83 assert.match(await page.locator(".compaction").innerText(), /durable compaction summary/);
84 assert.deepEqual(await page.evaluate(() => window.maintenanceProbe.lifecycle()), { running: false, cancellable: false, echoes: 0 });
85 await page.evaluate(() => window.maintenanceProbe.coldRestore());
86 assert.equal(await page.locator(".compaction").count(), 1);
87 const disclosure = page.locator(".compaction button");
88 if (await disclosure.getAttribute("aria-expanded") === "false") await disclosure.click();
89 assert.match(await page.locator(".compaction").innerText(), /durable compaction summary/);
90 await page.screenshot({ path: path.join(evidence, "restored-summary.png") });
91 await page.evaluate(() => window.maintenanceProbe.holdAdmission());
92 await input.fill("/compact");
93 await input.press("Enter");
94 await page.locator(".composer-run-strip__state").filter({ hasText: "Preparing compaction" }).waitFor();
95 await input.fill("Keep this draft after failure");
96 await page.evaluate(() => window.maintenanceProbe.rejectAdmission());
97 await page.locator(".composer-run-strip__state").waitFor({ state: "detached" });
98 assert.equal(await input.inputValue(), "Keep this draft after failure");
99 await page.evaluate(() => window.maintenanceProbe.holdAdmission());
100 await input.fill("Ordinary request");
101 await input.press("Enter");
102 await page.waitForFunction(() => window.maintenanceProbe.stats().submissions === 6);
103 await input.fill("/compact");
104 assert.equal(await page.locator(".composer-run-strip__state").count(), 0, "editing a normal submission into /compact cannot relabel the in-flight request");
105 await page.evaluate(() => window.maintenanceProbe.rejectAdmission());
106 await page.getByRole("button", { name: "Send (Enter)", exact: true }).waitFor();
107 assert.deepEqual(errors, []);
108 console.log(`PASS submission edits, session isolation, admission failure, duplicate compaction and durable summary restore; evidence: ${evidence}`);
109 } catch (error) {
110 await mkdir(evidence, { recursive: true });
111 await page?.screenshot({ path: path.join(evidence, "failure.png") });
112 console.error(await page?.evaluate(() => ({ stats: window.maintenanceProbe?.stats(), text: document.body.innerText.slice(-2500) })));
113 throw error;
114 } finally {
115 await browser?.close();
116 await server.close();
117 }
118
118 lines Plain Text