Skip to content

Commit 58e1dfe

Browse files
voidstackloopclaude
andcommitted
e2e: raise CI timeouts for the agent tool-approval tests and add failure traces
CI failed both agent-tool-approval tests on their Allow/Deny wait after exactly 15s (the assertion timeout), with total run time close to that figure rather than the full 60s per-test budget — consistent with a slower/shared CI runner running past a locally-comfortable margin, not a hang or a real bug (the other six tests, none of which chain an agent- workspace pick + detectScripts + a full chat round trip, passed fine). - expect() timeout is now CI-aware (20s vs. 10s locally) in the config. - The two Allow/Deny waits specifically go to 30s, with the per-test timeout for this file raised to 90s to leave room around them. - trace: retain-on-failure and screenshot: only-on-failure are now on, so a future failure comes with a trace/screenshot instead of just a log. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 5097e09 commit 58e1dfe

2 files changed

Lines changed: 35 additions & 7 deletions

File tree

e2e/playwright.config.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,19 @@ export default defineConfig({
1818
fullyParallel: false,
1919
retries: process.env.CI ? 1 : 0,
2020
timeout: 60_000,
21-
expect: { timeout: 10_000 },
21+
// CI runners (shared, no GPU, xvfb overhead on top of Electron's own
22+
// startup cost) are measurably slower than a local dev machine — a wait
23+
// that's comfortably generous locally can still time out there. Give CI
24+
// more headroom uniformly rather than chasing each timeout one at a time.
25+
expect: { timeout: process.env.CI ? 20_000 : 10_000 },
2226
reporter: process.env.CI ? [["list"], ["html", { open: "never" }]] : "list",
27+
use: {
28+
// Only kept for a run that actually failed — cheap on disk, and the
29+
// difference between "it broke somewhere" and "here's exactly what
30+
// the page looked like and every action leading up to it."
31+
trace: "retain-on-failure",
32+
screenshot: "only-on-failure",
33+
},
2334
webServer: {
2435
command: "npx vite preview --port 5173 --strictPort",
2536
cwd: path.resolve(__dirname, "../frontend"),

e2e/tests/agent-tool-approval.spec.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ import { startFakeOllama, type FakeOllamaServer } from "../fixtures/fake-ollama"
1212
// through the real IPC bridge and a real (sandboxed, harmless) command
1313
// execution on Allow, not a mocked approval handler.
1414

15+
// The Allow/Deny wait below alone can take 30s on a slow CI runner; the
16+
// config's default 60s per-test budget leaves too little room for the setup
17+
// and follow-up assertions around it.
18+
test.setTimeout(90_000);
19+
1520
let fakeOllama: FakeOllamaServer;
1621
let instance: LaunchedApp;
1722
let workspaceDir: string;
@@ -48,7 +53,7 @@ async function enableAgentModeAndSendToolCallingMessage(instance_: LaunchedApp):
4853
const input = window.getByPlaceholder("Send a message...");
4954
await input.fill("run a command for me");
5055
const sendButton = window.getByRole("button", { name: "Send message" });
51-
await expect(sendButton).toBeEnabled({ timeout: 15_000 });
56+
await expect(sendButton).toBeEnabled({ timeout: 20_000 });
5257
await sendButton.click();
5358
}
5459

@@ -59,13 +64,19 @@ test("Deny stops the tool from running and the card clears", async () => {
5964
// "run_command" appears twice once the card is up (the tool-call summary
6065
// line and the pending-call header) — anchor on the Allow/Deny buttons
6166
// themselves, which is what actually defines "the approval card showed".
62-
await expect(window.getByRole("button", { name: "Allow" })).toBeVisible({ timeout: 15_000 });
67+
// Generous on top of the config's own CI-aware expect timeout: this
68+
// specific wait spans agent-workspace setup (a real IPC round trip plus
69+
// agentTools.detectProjectScripts()) and a full chat request/response
70+
// round trip through the fake Ollama server — the longest chain of
71+
// async work in this suite, and the one most exposed to a slower/shared
72+
// CI runner.
73+
await expect(window.getByRole("button", { name: "Allow" })).toBeVisible({ timeout: 30_000 });
6374
await window.getByRole("button", { name: "Deny" }).click();
6475

6576
await expect(window.getByRole("button", { name: "Deny" })).toBeHidden();
6677
// The agent loop still completes (with the model told it was denied) —
6778
// the whole turn doesn't hang after a denial.
68-
await expect(window.getByText("Hello from the fake model.")).toBeVisible({ timeout: 15_000 });
79+
await expect(window.getByText("Hello from the fake model.")).toBeVisible({ timeout: 20_000 });
6980

7081
// Nothing the denied command would have produced actually happened.
7182
expect(fs.readdirSync(workspaceDir)).toEqual([]);
@@ -75,12 +86,18 @@ test("Allow runs the tool for real and the card clears", async () => {
7586
const { window } = instance;
7687
await enableAgentModeAndSendToolCallingMessage(instance);
7788

78-
await expect(window.getByRole("button", { name: "Allow" })).toBeVisible({ timeout: 15_000 });
89+
// Generous on top of the config's own CI-aware expect timeout: this
90+
// specific wait spans agent-workspace setup (a real IPC round trip plus
91+
// agentTools.detectProjectScripts()) and a full chat request/response
92+
// round trip through the fake Ollama server — the longest chain of
93+
// async work in this suite, and the one most exposed to a slower/shared
94+
// CI runner.
95+
await expect(window.getByRole("button", { name: "Allow" })).toBeVisible({ timeout: 30_000 });
7996
await window.getByRole("button", { name: "Allow" }).click();
8097

8198
await expect(window.getByRole("button", { name: "Allow" })).toBeHidden();
8299
// The tool result card (not the earlier pending-call summary line, which
83100
// also still mentions the command) — proof the command actually ran.
84-
await expect(window.locator("pre", { hasText: "hello-from-agent" })).toBeVisible({ timeout: 15_000 });
85-
await expect(window.getByText("Hello from the fake model.")).toBeVisible({ timeout: 15_000 });
101+
await expect(window.locator("pre", { hasText: "hello-from-agent" })).toBeVisible({ timeout: 20_000 });
102+
await expect(window.getByText("Hello from the fake model.")).toBeVisible({ timeout: 20_000 });
86103
});

0 commit comments

Comments
 (0)