Skip to content

Commit c8771de

Browse files
committed
Revert "test: harden local startup and self-heal coverage"
This reverts commit 27fd21b.
1 parent 27fd21b commit c8771de

4 files changed

Lines changed: 14 additions & 116 deletions

File tree

packages/core/lib/v3/understudy/cdp.ts

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -116,41 +116,13 @@ export class CdpConnection implements CDPSessionLike {
116116

117117
static async connect(
118118
wsUrl: string,
119-
options?: { headers?: Record<string, string>; retryForMs?: number },
120-
): Promise<CdpConnection> {
121-
const deadlineMs = options?.retryForMs
122-
? Date.now() + options.retryForMs
123-
: undefined;
124-
let lastError: unknown;
125-
126-
do {
127-
try {
128-
return await CdpConnection.connectOnce(wsUrl, options?.headers);
129-
} catch (error) {
130-
lastError = error;
131-
if (
132-
!deadlineMs ||
133-
Date.now() >= deadlineMs ||
134-
!isTransientConnectError(error)
135-
) {
136-
throw error;
137-
}
138-
await new Promise((resolve) => setTimeout(resolve, 100));
139-
}
140-
} while (deadlineMs && Date.now() < deadlineMs);
141-
142-
throw lastError;
143-
}
144-
145-
private static async connectOnce(
146-
wsUrl: string,
147-
userHeaders?: Record<string, string>,
119+
options?: { headers?: Record<string, string> },
148120
): Promise<CdpConnection> {
149121
// Include User-Agent header for server-side observability and version tracking
150122
// Merge user-provided headers, letting them override defaults
151123
const headers = {
152124
"User-Agent": `Stagehand/${STAGEHAND_VERSION}`,
153-
...userHeaders,
125+
...options?.headers,
154126
};
155127
const ws = new WebSocket(wsUrl, { headers });
156128
await new Promise<void>((resolve, reject) => {
@@ -538,16 +510,6 @@ export class CdpConnection implements CDPSessionLike {
538510
}
539511
}
540512

541-
function isTransientConnectError(error: unknown): boolean {
542-
const err = error as NodeJS.ErrnoException | undefined;
543-
return (
544-
err?.code === "ECONNREFUSED" ||
545-
err?.code === "ECONNRESET" ||
546-
err?.message?.includes("ECONNREFUSED") === true ||
547-
err?.message?.includes("ECONNRESET") === true
548-
);
549-
}
550-
551513
export class CdpSession implements CDPSessionLike {
552514
constructor(
553515
private readonly root: CdpConnection,

packages/core/lib/v3/understudy/context.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ export class V3Context {
166166
const connectTask = async () => {
167167
const conn = await CdpConnection.connect(wsUrl, {
168168
headers: opts?.cdpHeaders,
169-
retryForMs: opts?.env === "LOCAL" ? 3_000 : undefined,
170169
});
171170
const ctx = new V3Context(
172171
conn,

packages/core/tests/integration/agent-cache-self-heal.spec.ts

Lines changed: 10 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,12 @@ import { test, expect } from "@playwright/test";
22
import fs from "fs/promises";
33
import path from "path";
44
import { V3 } from "../../lib/v3/v3.js";
5-
import { getV3TestConfig } from "./v3.config.js";
5+
import { v3TestConfig } from "./v3.config.js";
66
import type {
77
AgentReplayActStep,
88
AgentReplayFillFormStep,
99
CachedAgentEntry,
1010
} from "../../lib/v3/types/private/cache.js";
11-
import {
12-
createScriptedAisdkTestLlmClient,
13-
doneToolResponse,
14-
findElementRefForText,
15-
toolCallResponse,
16-
} from "./testUtils.js";
17-
18-
function encodeHtml(html: string): string {
19-
return `data:text/html,${encodeURIComponent(html)}`;
20-
}
21-
22-
function createSelfHealLlmClient() {
23-
return createScriptedAisdkTestLlmClient({
24-
jsonResponses: {
25-
act: [
26-
(options) => ({
27-
action: {
28-
target: findElementRefForText(options, "Launch self-heal"),
29-
description: "launch self-heal button",
30-
method: "click",
31-
button: null,
32-
},
33-
twoStep: false,
34-
}),
35-
(options) => ({
36-
action: {
37-
target: findElementRefForText(options, "Launch self-heal"),
38-
description: "launch self-heal button",
39-
method: "click",
40-
button: null,
41-
},
42-
twoStep: false,
43-
}),
44-
],
45-
},
46-
generateResponses: [
47-
toolCallResponse("act", { action: "click the button" }),
48-
doneToolResponse("Clicked the button successfully.", true),
49-
],
50-
});
51-
}
5211

5312
test.describe("Agent cache self-heal (e2e)", () => {
5413
let v3: V3;
@@ -59,10 +18,7 @@ test.describe("Agent cache self-heal (e2e)", () => {
5918
await fs.mkdir(testInfo.outputDir, { recursive: true });
6019
cacheDir = await fs.mkdtemp(path.join(testInfo.outputDir, "agent-cache-"));
6120
v3 = new V3({
62-
...getV3TestConfig({
63-
experimental: true,
64-
llmClient: createSelfHealLlmClient(),
65-
}),
21+
...v3TestConfig,
6622
cacheDir,
6723
selfHeal: true,
6824
});
@@ -74,32 +30,19 @@ test.describe("Agent cache self-heal (e2e)", () => {
7430
});
7531

7632
test("replays heal corrupted selectors", async () => {
77-
test.setTimeout(60_000);
33+
test.setTimeout(120_000);
7834

79-
const agent = v3.agent();
35+
const agent = v3.agent({
36+
model: "anthropic/claude-haiku-4-5-20251001",
37+
});
8038
const page = v3.context.pages()[0];
81-
const url = encodeHtml(`
82-
<!doctype html>
83-
<html>
84-
<body>
85-
<button
86-
id="launch"
87-
onclick="document.getElementById('status').textContent = 'clicked';"
88-
>
89-
Launch self-heal
90-
</button>
91-
<div id="status">idle</div>
92-
</body>
93-
</html>
94-
`);
39+
const url =
40+
"https://browserbase.github.io/stagehand-eval-sites/sites/shadow-dom/";
9541
const instruction = "click the button";
9642

97-
await page.goto(url, { waitUntil: "load" });
43+
await page.goto(url, { waitUntil: "networkidle" });
9844
const firstResult = await agent.execute({ instruction, maxSteps: 20 });
9945
expect(firstResult.success).toBe(true);
100-
await expect
101-
.poll(async () => page.evaluate(() => document.body.textContent ?? ""))
102-
.toContain("clicked");
10346

10447
const cachePath = await locateAgentCacheFile(cacheDir);
10548
const originalEntry = await readCacheEntry(cachePath);
@@ -119,13 +62,9 @@ test.describe("Agent cache self-heal (e2e)", () => {
11962
);
12063

12164
// Second run should replay from cache, self-heal, and update the file.
122-
await page.goto(url, { waitUntil: "load" });
65+
await page.goto(url, { waitUntil: "networkidle" });
12366
const replayResult = await agent.execute({ instruction, maxSteps: 20 });
12467
expect(replayResult.success).toBe(true);
125-
expect(replayResult.metadata?.cacheHit).toBe(true);
126-
await expect
127-
.poll(async () => page.evaluate(() => document.body.textContent ?? ""))
128-
.toContain("clicked");
12968

13069
const healedEntry = await readCacheEntry(cachePath);
13170
const healedActionStep = findFirstActionStep(healedEntry);

packages/core/tests/integration/multi-instance-logger.spec.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,8 @@ test.describe("V3 Multi-Instance Logger Isolation", () => {
147147
);
148148

149149
try {
150-
// This test is about shared global logger behavior, not concurrent
151-
// startup. Initialize sequentially to avoid local Chromium flake.
152-
await v3Instance1.init();
153-
await v3Instance2.init();
150+
// Initialize both instances concurrently
151+
await Promise.all([v3Instance1.init(), v3Instance2.init()]);
154152

155153
// Both should work fine
156154
expect(v3Instance1.context).toBeDefined();

0 commit comments

Comments
 (0)