cdp-mcp 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -303
- package/bin.js +23 -0
- package/contract.d.ts +1 -0
- package/contract.js +2 -0
- package/index.d.ts +1 -0
- package/index.js +2 -0
- package/package.json +31 -73
- package/dist/contract.d.ts +0 -11
- package/dist/contract.js +0 -11
- package/dist/contract.js.map +0 -1
- package/dist/index.d.ts +0 -18
- package/dist/index.js +0 -402
- package/dist/index.js.map +0 -1
- package/dist/locator.d.ts +0 -108
- package/dist/locator.js +0 -176
- package/dist/locator.js.map +0 -1
- package/dist/server.d.ts +0 -2
- package/dist/server.js +0 -41
- package/dist/server.js.map +0 -1
- package/dist/session/browser.d.ts +0 -29
- package/dist/session/browser.js +0 -409
- package/dist/session/browser.js.map +0 -1
- package/dist/session/buffers.d.ts +0 -48
- package/dist/session/buffers.js +0 -43
- package/dist/session/buffers.js.map +0 -1
- package/dist/session/pause.d.ts +0 -21
- package/dist/session/pause.js +0 -99
- package/dist/session/pause.js.map +0 -1
- package/dist/session/state.d.ts +0 -53
- package/dist/session/state.js +0 -93
- package/dist/session/state.js.map +0 -1
- package/dist/sourcemap/loader.d.ts +0 -4
- package/dist/sourcemap/loader.js +0 -138
- package/dist/sourcemap/loader.js.map +0 -1
- package/dist/sourcemap/normalize.d.ts +0 -2
- package/dist/sourcemap/normalize.js +0 -59
- package/dist/sourcemap/normalize.js.map +0 -1
- package/dist/sourcemap/store.d.ts +0 -57
- package/dist/sourcemap/store.js +0 -185
- package/dist/sourcemap/store.js.map +0 -1
- package/dist/tools/_locator_runtime.d.ts +0 -31
- package/dist/tools/_locator_runtime.js +0 -243
- package/dist/tools/_locator_runtime.js.map +0 -1
- package/dist/tools/_register.d.ts +0 -2
- package/dist/tools/_register.js +0 -30
- package/dist/tools/_register.js.map +0 -1
- package/dist/tools/breakpoints.d.ts +0 -4
- package/dist/tools/breakpoints.js +0 -164
- package/dist/tools/breakpoints.js.map +0 -1
- package/dist/tools/console.d.ts +0 -2
- package/dist/tools/console.js +0 -48
- package/dist/tools/console.js.map +0 -1
- package/dist/tools/dom.d.ts +0 -2
- package/dist/tools/dom.js +0 -309
- package/dist/tools/dom.js.map +0 -1
- package/dist/tools/execution.d.ts +0 -29
- package/dist/tools/execution.js +0 -89
- package/dist/tools/execution.js.map +0 -1
- package/dist/tools/forms.d.ts +0 -8
- package/dist/tools/forms.js +0 -256
- package/dist/tools/forms.js.map +0 -1
- package/dist/tools/inspect.d.ts +0 -2
- package/dist/tools/inspect.js +0 -178
- package/dist/tools/inspect.js.map +0 -1
- package/dist/tools/nav.d.ts +0 -2
- package/dist/tools/nav.js +0 -136
- package/dist/tools/nav.js.map +0 -1
- package/dist/tools/network.d.ts +0 -2
- package/dist/tools/network.js +0 -137
- package/dist/tools/network.js.map +0 -1
- package/dist/tools/session.d.ts +0 -2
- package/dist/tools/session.js +0 -76
- package/dist/tools/session.js.map +0 -1
- package/dist/tools/source.d.ts +0 -2
- package/dist/tools/source.js +0 -63
- package/dist/tools/source.js.map +0 -1
- package/dist/tools/storage.d.ts +0 -2
- package/dist/tools/storage.js +0 -296
- package/dist/tools/storage.js.map +0 -1
- package/dist/util/browser-resolve.d.ts +0 -19
- package/dist/util/browser-resolve.js +0 -263
- package/dist/util/browser-resolve.js.map +0 -1
- package/dist/util/errors.d.ts +0 -7
- package/dist/util/errors.js +0 -12
- package/dist/util/errors.js.map +0 -1
- package/dist/util/format.d.ts +0 -20
- package/dist/util/format.js +0 -65
- package/dist/util/format.js.map +0 -1
- package/dist/util/log.d.ts +0 -6
- package/dist/util/log.js +0 -34
- package/dist/util/log.js.map +0 -1
- package/docs/chromium-sandboxing.md +0 -197
- package/docs/known-chromium-gaps.md +0 -138
- package/docs/launchd-service.md +0 -217
- package/docs/local-l3-e2e-setup.md +0 -199
- package/docs/systemd-service.md +0 -233
package/dist/tools/storage.js
DELETED
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { readFile, writeFile, rename, rm } from "node:fs/promises";
|
|
3
|
-
import { randomBytes } from "node:crypto";
|
|
4
|
-
import { requireSession } from "../session/state.js";
|
|
5
|
-
import { ToolError } from "../util/errors.js";
|
|
6
|
-
import { registerJsonTool } from "./_register.js";
|
|
7
|
-
/**
|
|
8
|
-
* Session-portability tools (issue #12 items 4, 5).
|
|
9
|
-
*
|
|
10
|
-
* Cookies go through CDP `Network.*` (NOT `document.cookie`) so HttpOnly
|
|
11
|
-
* auth/session cookies — the whole reason to resume a session — round-trip.
|
|
12
|
-
* localStorage is read/written via `Runtime.evaluate` (the `Storage.*` domain
|
|
13
|
-
* is out of scope per AGENTS.md). The on-disk shape is the de-facto Playwright
|
|
14
|
-
* `storageState` JSON so a flow can be handed to/from mainstream tooling.
|
|
15
|
-
*
|
|
16
|
-
* v1 localStorage scope is the **current page origin** only: localStorage is
|
|
17
|
-
* origin-partitioned and CDP can only read/write it for a document that is
|
|
18
|
-
* actually on that origin. Cookies (the load-bearing part for auth resume) are
|
|
19
|
-
* captured/restored for all origins. Multi-origin localStorage restore would
|
|
20
|
-
* require navigating to each origin first; origins in the file that don't match
|
|
21
|
-
* the current page are reported in `origins_skipped` rather than silently lost.
|
|
22
|
-
*
|
|
23
|
-
* File read/write mirrors `screenshot path=`: no extra path filter — the
|
|
24
|
-
* operator gate is the same `--allow-remote`/non-loopback rule (README §SSE).
|
|
25
|
-
*/
|
|
26
|
-
const SENSITIVE_NAME = /(sess|sid|token|auth|csrf|xsrf|jwt|secret|api[-_]?key)/i;
|
|
27
|
-
const sameSiteSchema = z.enum(["Strict", "Lax", "None"]);
|
|
28
|
-
const storageStateSchema = z.object({
|
|
29
|
-
cookies: z
|
|
30
|
-
.array(z.object({
|
|
31
|
-
name: z.string(),
|
|
32
|
-
value: z.string(),
|
|
33
|
-
domain: z.string(),
|
|
34
|
-
path: z.string(),
|
|
35
|
-
expires: z.number().optional(),
|
|
36
|
-
httpOnly: z.boolean().optional(),
|
|
37
|
-
secure: z.boolean().optional(),
|
|
38
|
-
sameSite: sameSiteSchema.optional(),
|
|
39
|
-
}))
|
|
40
|
-
.default([]),
|
|
41
|
-
origins: z
|
|
42
|
-
.array(z.object({
|
|
43
|
-
origin: z.string(),
|
|
44
|
-
localStorage: z.array(z.object({ name: z.string(), value: z.string() })).default([]),
|
|
45
|
-
}))
|
|
46
|
-
.default([]),
|
|
47
|
-
});
|
|
48
|
-
const cookieParamSchema = z.object({
|
|
49
|
-
name: z.string(),
|
|
50
|
-
value: z.string(),
|
|
51
|
-
url: z.string().optional().describe("Cookie URL (provide this OR domain)."),
|
|
52
|
-
domain: z.string().optional(),
|
|
53
|
-
path: z.string().optional(),
|
|
54
|
-
secure: z.boolean().optional(),
|
|
55
|
-
httpOnly: z.boolean().optional(),
|
|
56
|
-
sameSite: sameSiteSchema.optional(),
|
|
57
|
-
expires: z.number().optional().describe("Expiry as seconds since epoch; omit for a session cookie."),
|
|
58
|
-
});
|
|
59
|
-
/**
|
|
60
|
-
* Write `data` to `dest` at mode 0o600, overwrite-safe and TOCTOU-safe.
|
|
61
|
-
*
|
|
62
|
-
* The storage-state file holds plaintext cookie secrets, so the 0o600
|
|
63
|
-
* postcondition must hold even on a shared, world-writable directory. Two traps:
|
|
64
|
-
* - Node's writeFile `mode` only applies when it *creates* the file, so writing
|
|
65
|
-
* straight to `dest` would leave an existing 0644 file world-readable.
|
|
66
|
-
* - A *predictable* temp path lets an attacker pre-create (or symlink) it at
|
|
67
|
-
* 0644, so the secret gets written through their file and renamed into place.
|
|
68
|
-
*
|
|
69
|
-
* So: create a temp with an **unpredictable** same-directory suffix using
|
|
70
|
-
* exclusive create (`flag: "wx"` ⇒ O_CREAT|O_EXCL — fails on any pre-existing
|
|
71
|
-
* file and refuses to follow a symlink), which makes 0o600 a real creation-time
|
|
72
|
-
* guarantee, then atomically rename it over the destination (same filesystem, so
|
|
73
|
-
* the secret never exists at the destination path in a half-written/0644 state).
|
|
74
|
-
* Retry on the astronomically-unlikely name collision.
|
|
75
|
-
*/
|
|
76
|
-
async function writeSecretFileAtomic(dest, data) {
|
|
77
|
-
let lastErr;
|
|
78
|
-
for (let attempt = 0; attempt < 5; attempt++) {
|
|
79
|
-
const tmp = `${dest}.${randomBytes(8).toString("hex")}.tmp`;
|
|
80
|
-
try {
|
|
81
|
-
await writeFile(tmp, data, { flag: "wx", mode: 0o600 });
|
|
82
|
-
}
|
|
83
|
-
catch (e) {
|
|
84
|
-
if (e.code === "EEXIST") {
|
|
85
|
-
lastErr = e;
|
|
86
|
-
continue; // collision (or planted file/symlink) — try a fresh random name
|
|
87
|
-
}
|
|
88
|
-
throw e; // ENOENT (missing parent dir), EACCES, etc.
|
|
89
|
-
}
|
|
90
|
-
try {
|
|
91
|
-
await rename(tmp, dest);
|
|
92
|
-
}
|
|
93
|
-
catch (e) {
|
|
94
|
-
await rm(tmp, { force: true }).catch(() => { });
|
|
95
|
-
throw e;
|
|
96
|
-
}
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
throw lastErr;
|
|
100
|
-
}
|
|
101
|
-
export function registerStorageTools(server) {
|
|
102
|
-
registerJsonTool(server, "export_storage_state", "Save the browser session (all cookies including HttpOnly, plus the current page origin's localStorage) to a JSON file in the de-facto Playwright storageState shape, so a flow can be resumed in a fresh session or handed to other tooling. The file preserves full cookie values (it exists to resume auth) — treat it as a secret. File write is gated by the same operator rule as screenshot path= / --allow-remote.", { path: z.string().describe("Absolute path to write the storageState JSON to.") }, async (input) => {
|
|
103
|
-
const s = requireSession();
|
|
104
|
-
const { cookies } = (await s.client.send("Network.getAllCookies"));
|
|
105
|
-
const probe = await s.client.send("Runtime.evaluate", {
|
|
106
|
-
expression: READ_ORIGIN_AND_LOCALSTORAGE,
|
|
107
|
-
returnByValue: true,
|
|
108
|
-
});
|
|
109
|
-
const probed = (probe.result?.value ?? { origin: "null", localStorage: [] });
|
|
110
|
-
const origins = probed.origin && probed.origin !== "null"
|
|
111
|
-
? [{ origin: probed.origin, localStorage: probed.localStorage }]
|
|
112
|
-
: [];
|
|
113
|
-
const state = { cookies: cookies.map(cdpCookieToState), origins };
|
|
114
|
-
// The file holds full cookie values (incl. HttpOnly auth/session tokens) —
|
|
115
|
-
// the description says "treat it as a secret". writeSecretFileAtomic writes
|
|
116
|
-
// it 0o600 and overwrite-safe (see the helper for the threat model).
|
|
117
|
-
try {
|
|
118
|
-
await writeSecretFileAtomic(input.path, JSON.stringify(state, null, 2));
|
|
119
|
-
}
|
|
120
|
-
catch (e) {
|
|
121
|
-
if (e.code === "ENOENT") {
|
|
122
|
-
throw new ToolError("not_found", `could not write storage-state file (does the parent directory exist?): ${e.message}`);
|
|
123
|
-
}
|
|
124
|
-
throw e; // EACCES/EISDIR/etc. surface as internal_error via registerJsonTool
|
|
125
|
-
}
|
|
126
|
-
return { saved: input.path, cookies: state.cookies.length, origins: origins.length };
|
|
127
|
-
});
|
|
128
|
-
registerJsonTool(server, "load_storage_state", "Restore a session from a Playwright-shaped storageState JSON file: sets all cookies (no navigation needed), then restores localStorage for the entries whose origin matches the current page. Cookies are added on top of the existing jar (additive, not a clean-context replace), so prefer a fresh session for Playwright-equivalent semantics. Origins that don't match the current page are returned in origins_skipped (restoring them would require navigating there first). File read is gated by the same operator rule as screenshot path= / --allow-remote.", { path: z.string().describe("Absolute path to a storageState JSON file (as written by export_storage_state).") }, async (input) => {
|
|
129
|
-
const s = requireSession();
|
|
130
|
-
let raw;
|
|
131
|
-
try {
|
|
132
|
-
raw = await readFile(input.path, "utf8");
|
|
133
|
-
}
|
|
134
|
-
catch (e) {
|
|
135
|
-
if (e.code === "ENOENT") {
|
|
136
|
-
throw new ToolError("not_found", `could not read storage-state file: ${e.message}`);
|
|
137
|
-
}
|
|
138
|
-
throw e; // EACCES/EISDIR/etc. surface as internal_error rather than masquerading as not_found
|
|
139
|
-
}
|
|
140
|
-
let parsed;
|
|
141
|
-
try {
|
|
142
|
-
parsed = JSON.parse(raw);
|
|
143
|
-
}
|
|
144
|
-
catch {
|
|
145
|
-
throw new ToolError("invalid_arg", "storage-state file is not valid JSON");
|
|
146
|
-
}
|
|
147
|
-
const result = storageStateSchema.safeParse(parsed);
|
|
148
|
-
if (!result.success) {
|
|
149
|
-
throw new ToolError("invalid_arg", `storage-state file is not a valid storageState: ${result.error.message}`);
|
|
150
|
-
}
|
|
151
|
-
const state = result.data;
|
|
152
|
-
if (state.cookies.length > 0) {
|
|
153
|
-
await s.client.send("Network.setCookies", { cookies: state.cookies.map(stateCookieToCdp) });
|
|
154
|
-
}
|
|
155
|
-
const restore = await s.client.send("Runtime.evaluate", {
|
|
156
|
-
expression: restoreLocalStorageExpr(state.origins),
|
|
157
|
-
returnByValue: true,
|
|
158
|
-
});
|
|
159
|
-
const restored = (restore.result?.value ?? { restored: [], skipped: state.origins.map((o) => o.origin) });
|
|
160
|
-
return {
|
|
161
|
-
loaded: input.path,
|
|
162
|
-
cookies: state.cookies.length,
|
|
163
|
-
origins_restored: restored.restored,
|
|
164
|
-
origins_skipped: restored.skipped,
|
|
165
|
-
};
|
|
166
|
-
});
|
|
167
|
-
registerJsonTool(server, "get_cookies", "List cookies (via CDP, so HttpOnly cookies are included) with their flags. For safe printing, the VALUE of likely session/auth cookies is redacted (httpOnly cookies, or names matching sess/sid/token/auth/csrf/jwt/secret/api-key); only value_length is shown for those. Full values are obtainable only through export_storage_state.", {
|
|
168
|
-
urls: z
|
|
169
|
-
.array(z.string())
|
|
170
|
-
.optional()
|
|
171
|
-
.describe("Restrict to cookies visible to these URLs; omit for all cookies in the browser."),
|
|
172
|
-
}, async (input) => {
|
|
173
|
-
const s = requireSession();
|
|
174
|
-
const res = (input.urls && input.urls.length > 0
|
|
175
|
-
? await s.client.send("Network.getCookies", { urls: input.urls })
|
|
176
|
-
: await s.client.send("Network.getAllCookies"));
|
|
177
|
-
return { cookies: res.cookies.map(redactForDisplay) };
|
|
178
|
-
});
|
|
179
|
-
registerJsonTool(server, "set_cookies", "Set one or more cookies in the browser cookie jar via CDP. Each cookie needs a url OR a domain. For restoring a saved session, prefer load_storage_state; this is the lower-level primitive.", { cookies: z.array(cookieParamSchema).describe("Cookies to set.") }, async (input) => {
|
|
180
|
-
const s = requireSession();
|
|
181
|
-
if (input.cookies.length === 0)
|
|
182
|
-
throw new ToolError("missing_arg", "cookies array is empty");
|
|
183
|
-
const missing = input.cookies.find((c) => !c.url && !c.domain);
|
|
184
|
-
if (missing)
|
|
185
|
-
throw new ToolError("missing_arg", `cookie '${missing.name}' needs a url or domain`);
|
|
186
|
-
// Normalize the session-cookie sentinel the same way load_storage_state
|
|
187
|
-
// does, so an exported `expires: -1` piped in here isn't sent as a 1969 expiry.
|
|
188
|
-
await s.client.send("Network.setCookies", {
|
|
189
|
-
cookies: input.cookies.map(withSessionExpiryOmitted),
|
|
190
|
-
});
|
|
191
|
-
return { set: input.cookies.length };
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
function cdpCookieToState(c) {
|
|
195
|
-
return {
|
|
196
|
-
name: c.name,
|
|
197
|
-
value: c.value,
|
|
198
|
-
domain: c.domain,
|
|
199
|
-
path: c.path,
|
|
200
|
-
// CDP uses -1 (or a missing field) for session cookies; Playwright too.
|
|
201
|
-
expires: typeof c.expires === "number" ? c.expires : -1,
|
|
202
|
-
httpOnly: !!c.httpOnly,
|
|
203
|
-
secure: !!c.secure,
|
|
204
|
-
// Playwright requires sameSite; CDP may omit it. Lax is the browser default.
|
|
205
|
-
sameSite: c.sameSite ?? "Lax",
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* CDP's `Network.setCookies` reads `expires` as an absolute epoch-seconds
|
|
210
|
-
* timestamp, so the session-cookie sentinel (`-1`, which `export_storage_state`
|
|
211
|
-
* writes) must be dropped rather than forwarded — otherwise the cookie is set
|
|
212
|
-
* already-expired (1969) and silently rejected. Shared by `load_storage_state`
|
|
213
|
-
* and `set_cookies` so both restore paths normalize identically.
|
|
214
|
-
*/
|
|
215
|
-
function withSessionExpiryOmitted(cookie) {
|
|
216
|
-
if (typeof cookie.expires === "number" && cookie.expires >= 0)
|
|
217
|
-
return cookie;
|
|
218
|
-
const copy = { ...cookie };
|
|
219
|
-
delete copy.expires;
|
|
220
|
-
return copy;
|
|
221
|
-
}
|
|
222
|
-
function stateCookieToCdp(c) {
|
|
223
|
-
const param = {
|
|
224
|
-
name: c.name,
|
|
225
|
-
value: c.value,
|
|
226
|
-
domain: c.domain,
|
|
227
|
-
path: c.path,
|
|
228
|
-
secure: !!c.secure,
|
|
229
|
-
httpOnly: !!c.httpOnly,
|
|
230
|
-
expires: c.expires,
|
|
231
|
-
};
|
|
232
|
-
if (c.sameSite)
|
|
233
|
-
param.sameSite = c.sameSite;
|
|
234
|
-
// -1 / undefined means a session cookie — omit expires entirely.
|
|
235
|
-
return withSessionExpiryOmitted(param);
|
|
236
|
-
}
|
|
237
|
-
function redactForDisplay(c) {
|
|
238
|
-
const redacted = !!c.httpOnly || SENSITIVE_NAME.test(c.name);
|
|
239
|
-
const out = {
|
|
240
|
-
name: c.name,
|
|
241
|
-
domain: c.domain,
|
|
242
|
-
path: c.path,
|
|
243
|
-
expires: typeof c.expires === "number" ? c.expires : -1,
|
|
244
|
-
httpOnly: !!c.httpOnly,
|
|
245
|
-
secure: !!c.secure,
|
|
246
|
-
sameSite: c.sameSite ?? null,
|
|
247
|
-
redacted,
|
|
248
|
-
value_length: (c.value ?? "").length,
|
|
249
|
-
};
|
|
250
|
-
if (!redacted)
|
|
251
|
-
out.value = c.value;
|
|
252
|
-
return out;
|
|
253
|
-
}
|
|
254
|
-
// ---------------------------------------------------------------------------
|
|
255
|
-
// In-page expressions
|
|
256
|
-
/** Read the current origin and its localStorage as { origin, localStorage:[{name,value}] }. */
|
|
257
|
-
const READ_ORIGIN_AND_LOCALSTORAGE = String.raw `(() => {
|
|
258
|
-
const items = [];
|
|
259
|
-
try {
|
|
260
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
261
|
-
const k = localStorage.key(i);
|
|
262
|
-
if (k === null) continue;
|
|
263
|
-
const v = localStorage.getItem(k);
|
|
264
|
-
if (v === null) continue;
|
|
265
|
-
items.push({ name: k, value: v });
|
|
266
|
-
}
|
|
267
|
-
} catch (e) {}
|
|
268
|
-
return { origin: location.origin, localStorage: items };
|
|
269
|
-
})()`;
|
|
270
|
-
/**
|
|
271
|
-
* For each origin in the file whose origin matches the current page, write its
|
|
272
|
-
* localStorage entries; report which origins were restored vs skipped.
|
|
273
|
-
*/
|
|
274
|
-
function restoreLocalStorageExpr(origins) {
|
|
275
|
-
return String.raw `(() => {
|
|
276
|
-
const origins = ${JSON.stringify(origins)};
|
|
277
|
-
const current = location.origin;
|
|
278
|
-
const restored = [];
|
|
279
|
-
const skipped = [];
|
|
280
|
-
for (const o of origins) {
|
|
281
|
-
if (o.origin !== current) {
|
|
282
|
-
skipped.push(o.origin);
|
|
283
|
-
continue;
|
|
284
|
-
}
|
|
285
|
-
// If any setItem throws (quota exceeded, storage disabled), report the
|
|
286
|
-
// origin as skipped rather than misleadingly claiming it was restored.
|
|
287
|
-
let ok = true;
|
|
288
|
-
for (const it of o.localStorage) {
|
|
289
|
-
try { localStorage.setItem(it.name, it.value); } catch (e) { ok = false; }
|
|
290
|
-
}
|
|
291
|
-
(ok ? restored : skipped).push(o.origin);
|
|
292
|
-
}
|
|
293
|
-
return { restored, skipped };
|
|
294
|
-
})()`;
|
|
295
|
-
}
|
|
296
|
-
//# sourceMappingURL=storage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/tools/storage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,cAAc,GAAG,yDAAyD,CAAC;AAEjF,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzD,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,OAAO,EAAE,CAAC;SACP,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC9B,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC9B,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;KACpC,CAAC,CACH;SACA,OAAO,CAAC,EAAE,CAAC;IACd,OAAO,EAAE,CAAC;SACP,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;KACrF,CAAC,CACH;SACA,OAAO,CAAC,EAAE,CAAC;CACf,CAAC,CAAC;AAKH,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAC3E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAChC,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2DAA2D,CAAC;CACrG,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,KAAK,UAAU,qBAAqB,CAAC,IAAY,EAAE,IAAY;IAC7D,IAAI,OAAgB,CAAC;IACrB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5D,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnD,OAAO,GAAG,CAAC,CAAC;gBACZ,SAAS,CAAC,gEAAgE;YAC5E,CAAC;YACD,MAAM,CAAC,CAAC,CAAC,4CAA4C;QACvD,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,CAAC;QACV,CAAC;QACD,OAAO;IACT,CAAC;IACD,MAAM,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,gBAAgB,CACd,MAAM,EACN,sBAAsB,EACtB,2ZAA2Z,EAC3Z,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC,EAAE,EACjF,KAAK,EAAE,KAAuB,EAAE,EAAE;QAChC,MAAM,CAAC,GAAG,cAAc,EAAE,CAAC;QAC3B,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAA6B,CAAC;QAChG,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE;YACrD,UAAU,EAAE,4BAA4B;YACxC,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,CAG1E,CAAC;QACF,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;YACvC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;YAChE,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,KAAK,GAAiB,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;QAChF,2EAA2E;QAC3E,4EAA4E;QAC5E,qEAAqE;QACrE,IAAI,CAAC;YACH,MAAM,qBAAqB,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnD,MAAM,IAAI,SAAS,CACjB,WAAW,EACX,0EAA2E,CAAW,CAAC,OAAO,EAAE,CACjG,CAAC;YACJ,CAAC;YACD,MAAM,CAAC,CAAC,CAAC,oEAAoE;QAC/E,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IACvF,CAAC,CACF,CAAC;IAEF,gBAAgB,CACd,MAAM,EACN,oBAAoB,EACpB,wiBAAwiB,EACxiB,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iFAAiF,CAAC,EAAE,EAChH,KAAK,EAAE,KAAuB,EAAE,EAAE;QAChC,MAAM,CAAC,GAAG,cAAc,EAAE,CAAC;QAC3B,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnD,MAAM,IAAI,SAAS,CAAC,WAAW,EAAE,sCAAuC,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YACjG,CAAC;YACD,MAAM,CAAC,CAAC,CAAC,qFAAqF;QAChG,CAAC;QACD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,SAAS,CAAC,aAAa,EAAE,sCAAsC,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,SAAS,CAAC,aAAa,EAAE,mDAAmD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;QAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE;YACvD,UAAU,EAAE,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC;YAClD,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAGvG,CAAC;QACF,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,IAAI;YAClB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM;YAC7B,gBAAgB,EAAE,QAAQ,CAAC,QAAQ;YACnC,eAAe,EAAE,QAAQ,CAAC,OAAO;SAClC,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,gBAAgB,CACd,MAAM,EACN,aAAa,EACb,2UAA2U,EAC3U;QACE,IAAI,EAAE,CAAC;aACJ,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,EAAE;aACV,QAAQ,CAAC,iFAAiF,CAAC;KAC/F,EACD,KAAK,EAAE,KAA0B,EAAE,EAAE;QACnC,MAAM,CAAC,GAAG,cAAc,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,CACV,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;YACjC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YAClE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CACtB,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;IACxD,CAAC,CACF,CAAC;IAEF,gBAAgB,CACd,MAAM,EACN,aAAa,EACb,8LAA8L,EAC9L,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,EACnE,KAAK,EAAE,KAA4D,EAAE,EAAE;QACrE,MAAM,CAAC,GAAG,cAAc,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,aAAa,EAAE,wBAAwB,CAAC,CAAC;QAC7F,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/D,IAAI,OAAO;YAAE,MAAM,IAAI,SAAS,CAAC,aAAa,EAAE,WAAW,OAAO,CAAC,IAAI,yBAAyB,CAAC,CAAC;QAClG,wEAAwE;QACxE,gFAAgF;QAChF,MAAM,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE;YACzC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;SACrD,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;IACvC,CAAC,CACF,CAAC;AACJ,CAAC;AAgBD,SAAS,gBAAgB,CAAC,CAAY;IACpC,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,wEAAwE;QACxE,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ;QACtB,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM;QAClB,6EAA6E;QAC7E,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,KAAK;KAC9B,CAAC;AACJ,CAAC;AAiBD;;;;;;GAMG;AACH,SAAS,wBAAwB,CAAiC,MAAS;IACzE,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7E,MAAM,IAAI,GAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAC9B,OAAO,IAAI,CAAC,OAAO,CAAC;IACpB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB,CAAC,CAAc;IACtC,MAAM,KAAK,GAAmB;QAC5B,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM;QAClB,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ;QACtB,OAAO,EAAE,CAAC,CAAC,OAAO;KACnB,CAAC;IACF,IAAI,CAAC,CAAC,QAAQ;QAAE,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC5C,iEAAiE;IACjE,OAAO,wBAAwB,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,gBAAgB,CAAC,CAAY;IACpC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7D,MAAM,GAAG,GAA4B;QACnC,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ;QACtB,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM;QAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;QAC5B,QAAQ;QACR,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM;KACrC,CAAC;IACF,IAAI,CAAC,QAAQ;QAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IACnC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AAEtB,+FAA+F;AAC/F,MAAM,4BAA4B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;KAY1C,CAAC;AAEN;;;GAGG;AACH,SAAS,uBAAuB,CAAC,OAAgC;IAC/D,OAAO,MAAM,CAAC,GAAG,CAAA;sBACG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;OAkBtC,CAAC;AACR,CAAC"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export type BrowserChoice = "chromium" | "chrome";
|
|
2
|
-
export interface ResolvedBrowser {
|
|
3
|
-
/** Absolute path to the Chrome/Chromium executable. */
|
|
4
|
-
binaryPath: string;
|
|
5
|
-
/** Which logical browser this binary represents. */
|
|
6
|
-
choice: BrowserChoice;
|
|
7
|
-
/** True when the binary is snap-confined (/snap/bin/* on Linux). Triggers
|
|
8
|
-
* the user-data-dir workaround in launch_chrome. */
|
|
9
|
-
snapConfined: boolean;
|
|
10
|
-
/** Diagnostic — which resolution step produced this. */
|
|
11
|
-
source: "CDP_TEST_BROWSER_PATH" | "which-chromium" | "playwright-cache" | "chrome-launcher-default";
|
|
12
|
-
}
|
|
13
|
-
export declare function getBrowserChoice(): BrowserChoice;
|
|
14
|
-
export declare function resolveBrowser(choice?: BrowserChoice): ResolvedBrowser;
|
|
15
|
-
/** True when the given binary is the snap-marker returned by step 4. */
|
|
16
|
-
export declare function isChromeLauncherDefault(b: ResolvedBrowser): boolean;
|
|
17
|
-
/** Determine the user-data-dir for snap-confined Chromium. Snap confinement
|
|
18
|
-
* rejects /tmp/... paths; only ~/snap/<app>/current/ is writable. */
|
|
19
|
-
export declare function snapUserDataDir(binaryPath: string): string;
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
// Shared Chromium/Chrome resolver used by BOTH the L3 e2e suite
|
|
2
|
-
// (test/e2e/setup/browser-path.ts re-exports from here) AND the L4 eval
|
|
3
|
-
// harness (evals/harness/runner.ts imports resolveBrowser() and feeds
|
|
4
|
-
// the result into the spawned MCP server via CHROME_PATH). Single
|
|
5
|
-
// resolution path so both layers cannot test against different
|
|
6
|
-
// protocol versions — the intent already documented in
|
|
7
|
-
// docs/test-eval-plan.md §L3 *Production code change required for
|
|
8
|
-
// chromePath* and §L3 *CI matrix* ("the same helper is reused by the
|
|
9
|
-
// eval harness").
|
|
10
|
-
//
|
|
11
|
-
// Resolution order (fail-fast — never silently fall back to chrome-
|
|
12
|
-
// launcher's auto-detection, because that's how the wrong browser ends
|
|
13
|
-
// up running and tests pass against the wrong protocol revision):
|
|
14
|
-
// 1. CDP_TEST_BROWSER_PATH env — explicit override, used by CI after
|
|
15
|
-
// `npx playwright install --with-deps chromium`. Wins everything.
|
|
16
|
-
// 2. `which chromium` (Linux/macOS) / `where chromium.exe` (Windows) —
|
|
17
|
-
// local dev path. Catches both /snap/bin/chromium and the apt
|
|
18
|
-
// /usr/bin/chromium symlink.
|
|
19
|
-
// 3. Playwright bundled cache — ~/.cache/ms-playwright/chromium-*/
|
|
20
|
-
// chrome-linux/chrome (Linux), ~/Library/Caches/ms-playwright/...
|
|
21
|
-
// (macOS), %LOCALAPPDATA%\ms-playwright\... (Windows). Handy after
|
|
22
|
-
// a fresh `npx playwright install`.
|
|
23
|
-
// 4. CDP_TEST_BROWSER=chrome — chrome-launcher's default detection.
|
|
24
|
-
// 5. Fail with an actionable install hint.
|
|
25
|
-
import { execSync } from "node:child_process";
|
|
26
|
-
import { existsSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
27
|
-
import { homedir, platform } from "node:os";
|
|
28
|
-
import { join } from "node:path";
|
|
29
|
-
export function getBrowserChoice() {
|
|
30
|
-
const env = process.env.CDP_TEST_BROWSER?.toLowerCase();
|
|
31
|
-
if (env === "chrome")
|
|
32
|
-
return "chrome";
|
|
33
|
-
if (env === "chromium" || env === undefined || env === "")
|
|
34
|
-
return "chromium";
|
|
35
|
-
throw new Error(`CDP_TEST_BROWSER must be 'chromium' or 'chrome' (got '${env}'). Default is 'chromium'.`);
|
|
36
|
-
}
|
|
37
|
-
export function resolveBrowser(choice = getBrowserChoice()) {
|
|
38
|
-
// Step 1 — explicit override wins.
|
|
39
|
-
const override = process.env.CDP_TEST_BROWSER_PATH;
|
|
40
|
-
if (override) {
|
|
41
|
-
if (!existsSync(override)) {
|
|
42
|
-
throw new Error(`CDP_TEST_BROWSER_PATH='${override}' does not exist. Unset it or install the binary.`);
|
|
43
|
-
}
|
|
44
|
-
return {
|
|
45
|
-
binaryPath: override,
|
|
46
|
-
choice,
|
|
47
|
-
snapConfined: override.startsWith("/snap/"),
|
|
48
|
-
source: "CDP_TEST_BROWSER_PATH",
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
// Step 2 — system-installed chromium (Linux/macOS via `which`, Windows via
|
|
52
|
-
// `where`). Skip when choice is 'chrome' — Chrome detection is delegated to
|
|
53
|
-
// chrome-launcher's defaults in step 4.
|
|
54
|
-
//
|
|
55
|
-
// On darwin we additionally skip the deprecated Homebrew cask `chromium`
|
|
56
|
-
// wrapper at /opt/homebrew/bin/chromium (and any path whose realpath
|
|
57
|
-
// resolves into /opt/homebrew/Caskroom/chromium/). That wrapper points
|
|
58
|
-
// at an unsigned .app Gatekeeper rejects as "damaged" — it launches
|
|
59
|
-
// successfully but the debug port never opens, so chrome-launcher's
|
|
60
|
-
// startup-port poll ECONNREFUSEs. The same gap is precisely what the
|
|
61
|
-
// §macOS arm64 entry in docs/known-chromium-gaps.md documents; skipping
|
|
62
|
-
// it here is what makes that entry's "resolveBrowser picks it up
|
|
63
|
-
// automatically" claim actually true for users who tried the cask first
|
|
64
|
-
// before reading the doc. Cask deprecation removal is scheduled
|
|
65
|
-
// 2026-09-01; once removed this skip becomes a no-op.
|
|
66
|
-
if (choice === "chromium") {
|
|
67
|
-
const sys = findOnPath("chromium") ?? findOnPath("chromium-browser");
|
|
68
|
-
if (sys && !isBrewCaskChromium(sys)) {
|
|
69
|
-
return {
|
|
70
|
-
binaryPath: sys,
|
|
71
|
-
choice,
|
|
72
|
-
snapConfined: sys.startsWith("/snap/"),
|
|
73
|
-
source: "which-chromium",
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
// Step 3 — Playwright's bundled cache. Used in CI after
|
|
78
|
-
// `npx playwright install`; also useful locally when the system chromium
|
|
79
|
-
// isn't installed.
|
|
80
|
-
const pw = findPlaywrightChromium();
|
|
81
|
-
if (pw && choice === "chromium") {
|
|
82
|
-
return {
|
|
83
|
-
binaryPath: pw,
|
|
84
|
-
choice,
|
|
85
|
-
snapConfined: false,
|
|
86
|
-
source: "playwright-cache",
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
// Step 4 — Chrome stable, only when explicitly requested. We don't return a
|
|
90
|
-
// path here; the caller forwards `undefined` to chrome-launcher, which runs
|
|
91
|
-
// its own detection. This is intentionally NOT used as a silent fallback
|
|
92
|
-
// for chromium because the protocol revision can diverge.
|
|
93
|
-
if (choice === "chrome") {
|
|
94
|
-
// chrome-launcher uses its own which() — we just signal it should take
|
|
95
|
-
// over by returning the marker path "chrome-launcher-default". Both
|
|
96
|
-
// callers strip this back to undefined before forwarding the path: L3
|
|
97
|
-
// global setup at test/e2e/setup/global.ts skips `chromePath` entirely,
|
|
98
|
-
// and the L4 runner at evals/harness/runner.ts omits CHROME_PATH from
|
|
99
|
-
// the subprocess env via isChromeLauncherDefault().
|
|
100
|
-
return {
|
|
101
|
-
binaryPath: "chrome-launcher-default",
|
|
102
|
-
choice,
|
|
103
|
-
snapConfined: false,
|
|
104
|
-
source: "chrome-launcher-default",
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
// Step 5 — actionable failure.
|
|
108
|
-
const isArm = process.arch === "arm64";
|
|
109
|
-
const installHint = isArm
|
|
110
|
-
? "sudo apt-get install chromium-browser # OR: npx playwright install chromium"
|
|
111
|
-
: "sudo snap install chromium OR sudo apt-get install chromium-browser OR npx playwright install chromium";
|
|
112
|
-
throw new Error(`Could not resolve a Chromium binary for the e2e suite.\n` +
|
|
113
|
-
`Tried (in order): CDP_TEST_BROWSER_PATH env, which chromium, Playwright cache.\n` +
|
|
114
|
-
`Install Chromium (${installHint}) or set CDP_TEST_BROWSER_PATH explicitly.`);
|
|
115
|
-
}
|
|
116
|
-
// Detect the deprecated Homebrew cask `chromium` wrapper on darwin. Returns
|
|
117
|
-
// true for both the well-known /opt/homebrew/bin/chromium path and any path
|
|
118
|
-
// whose realpath resolves into /opt/homebrew/Caskroom/chromium/ (covers
|
|
119
|
-
// future brew layout shifts where the wrapper lives elsewhere but the
|
|
120
|
-
// Caskroom prefix stays put). Never true off darwin.
|
|
121
|
-
function isBrewCaskChromium(binaryPath) {
|
|
122
|
-
if (platform() !== "darwin")
|
|
123
|
-
return false;
|
|
124
|
-
if (binaryPath === "/opt/homebrew/bin/chromium")
|
|
125
|
-
return true;
|
|
126
|
-
try {
|
|
127
|
-
const resolved = realpathSync(binaryPath);
|
|
128
|
-
return resolved.startsWith("/opt/homebrew/Caskroom/chromium/");
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
function findOnPath(cmd) {
|
|
135
|
-
try {
|
|
136
|
-
const which = platform() === "win32" ? "where" : "which";
|
|
137
|
-
const out = execSync(`${which} ${cmd}`, { stdio: ["ignore", "pipe", "ignore"] })
|
|
138
|
-
.toString()
|
|
139
|
-
.split(/\r?\n/)
|
|
140
|
-
.find((line) => line.trim().length > 0);
|
|
141
|
-
if (!out)
|
|
142
|
-
return null;
|
|
143
|
-
const path = out.trim();
|
|
144
|
-
return existsSync(path) ? path : null;
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
function findPlaywrightChromium() {
|
|
151
|
-
const candidates = playwrightCacheDirs();
|
|
152
|
-
for (const dir of candidates) {
|
|
153
|
-
if (!existsSync(dir))
|
|
154
|
-
continue;
|
|
155
|
-
let entries;
|
|
156
|
-
try {
|
|
157
|
-
entries = readdirSync(dir);
|
|
158
|
-
}
|
|
159
|
-
catch {
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
// Filter to chromium-* / chromium-headless-shell-* — pick the highest-
|
|
163
|
-
// numbered revision (newest install).
|
|
164
|
-
const chromiums = entries
|
|
165
|
-
.filter((e) => e.startsWith("chromium-") && !e.startsWith("chromium-headless-shell-"))
|
|
166
|
-
.map((e) => ({ name: e, full: join(dir, e) }))
|
|
167
|
-
.filter((e) => {
|
|
168
|
-
try {
|
|
169
|
-
return statSync(e.full).isDirectory();
|
|
170
|
-
}
|
|
171
|
-
catch {
|
|
172
|
-
return false;
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
.sort((a, b) => b.name.localeCompare(a.name));
|
|
176
|
-
for (const c of chromiums) {
|
|
177
|
-
const exe = pickPlaywrightExe(c.full);
|
|
178
|
-
if (exe)
|
|
179
|
-
return exe;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
function playwrightCacheDirs() {
|
|
185
|
-
const home = homedir();
|
|
186
|
-
const plat = platform();
|
|
187
|
-
if (plat === "linux")
|
|
188
|
-
return [join(home, ".cache", "ms-playwright")];
|
|
189
|
-
if (plat === "darwin")
|
|
190
|
-
return [join(home, "Library", "Caches", "ms-playwright")];
|
|
191
|
-
if (plat === "win32") {
|
|
192
|
-
const local = process.env.LOCALAPPDATA ?? join(home, "AppData", "Local");
|
|
193
|
-
return [join(local, "ms-playwright")];
|
|
194
|
-
}
|
|
195
|
-
return [join(home, ".cache", "ms-playwright")];
|
|
196
|
-
}
|
|
197
|
-
function pickPlaywrightExe(chromiumDir) {
|
|
198
|
-
// Layout, per Playwright's install layout:
|
|
199
|
-
// Linux: chromium-<rev>/chrome-linux/chrome
|
|
200
|
-
// macOS: chromium-<rev>/chrome-mac/Chromium.app/Contents/MacOS/Chromium
|
|
201
|
-
// Windows: chromium-<rev>/chrome-win/chrome.exe
|
|
202
|
-
const plat = platform();
|
|
203
|
-
// Playwright's layout varies by version/arch (Chrome-for-Testing renamed
|
|
204
|
-
// some folders ~Playwright 1.40+):
|
|
205
|
-
// Linux x86_64: chromium-<rev>/chrome-linux/chrome (older)
|
|
206
|
-
// chromium-<rev>/chrome-linux64/chrome (CfT, newer)
|
|
207
|
-
// Linux ARM64: chromium-<rev>/chrome-linux/chrome (ARM64 unchanged)
|
|
208
|
-
// chromium-<rev>/chrome-linux-arm64/chrome (rare variant)
|
|
209
|
-
// macOS x86_64: chromium-<rev>/chrome-mac/Chromium.app/... (older)
|
|
210
|
-
// chromium-<rev>/chrome-mac-x64/Google Chrome for Testing.app/... (CfT, newer)
|
|
211
|
-
// macOS arm64: chromium-<rev>/chrome-mac-arm/Chromium.app/... (older)
|
|
212
|
-
// chromium-<rev>/chrome-mac-arm64/Google Chrome for Testing.app/...(CfT, newer)
|
|
213
|
-
// Windows: chromium-<rev>/chrome-win/chrome.exe (older)
|
|
214
|
-
// chromium-<rev>/chrome-win64/chrome.exe (newer)
|
|
215
|
-
// Codex blocker review on PR #11 flagged the missing chrome-linux64
|
|
216
|
-
// candidate — modern Playwright on ubuntu-latest landed in CfT layout
|
|
217
|
-
// and the resolver step exited 1 before the test runner started.
|
|
218
|
-
// The mac-arm64 CfT candidates were added while validating
|
|
219
|
-
// set_breakpoint idempotency on darwin-arm64, where Playwright
|
|
220
|
-
// v1223+ installs to chrome-mac-arm64/Google Chrome
|
|
221
|
-
// for Testing.app/Contents/MacOS/Google Chrome for Testing.
|
|
222
|
-
const candidates = plat === "win32"
|
|
223
|
-
? [
|
|
224
|
-
join(chromiumDir, "chrome-win64", "chrome.exe"),
|
|
225
|
-
join(chromiumDir, "chrome-win", "chrome.exe"),
|
|
226
|
-
]
|
|
227
|
-
: plat === "darwin"
|
|
228
|
-
? [
|
|
229
|
-
// CfT-renamed layouts first (Playwright 1.40+ / chromium revisions
|
|
230
|
-
// ~v1200+). `existsSync` makes the order forgiving — try newer
|
|
231
|
-
// first so we don't accidentally pick an older sibling layout
|
|
232
|
-
// when both happen to be present.
|
|
233
|
-
join(chromiumDir, "chrome-mac-arm64", "Google Chrome for Testing.app", "Contents", "MacOS", "Google Chrome for Testing"),
|
|
234
|
-
join(chromiumDir, "chrome-mac-x64", "Google Chrome for Testing.app", "Contents", "MacOS", "Google Chrome for Testing"),
|
|
235
|
-
// Older Chromium.app-branded layouts.
|
|
236
|
-
join(chromiumDir, "chrome-mac", "Chromium.app", "Contents", "MacOS", "Chromium"),
|
|
237
|
-
join(chromiumDir, "chrome-mac-arm", "Chromium.app", "Contents", "MacOS", "Chromium"),
|
|
238
|
-
]
|
|
239
|
-
: [
|
|
240
|
-
join(chromiumDir, "chrome-linux", "chrome"),
|
|
241
|
-
join(chromiumDir, "chrome-linux64", "chrome"),
|
|
242
|
-
join(chromiumDir, "chrome-linux-arm64", "chrome"),
|
|
243
|
-
];
|
|
244
|
-
for (const c of candidates) {
|
|
245
|
-
if (existsSync(c))
|
|
246
|
-
return c;
|
|
247
|
-
}
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
/** True when the given binary is the snap-marker returned by step 4. */
|
|
251
|
-
export function isChromeLauncherDefault(b) {
|
|
252
|
-
return b.source === "chrome-launcher-default";
|
|
253
|
-
}
|
|
254
|
-
/** Determine the user-data-dir for snap-confined Chromium. Snap confinement
|
|
255
|
-
* rejects /tmp/... paths; only ~/snap/<app>/current/ is writable. */
|
|
256
|
-
export function snapUserDataDir(binaryPath) {
|
|
257
|
-
// Parse the snap app name out of the binary path. /snap/bin/chromium ->
|
|
258
|
-
// 'chromium'; /snap/firefox/current/firefox -> 'firefox'.
|
|
259
|
-
const match = binaryPath.match(/\/snap\/(?:bin\/)?([^/]+)/);
|
|
260
|
-
const app = match?.[1] ?? "chromium";
|
|
261
|
-
return join(homedir(), "snap", app, "current", "cdp-mcp-test-profile");
|
|
262
|
-
}
|
|
263
|
-
//# sourceMappingURL=browser-resolve.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-resolve.js","sourceRoot":"","sources":["../../src/util/browser-resolve.ts"],"names":[],"mappings":"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"}
|
package/dist/util/errors.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export declare class ToolError extends Error {
|
|
2
|
-
code: string;
|
|
3
|
-
constructor(code: string, message: string);
|
|
4
|
-
}
|
|
5
|
-
export declare const noSession: () => ToolError;
|
|
6
|
-
export declare const notPaused: () => ToolError;
|
|
7
|
-
export declare const alreadySession: () => ToolError;
|
package/dist/util/errors.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export class ToolError extends Error {
|
|
2
|
-
code;
|
|
3
|
-
constructor(code, message) {
|
|
4
|
-
super(message);
|
|
5
|
-
this.code = code;
|
|
6
|
-
this.name = "ToolError";
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
export const noSession = () => new ToolError("no_session", "No browser session. Call launch_chrome or attach_chrome first.");
|
|
10
|
-
export const notPaused = () => new ToolError("not_paused", "Operation requires the debugger to be paused. Set a breakpoint and call wait_for_pause.");
|
|
11
|
-
export const alreadySession = () => new ToolError("already_session", "A session is already active. Call close_session before opening a new one.");
|
|
12
|
-
//# sourceMappingURL=errors.js.map
|
package/dist/util/errors.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/util/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAU,SAAQ,KAAK;IACf;IAAnB,YAAmB,IAAY,EAAE,OAAe;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QADE,SAAI,GAAJ,IAAI,CAAQ;QAE7B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAC5B,IAAI,SAAS,CACX,YAAY,EACZ,gEAAgE,CACjE,CAAC;AAEJ,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAC5B,IAAI,SAAS,CACX,YAAY,EACZ,yFAAyF,CAC1F,CAAC;AAEJ,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CACjC,IAAI,SAAS,CACX,iBAAiB,EACjB,2EAA2E,CAC5E,CAAC"}
|