@monoes/monobrowse 1.0.7 → 1.0.9
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/LICENSE +191 -0
- package/README.md +0 -0
- package/dist/src/__tests__/close-browser.test.js +78 -4
- package/dist/src/__tests__/close-browser.test.js.map +1 -1
- package/dist/src/__tests__/open-url-navigate-error.test.d.ts +2 -0
- package/dist/src/__tests__/open-url-navigate-error.test.d.ts.map +1 -0
- package/dist/src/__tests__/open-url-navigate-error.test.js +48 -0
- package/dist/src/__tests__/open-url-navigate-error.test.js.map +1 -0
- package/dist/src/browser/browser.d.ts +9 -0
- package/dist/src/browser/browser.d.ts.map +1 -1
- package/dist/src/browser/browser.js +51 -10
- package/dist/src/browser/browser.js.map +1 -1
- package/dist/src/browser/dashboard/ui.html +0 -0
- package/dist/src/cli.js +0 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -10
- package/src/__tests__/adapters.test.ts +0 -0
- package/src/__tests__/batch-eval-parsing.test.ts +0 -0
- package/src/__tests__/box-model.test.ts +0 -0
- package/src/__tests__/browser-launch.test.ts +0 -0
- package/src/__tests__/cdp-client.test.ts +0 -0
- package/src/__tests__/close-browser.test.ts +83 -4
- package/src/__tests__/console-log.test.ts +0 -0
- package/src/__tests__/find.test.ts +0 -0
- package/src/__tests__/frame-command.test.ts +0 -0
- package/src/__tests__/open-url-navigate-error.test.ts +58 -0
- package/src/__tests__/output.test.ts +0 -0
- package/src/__tests__/ref-cache.test.ts +0 -0
- package/src/__tests__/session-state.test.ts +0 -0
- package/src/__tests__/snapshot.test.ts +0 -0
- package/src/__tests__/storage-eval.test.ts +0 -0
- package/src/__tests__/tabs.test.ts +0 -0
- package/src/browser/action-builder/analyzer.ts +0 -0
- package/src/browser/action-builder/types.ts +0 -0
- package/src/browser/actions.ts +0 -0
- package/src/browser/adapters/gemini.ts +0 -0
- package/src/browser/adapters/google.ts +0 -0
- package/src/browser/adapters/index.ts +0 -0
- package/src/browser/adapters/instagram.ts +0 -0
- package/src/browser/adapters/linkedin.ts +0 -0
- package/src/browser/adapters/microsoft.ts +0 -0
- package/src/browser/adapters/x.ts +0 -0
- package/src/browser/batch.ts +0 -0
- package/src/browser/browser.ts +48 -10
- package/src/browser/cdp.ts +0 -0
- package/src/browser/console-log.ts +0 -0
- package/src/browser/dashboard/api-types.ts +0 -0
- package/src/browser/dashboard/server.ts +0 -0
- package/src/browser/dashboard/ui.html +0 -0
- package/src/browser/dialog.ts +0 -0
- package/src/browser/emulation.ts +0 -0
- package/src/browser/find.ts +0 -0
- package/src/browser/har.ts +0 -0
- package/src/browser/index.ts +0 -0
- package/src/browser/network.ts +0 -0
- package/src/browser/pdf.ts +0 -0
- package/src/browser/profiler.ts +0 -0
- package/src/browser/record.ts +0 -0
- package/src/browser/ref-cache.ts +0 -0
- package/src/browser/screenshot.ts +0 -0
- package/src/browser/session.ts +0 -0
- package/src/browser/snapshot.ts +0 -0
- package/src/browser/storage.ts +0 -0
- package/src/browser/tabs.ts +0 -0
- package/src/browser/trace.ts +0 -0
- package/src/browser/vitals.ts +0 -0
- package/src/browser/wait.ts +0 -0
- package/src/cli/action.ts +0 -0
- package/src/cli/commands.ts +0 -0
- package/src/cli/output.ts +0 -0
- package/src/cli/platform.ts +0 -0
- package/src/cli/types.ts +0 -0
- package/src/cli.ts +0 -0
- package/src/index.ts +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monobrowse",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Native browser automation via Chrome DevTools Protocol
|
|
3
|
+
"version": "1.0.9",
|
|
4
|
+
"description": "Native browser automation via Chrome DevTools Protocol — the engine powering monomind browse",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"monobrowse": "./dist/src/cli.js"
|
|
@@ -33,13 +33,6 @@
|
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=18.0.0"
|
|
35
35
|
},
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "tsc && node ../../../scripts/build-fs.mjs copy-into dist/src/browser/dashboard src/browser/dashboard/ui.html",
|
|
38
|
-
"test": "vitest run",
|
|
39
|
-
"test:coverage": "vitest run --coverage",
|
|
40
|
-
"prebuild": "node ../../../scripts/build-fs.mjs clean dist tsconfig.tsbuildinfo",
|
|
41
|
-
"prepublishOnly": "npm run build"
|
|
42
|
-
},
|
|
43
36
|
"keywords": [
|
|
44
37
|
"browser-automation",
|
|
45
38
|
"cdp",
|
|
@@ -66,5 +59,11 @@
|
|
|
66
59
|
"devDependencies": {
|
|
67
60
|
"typescript": "^7.0.2",
|
|
68
61
|
"vitest": "^4.1.4"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsc && node ../../../scripts/build-fs.mjs copy-into dist/src/browser/dashboard src/browser/dashboard/ui.html",
|
|
65
|
+
"test": "vitest run",
|
|
66
|
+
"test:coverage": "vitest run --coverage",
|
|
67
|
+
"prebuild": "node ../../../scripts/build-fs.mjs clean dist tsconfig.tsbuildinfo"
|
|
69
68
|
}
|
|
70
|
-
}
|
|
69
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -30,10 +30,15 @@ class FakeWs {
|
|
|
30
30
|
emit(event: string, ...args: unknown[]): void {
|
|
31
31
|
for (const fn of [...(this.handlers.get(event) ?? [])]) fn(...args);
|
|
32
32
|
}
|
|
33
|
-
send(
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
/** When true, send() acknowledges the CDP command by delivering a matching
|
|
34
|
+
* empty result — the GRACEFUL path. Default false leaves it hanging so
|
|
35
|
+
* closeBrowser's own BROWSER_CLOSE_TIMEOUT_MS race settles it (ungraceful). */
|
|
36
|
+
autoAck = false;
|
|
37
|
+
send(data: string, cb?: (err?: Error) => void): void {
|
|
36
38
|
void cb;
|
|
39
|
+
if (!this.autoAck) return;
|
|
40
|
+
const { id } = JSON.parse(data) as { id: number };
|
|
41
|
+
queueMicrotask(() => this.deliver({ id, result: {} }));
|
|
37
42
|
}
|
|
38
43
|
close(): void {}
|
|
39
44
|
deliver(msg: unknown): void {
|
|
@@ -47,6 +52,10 @@ let tempDir: string;
|
|
|
47
52
|
let killSpy: ReturnType<typeof vi.spyOn>;
|
|
48
53
|
|
|
49
54
|
beforeEach(async () => {
|
|
55
|
+
// Clean env vars that can interfere with timer behavior in test environment
|
|
56
|
+
delete process.env.MONOMIND_SDK_AGENT;
|
|
57
|
+
delete process.env.MONOMIND_HOOK_QUIET;
|
|
58
|
+
|
|
50
59
|
vi.useFakeTimers();
|
|
51
60
|
lastSocket = null;
|
|
52
61
|
tempDir = await mkdtemp(join(tmpdir(), 'monobrowse-close-test-'));
|
|
@@ -66,11 +75,12 @@ async function writePersistedPort(port: number, pid: number, savedAt: number): P
|
|
|
66
75
|
await writeFile(join(dir, 'active-port.json'), JSON.stringify({ port, pid, launched: true, savedAt }), 'utf-8');
|
|
67
76
|
}
|
|
68
77
|
|
|
69
|
-
async function connectedClient() {
|
|
78
|
+
async function connectedClient(autoAck = false) {
|
|
70
79
|
vi.resetModules();
|
|
71
80
|
const { CdpClient } = await import('../browser/cdp.js');
|
|
72
81
|
const client = new CdpClient();
|
|
73
82
|
const p = client.connect('ws://127.0.0.1:9333/devtools/page/ABC');
|
|
83
|
+
lastSocket!.autoAck = autoAck;
|
|
74
84
|
lastSocket!.emit('open');
|
|
75
85
|
await p;
|
|
76
86
|
return client;
|
|
@@ -128,6 +138,75 @@ describe('#115 review follow-up: closeBrowser() cross-process PID-kill fallback'
|
|
|
128
138
|
expect(killSpy).not.toHaveBeenCalledWith(11111, 'SIGKILL');
|
|
129
139
|
});
|
|
130
140
|
|
|
141
|
+
// The graceful path is what the monodesign detection driver actually takes,
|
|
142
|
+
// and it had no coverage: closeBrowser used to return on the Browser.close
|
|
143
|
+
// ack while Chrome was still exiting, holding its CDP port and its profile's
|
|
144
|
+
// singleton lock, with an unref'd 1s timer as the only force-kill (which
|
|
145
|
+
// never fired at all if the caller's process exited first).
|
|
146
|
+
it('graceful close waits for the process to actually exit, without killing it', async () => {
|
|
147
|
+
vi.resetModules();
|
|
148
|
+
const { closeBrowser } = await import('../browser/browser.js');
|
|
149
|
+
const port = 9337;
|
|
150
|
+
await writePersistedPort(port, 22222, Date.now());
|
|
151
|
+
|
|
152
|
+
let alive = true;
|
|
153
|
+
killSpy.mockImplementation((_pid: unknown, signal?: unknown) => {
|
|
154
|
+
if (signal === 0 && !alive) throw Object.assign(new Error('ESRCH'), { code: 'ESRCH' });
|
|
155
|
+
return true as never;
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const client = await connectedClient(true);
|
|
159
|
+
const closePromise = closeBrowser(client, port);
|
|
160
|
+
// Still running a moment after the ack — close() must NOT have resolved.
|
|
161
|
+
await vi.advanceTimersByTimeAsync(200);
|
|
162
|
+
let settled = false;
|
|
163
|
+
void closePromise.then(() => {
|
|
164
|
+
settled = true;
|
|
165
|
+
});
|
|
166
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
167
|
+
expect(settled).toBe(false);
|
|
168
|
+
|
|
169
|
+
alive = false; // Chrome finishes exiting
|
|
170
|
+
await vi.advanceTimersByTimeAsync(200);
|
|
171
|
+
await closePromise;
|
|
172
|
+
expect(killSpy).not.toHaveBeenCalledWith(22222, 'SIGKILL');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('graceful close force-kills a process that never exits', async () => {
|
|
176
|
+
vi.resetModules();
|
|
177
|
+
const { closeBrowser } = await import('../browser/browser.js');
|
|
178
|
+
const port = 9338;
|
|
179
|
+
await writePersistedPort(port, 33333, Date.now());
|
|
180
|
+
|
|
181
|
+
const client = await connectedClient(true);
|
|
182
|
+
const closePromise = closeBrowser(client, port);
|
|
183
|
+
// The exit poll schedules one timer per tick, each from the previous
|
|
184
|
+
// tick's callback. How far a single advance carries through a chain like
|
|
185
|
+
// that is a fake-timer implementation detail that differs by Node version
|
|
186
|
+
// (runAllTimersAsync hung this test on Node 22 while passing on 26), so
|
|
187
|
+
// step the clock until the promise settles instead of assuming.
|
|
188
|
+
//
|
|
189
|
+
// Each `advanceTimersByTimeAsync` call has real (non-fake) overhead of
|
|
190
|
+
// its own — a previous fix here just raised the iteration count at a
|
|
191
|
+
// fixed 100ms step (100ms x 600 = enough fake-time headroom, but up to
|
|
192
|
+
// 600 real await round-trips), which still intermittently timed out on a
|
|
193
|
+
// slow/busy CI runner because that overhead is per CALL, not per fake-ms
|
|
194
|
+
// advanced. Stepping by a much larger 2000ms per call reaches the same
|
|
195
|
+
// (and greater) fake-time coverage in a fraction of the calls — the exit
|
|
196
|
+
// poll's PROCESS_EXIT_TIMEOUT_MS deadline (5000ms) is comfortably inside
|
|
197
|
+
// even a handful of iterations — without giving up the settle-and-stop
|
|
198
|
+
// loop that avoids the Node 22 hang a single unbounded advance hit.
|
|
199
|
+
let settled = false;
|
|
200
|
+
void closePromise.then(() => {
|
|
201
|
+
settled = true;
|
|
202
|
+
});
|
|
203
|
+
for (let i = 0; i < 60 && !settled; i++) await vi.advanceTimersByTimeAsync(2000);
|
|
204
|
+
await closePromise;
|
|
205
|
+
|
|
206
|
+
expect(settled).toBe(true);
|
|
207
|
+
expect(killSpy).toHaveBeenCalledWith(33333, 'SIGKILL');
|
|
208
|
+
}, 20_000);
|
|
209
|
+
|
|
131
210
|
it('no persisted port file at all — closeBrowser is a no-op, no kill attempted', async () => {
|
|
132
211
|
vi.resetModules();
|
|
133
212
|
const { closeBrowser } = await import('../browser/browser.js');
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openUrl() (browser.ts) previously ignored Page.navigate's own response and
|
|
3
|
+
* always fell through to waitForNetworkIdle, so a protocol-level navigation
|
|
4
|
+
* failure (e.g. a refused connection) settled on the chrome-error://
|
|
5
|
+
* chromewebdata/ page and `browse open` reported success with exit 0. CDP's
|
|
6
|
+
* Page.navigate response carries errorText when navigation itself failed —
|
|
7
|
+
* this checks that response before doing anything else.
|
|
8
|
+
*/
|
|
9
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
10
|
+
import type { CdpClient } from '../browser/cdp.js';
|
|
11
|
+
import { openUrl } from '../browser/browser.js';
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
vi.restoreAllMocks();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/** Client stub that records calls and answers from a per-method table. */
|
|
18
|
+
function stubClient(table: Record<string, unknown> = {}): {
|
|
19
|
+
client: CdpClient;
|
|
20
|
+
calls: Array<{ method: string; params: unknown }>;
|
|
21
|
+
} {
|
|
22
|
+
const calls: Array<{ method: string; params: unknown }> = [];
|
|
23
|
+
const client = {
|
|
24
|
+
send: vi.fn(async (method: string, params: unknown) => {
|
|
25
|
+
calls.push({ method, params });
|
|
26
|
+
const entry = table[method];
|
|
27
|
+
if (entry instanceof Error) throw entry;
|
|
28
|
+
return entry ?? {};
|
|
29
|
+
}),
|
|
30
|
+
on: vi.fn(() => {
|
|
31
|
+
throw new Error('waitForNetworkIdle should not run once Page.navigate reports errorText');
|
|
32
|
+
}),
|
|
33
|
+
} as unknown as CdpClient;
|
|
34
|
+
return { client, calls };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe('openUrl navigation-failure detection', () => {
|
|
38
|
+
it('throws when Page.navigate reports errorText, without waiting for network idle', async () => {
|
|
39
|
+
const { client, calls } = stubClient({
|
|
40
|
+
'Page.navigate': { frameId: 'f1', errorText: 'net::ERR_CONNECTION_REFUSED' },
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await expect(openUrl(client, 'sess-1', 'http://127.0.0.1:1/')).rejects.toThrow(
|
|
44
|
+
/net::ERR_CONNECTION_REFUSED/,
|
|
45
|
+
);
|
|
46
|
+
expect(calls).toEqual([
|
|
47
|
+
{ method: 'Page.navigate', params: { url: 'http://127.0.0.1:1/' } },
|
|
48
|
+
]);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('rejects the 2 MB URL guard before ever calling Page.navigate', async () => {
|
|
52
|
+
const { client, calls } = stubClient();
|
|
53
|
+
const hugeUrl = `http://x/${'a'.repeat(2_097_152)}`;
|
|
54
|
+
|
|
55
|
+
await expect(openUrl(client, 'sess-1', hugeUrl)).rejects.toThrow(/2 MB/);
|
|
56
|
+
expect(calls).toHaveLength(0);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/browser/actions.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/browser/batch.ts
CHANGED
|
File without changes
|
package/src/browser/browser.ts
CHANGED
|
@@ -14,6 +14,11 @@ const DEFAULT_PORT = 9222;
|
|
|
14
14
|
const LAUNCH_TIMEOUT = 10_000;
|
|
15
15
|
const POLL_INTERVAL = 200;
|
|
16
16
|
const BROWSER_CLOSE_TIMEOUT_MS = 3000;
|
|
17
|
+
// How long closeBrowser() waits for the process to actually disappear before
|
|
18
|
+
// forcing it, and again after forcing. Bounded so a wedged Chrome cannot hang
|
|
19
|
+
// a caller indefinitely.
|
|
20
|
+
const PROCESS_EXIT_TIMEOUT_MS = 5000;
|
|
21
|
+
const PROCESS_EXIT_POLL_MS = 50;
|
|
17
22
|
// A cross-process persisted PID older than this is not trusted for the
|
|
18
23
|
// SIGKILL fallback in closeBrowser() — see the call site for why.
|
|
19
24
|
const PERSISTED_PID_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
@@ -79,7 +84,10 @@ async function isChromeIdentity(port: number): Promise<boolean> {
|
|
|
79
84
|
const res = await fetch(`http://127.0.0.1:${port}/json/version`, { signal: AbortSignal.timeout(1000) });
|
|
80
85
|
if (!res.ok) return false;
|
|
81
86
|
const info = (await res.json()) as { Browser?: string };
|
|
82
|
-
|
|
87
|
+
// Edge's Browser field is "Edg/<version>" with no "chrome"/"chromium"
|
|
88
|
+
// substring, even though it's Chromium-based and CDP-compatible —
|
|
89
|
+
// accept it alongside Chrome/Chromium rather than rejecting a valid target.
|
|
90
|
+
return typeof info.Browser === 'string' && /chrom(e|ium)|edg/i.test(info.Browser);
|
|
83
91
|
} catch {
|
|
84
92
|
return false;
|
|
85
93
|
}
|
|
@@ -282,6 +290,15 @@ export async function connectToTarget(port: number, targetId?: string): Promise<
|
|
|
282
290
|
* falls back to killing the tracked PID directly so a headed/interactive
|
|
283
291
|
* browser window (e.g. one spawned for a login/CAPTCHA flow) never lingers
|
|
284
292
|
* as a visible, authenticated, still-debuggable orphan process.
|
|
293
|
+
*
|
|
294
|
+
* On the graceful path this resolves only once the process is actually gone,
|
|
295
|
+
* or after force-killing it when it outlasts PROCESS_EXIT_TIMEOUT_MS. Chrome
|
|
296
|
+
* acknowledges `Browser.close` well before it exits, and this used to return
|
|
297
|
+
* on the ack with an unref'd 1s timer as the only force-kill — so it resolved
|
|
298
|
+
* while Chrome was still running and holding its port and its profile's
|
|
299
|
+
* singleton lock, and if the caller's process exited first the kill never
|
|
300
|
+
* happened at all. Callers reasonably read a resolved close() as "that
|
|
301
|
+
* browser is gone"; on the graceful path it now means that.
|
|
285
302
|
*/
|
|
286
303
|
export async function closeBrowser(client: CdpClient, port: number): Promise<void> {
|
|
287
304
|
let gracefullyClosed = false;
|
|
@@ -338,23 +355,44 @@ export async function closeBrowser(client: CdpClient, port: number): Promise<voi
|
|
|
338
355
|
return;
|
|
339
356
|
}
|
|
340
357
|
|
|
341
|
-
// Browser.close was acknowledged —
|
|
342
|
-
//
|
|
343
|
-
|
|
358
|
+
// Browser.close was acknowledged — wait for the process to actually go away,
|
|
359
|
+
// then force-kill as a safety net in case it hung.
|
|
360
|
+
if (await waitForProcessExit(pid)) return;
|
|
361
|
+
try {
|
|
362
|
+
process.kill(pid, 'SIGKILL');
|
|
363
|
+
} catch {
|
|
364
|
+
/* raced us to exit — expected */
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/** Poll until `pid` is gone or PROCESS_EXIT_TIMEOUT_MS elapses. Returns
|
|
369
|
+
* whether it exited. `process.kill(pid, 0)` throws once the process is no
|
|
370
|
+
* longer there, on Windows as well as POSIX. */
|
|
371
|
+
async function waitForProcessExit(pid: number): Promise<boolean> {
|
|
372
|
+
const deadline = Date.now() + PROCESS_EXIT_TIMEOUT_MS;
|
|
373
|
+
for (;;) {
|
|
344
374
|
try {
|
|
345
|
-
process.kill(pid, 0);
|
|
346
|
-
process.kill(pid, 'SIGKILL');
|
|
375
|
+
process.kill(pid, 0);
|
|
347
376
|
} catch {
|
|
348
|
-
|
|
377
|
+
return true;
|
|
349
378
|
}
|
|
350
|
-
|
|
351
|
-
|
|
379
|
+
if (Date.now() >= deadline) return false;
|
|
380
|
+
await new Promise((resolve) => {
|
|
381
|
+
const t = setTimeout(resolve, PROCESS_EXIT_POLL_MS);
|
|
382
|
+
t.unref?.();
|
|
383
|
+
});
|
|
384
|
+
}
|
|
352
385
|
}
|
|
353
386
|
|
|
354
387
|
export async function openUrl(client: CdpClient, sessionId: string, url: string): Promise<void> {
|
|
355
388
|
// Cap to 2 MB to prevent OOM in CDP message serializer (e.g. data: URI attacks)
|
|
356
389
|
if (url.length > 2_097_152) throw new Error('URL exceeds 2 MB limit');
|
|
357
|
-
|
|
390
|
+
// Page.navigate reports a protocol-level failure (e.g. a refused connection)
|
|
391
|
+
// via errorText in its own response, before Chrome ever settles on the
|
|
392
|
+
// chrome-error://chromewebdata/ page — without this check a refused
|
|
393
|
+
// connection previously reported success against that error page.
|
|
394
|
+
const nav = await client.send<{ errorText?: string }>('Page.navigate', { url }, sessionId);
|
|
395
|
+
if (nav.errorText) throw new Error(`Navigation to ${url} failed: ${nav.errorText}`);
|
|
358
396
|
await waitForNetworkIdle(client, sessionId, 500, 30_000);
|
|
359
397
|
}
|
|
360
398
|
|
package/src/browser/cdp.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/browser/dialog.ts
CHANGED
|
File without changes
|
package/src/browser/emulation.ts
CHANGED
|
File without changes
|
package/src/browser/find.ts
CHANGED
|
File without changes
|
package/src/browser/har.ts
CHANGED
|
File without changes
|
package/src/browser/index.ts
CHANGED
|
File without changes
|
package/src/browser/network.ts
CHANGED
|
File without changes
|
package/src/browser/pdf.ts
CHANGED
|
File without changes
|
package/src/browser/profiler.ts
CHANGED
|
File without changes
|
package/src/browser/record.ts
CHANGED
|
File without changes
|
package/src/browser/ref-cache.ts
CHANGED
|
File without changes
|
|
File without changes
|
package/src/browser/session.ts
CHANGED
|
File without changes
|
package/src/browser/snapshot.ts
CHANGED
|
File without changes
|
package/src/browser/storage.ts
CHANGED
|
File without changes
|
package/src/browser/tabs.ts
CHANGED
|
File without changes
|
package/src/browser/trace.ts
CHANGED
|
File without changes
|
package/src/browser/vitals.ts
CHANGED
|
File without changes
|
package/src/browser/wait.ts
CHANGED
|
File without changes
|
package/src/cli/action.ts
CHANGED
|
File without changes
|
package/src/cli/commands.ts
CHANGED
|
File without changes
|
package/src/cli/output.ts
CHANGED
|
File without changes
|
package/src/cli/platform.ts
CHANGED
|
File without changes
|
package/src/cli/types.ts
CHANGED
|
File without changes
|
package/src/cli.ts
CHANGED
|
File without changes
|
package/src/index.ts
CHANGED
|
File without changes
|