mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 02:26:12 +02:00
test: unload chat client before restarting its server
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
639cb48562
commit
1fe2fe2751
5 files changed
+44
-2
No files matched your search
@@ -176,6 +176,9 @@ fails the case instead of silently testing another phase.
|
||||
Restart continuity requires the agent to recall a phrase after the server
|
||||
restarts. The final prompt does not reveal that phrase. A generic successful
|
||||
reply after restart cannot pass this check.
|
||||
The browser leaves the old development client before the server stops, then
|
||||
opens the canonical chat route and waits for the composer. This avoids racing
|
||||
Vite's automatic reconnect navigation against the test's explicit navigation.
|
||||
|
||||
The blocker query requests a JSON status snapshot. It must name the current
|
||||
recorded blocker and report zero active runs independently of the task's blocked
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { createServer } from "node:http";
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { restartChatServer } from "./chat-restart.js";
|
||||
|
||||
test("unloads the old browser client before server restart and opens the new document", async ({ page }) => {
|
||||
let generation = 1;
|
||||
const server = createServer((_req, res) => {
|
||||
res.writeHead(200, { "content-type": "text/html" });
|
||||
res.end(`<input data-testid="composer" value="server generation ${generation}"><script>setInterval(() => fetch('/probe').catch(() => {}), 50)</script>`);
|
||||
});
|
||||
await new Promise<void>(resolve => server.listen(0, "127.0.0.1", resolve));
|
||||
const address = server.address();
|
||||
if (!address || typeof address === "string") throw new Error("Missing listener");
|
||||
const url = `http://127.0.0.1:${address.port}`;
|
||||
try {
|
||||
await page.goto(url);
|
||||
await expect(page.getByTestId("composer")).toHaveValue("server generation 1");
|
||||
await restartChatServer(page, async () => {
|
||||
expect(page.url(), "The old client must be gone before it can auto-reload").toBe("about:blank");
|
||||
server.closeAllConnections();
|
||||
await new Promise<void>((resolve, reject) => server.close(error => error ? reject(error) : resolve()));
|
||||
generation += 1;
|
||||
await new Promise<void>(resolve => server.listen(address.port, "127.0.0.1", resolve));
|
||||
});
|
||||
await page.goto(url, { waitUntil: "commit" });
|
||||
await expect(page.getByTestId("composer")).toHaveValue("server generation 2");
|
||||
} finally {
|
||||
server.closeAllConnections();
|
||||
await new Promise<void>((resolve, reject) => server.close(error => error ? reject(error) : resolve()));
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
|
||||
/** Restart the test server without letting the old Vite client race navigation. */
|
||||
export async function restartChatServer(page: Page, restart: () => Promise<void>) {
|
||||
await page.goto("about:blank", { waitUntil: "commit", timeout: 30_000 });
|
||||
await restart();
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { defineConfig } from "@playwright/test";
|
||||
/** Browser-only harness regressions: no Paperclip instance or provider credentials. */
|
||||
export default defineConfig({
|
||||
testDir: ".",
|
||||
testMatch: ["screenshot-readiness.spec.ts", "lost-send.spec.ts"],
|
||||
testMatch: ["screenshot-readiness.spec.ts", "lost-send.spec.ts", "chat-restart.spec.ts"],
|
||||
workers: 1,
|
||||
retries: 0,
|
||||
timeout: 10_000,
|
||||
|
||||
@@ -4,6 +4,7 @@ import { createTaskThroughUi, submitTaskReply } from "./user-actions.js";
|
||||
|
||||
import { runFirstTaskFlow, setupFirstTaskFixtures } from "./first-task-flow.js";
|
||||
import { runChatFlow } from "./chat-flow.js";
|
||||
import { restartChatServer } from "./chat-restart.js";
|
||||
import { createHash, randomBytes } from "node:crypto";
|
||||
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
@@ -832,7 +833,7 @@ for (const execution of executions) {
|
||||
} else if (execution.task.flow === "agent_chat") {
|
||||
const chat = await runChatFlow({
|
||||
page, api, fixtures, execution, nonce, workspacePath,
|
||||
restart: () => restartIsolatedPaperclipServer({ api, requestId: `chat-${nonce}`, deadlineAt: startedAtMs + deadlineMs }),
|
||||
restart: () => restartChatServer(page, () => restartIsolatedPaperclipServer({ api, requestId: `chat-${nonce}`, deadlineAt: startedAtMs + deadlineMs })),
|
||||
observe: (chatIssue, chatRuns) => { issue = chatIssue; selectedRuns = chatRuns; },
|
||||
capture: captureScreenshot,
|
||||
evidence: (name, data) => writeSanitizedJson(snapshotsDir, name, data, secrets),
|
||||
|
||||
Reference in new issue
Block a user