@monoes/monobrowse 1.0.17 → 1.0.21
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/dist/src/__tests__/browse-concurrency.test.d.ts +15 -0
- package/dist/src/__tests__/browse-concurrency.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-concurrency.test.js +198 -0
- package/dist/src/__tests__/browse-concurrency.test.js.map +1 -0
- package/dist/src/__tests__/browser-launch.test.js +132 -1
- package/dist/src/__tests__/browser-launch.test.js.map +1 -1
- package/dist/src/__tests__/close-browser.test.js +2 -2
- package/dist/src/__tests__/close-browser.test.js.map +1 -1
- package/dist/src/__tests__/frame-command.test.js +12 -2
- package/dist/src/__tests__/frame-command.test.js.map +1 -1
- package/dist/src/__tests__/reap-idle-browser.test.js +13 -13
- package/dist/src/__tests__/reap-idle-browser.test.js.map +1 -1
- package/dist/src/__tests__/ref-cache.test.js +96 -58
- package/dist/src/__tests__/ref-cache.test.js.map +1 -1
- package/dist/src/__tests__/report-exit-code.test.js +1 -1
- package/dist/src/__tests__/session-discovery.test.d.ts +13 -0
- package/dist/src/__tests__/session-discovery.test.d.ts.map +1 -0
- package/dist/src/__tests__/session-discovery.test.js +218 -0
- package/dist/src/__tests__/session-discovery.test.js.map +1 -0
- package/dist/src/browser/browser.d.ts +2 -1
- package/dist/src/browser/browser.d.ts.map +1 -1
- package/dist/src/browser/browser.js +145 -42
- package/dist/src/browser/browser.js.map +1 -1
- package/dist/src/browser/ref-cache.d.ts +50 -22
- package/dist/src/browser/ref-cache.d.ts.map +1 -1
- package/dist/src/browser/ref-cache.js +122 -57
- package/dist/src/browser/ref-cache.js.map +1 -1
- package/dist/src/browser/types.d.ts +2 -0
- package/dist/src/browser/types.d.ts.map +1 -1
- package/dist/src/browser/types.js.map +1 -1
- package/dist/src/cli/commands-context.js +1 -1
- package/dist/src/cli/commands-context.js.map +1 -1
- package/dist/src/cli/commands-navigate.js +2 -2
- package/dist/src/cli/commands-navigate.js.map +1 -1
- package/dist/src/cli/commands-page.js +2 -2
- package/dist/src/cli/commands-page.js.map +1 -1
- package/dist/src/cli/commands-report.js +2 -2
- package/dist/src/cli/commands-report.js.map +1 -1
- package/dist/src/cli/commands-session.d.ts.map +1 -1
- package/dist/src/cli/commands-session.js +70 -56
- package/dist/src/cli/commands-session.js.map +1 -1
- package/dist/src/cli/commands.d.ts.map +1 -1
- package/dist/src/cli/commands.js +102 -66
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/session.d.ts +66 -2
- package/dist/src/cli/session.d.ts.map +1 -1
- package/dist/src/cli/session.js +190 -33
- package/dist/src/cli/session.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/__tests__/browse-concurrency.test.ts +233 -0
- package/src/__tests__/browser-launch.test.ts +142 -1
- package/src/__tests__/close-browser.test.ts +2 -2
- package/src/__tests__/frame-command.test.ts +12 -2
- package/src/__tests__/reap-idle-browser.test.ts +15 -14
- package/src/__tests__/ref-cache.test.ts +112 -59
- package/src/__tests__/report-exit-code.test.ts +1 -1
- package/src/__tests__/session-discovery.test.ts +259 -0
- package/src/browser/browser.ts +149 -39
- package/src/browser/ref-cache.ts +144 -72
- package/src/browser/types.ts +2 -0
- package/src/cli/commands-context.ts +1 -1
- package/src/cli/commands-navigate.ts +2 -2
- package/src/cli/commands-page.ts +2 -2
- package/src/cli/commands-report.ts +2 -2
- package/src/cli/commands-session.ts +74 -55
- package/src/cli/commands.ts +106 -66
- package/src/cli/session.ts +208 -33
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #318: two uncoordinated `browse open` invocations with no `--port` raced on
|
|
3
|
+
* the shared default CDP port (9222) and the userDataDir derived from it —
|
|
4
|
+
* one failed outright ("Chrome exited before the CDP endpoint opened on port
|
|
5
|
+
* 9222"), or both attached to ONE Chrome and a single `browse close` killed
|
|
6
|
+
* the other caller's browser too.
|
|
7
|
+
*
|
|
8
|
+
* This is a real-process test on purpose: the bug lives in the interaction
|
|
9
|
+
* between two separate CLI processes and the session state they share on
|
|
10
|
+
* disk, which no in-process unit test can reproduce. It spawns the built CLI
|
|
11
|
+
* (dist/src/cli.js) against a file:// fixture page, so it is skipped when the
|
|
12
|
+
* package has not been built or no Chrome/Chromium is installed.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=browse-concurrency.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browse-concurrency.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-concurrency.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #318: two uncoordinated `browse open` invocations with no `--port` raced on
|
|
3
|
+
* the shared default CDP port (9222) and the userDataDir derived from it —
|
|
4
|
+
* one failed outright ("Chrome exited before the CDP endpoint opened on port
|
|
5
|
+
* 9222"), or both attached to ONE Chrome and a single `browse close` killed
|
|
6
|
+
* the other caller's browser too.
|
|
7
|
+
*
|
|
8
|
+
* This is a real-process test on purpose: the bug lives in the interaction
|
|
9
|
+
* between two separate CLI processes and the session state they share on
|
|
10
|
+
* disk, which no in-process unit test can reproduce. It spawns the built CLI
|
|
11
|
+
* (dist/src/cli.js) against a file:// fixture page, so it is skipped when the
|
|
12
|
+
* package has not been built or no Chrome/Chromium is installed.
|
|
13
|
+
*/
|
|
14
|
+
import { execFile, execFileSync, spawn } from 'node:child_process';
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
17
|
+
import { tmpdir } from 'node:os';
|
|
18
|
+
import { dirname, join } from 'node:path';
|
|
19
|
+
import { fileURLToPath } from 'node:url';
|
|
20
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
21
|
+
import { CHROME_EXECUTABLES } from '../browser/types.js';
|
|
22
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const CLI = join(here, '..', '..', 'dist', 'src', 'cli.js');
|
|
24
|
+
function chromeAvailable() {
|
|
25
|
+
if (CHROME_EXECUTABLES.some((p) => existsSync(p)))
|
|
26
|
+
return true;
|
|
27
|
+
try {
|
|
28
|
+
return (execFileSync('which', ['google-chrome', 'chromium-browser', 'chromium'], {
|
|
29
|
+
encoding: 'utf8',
|
|
30
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
31
|
+
}).trim().length > 0);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const runnable = existsSync(CLI) && chromeAvailable();
|
|
38
|
+
function runCli(args, cwd, profileRoot) {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
const child = spawn(process.execPath, [CLI, ...args], {
|
|
41
|
+
cwd,
|
|
42
|
+
// Per-trial TMPDIR: every browser profile this invocation creates lands
|
|
43
|
+
// under it, so the sweep in afterEach can identify (and only kill) the
|
|
44
|
+
// Chrome processes this test started.
|
|
45
|
+
env: { ...process.env, TMPDIR: profileRoot, CI: '1' },
|
|
46
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
47
|
+
});
|
|
48
|
+
let stdout = '';
|
|
49
|
+
let stderr = '';
|
|
50
|
+
child.stdout.on('data', (d) => {
|
|
51
|
+
stdout += d;
|
|
52
|
+
});
|
|
53
|
+
child.stderr.on('data', (d) => {
|
|
54
|
+
stderr += d;
|
|
55
|
+
});
|
|
56
|
+
child.on('close', (code) => resolve({ code, stdout, stderr }));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** The CDP port `open` reports for the session it started. */
|
|
60
|
+
function reportedPort(run) {
|
|
61
|
+
const m = /\[port (\d+)\]/.exec(run.stdout);
|
|
62
|
+
return m ? Number(m[1]) : null;
|
|
63
|
+
}
|
|
64
|
+
async function cdpAlive(port) {
|
|
65
|
+
try {
|
|
66
|
+
const res = await fetch(`http://127.0.0.1:${port}/json/version`, {
|
|
67
|
+
signal: AbortSignal.timeout(1500),
|
|
68
|
+
});
|
|
69
|
+
return res.ok;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const dirs = [];
|
|
76
|
+
afterEach(async () => {
|
|
77
|
+
for (const dir of dirs.splice(0)) {
|
|
78
|
+
// Kill anything still running out of this trial's profile root before the
|
|
79
|
+
// directory goes away — a leaked Chrome would otherwise outlive the run.
|
|
80
|
+
await new Promise((resolve) => {
|
|
81
|
+
execFile('pkill', ['-f', dir], () => resolve());
|
|
82
|
+
});
|
|
83
|
+
// A killed Chrome keeps writing out its profile for a moment; retry the
|
|
84
|
+
// removal instead of failing the test on ENOTEMPTY.
|
|
85
|
+
await rm(dir, { recursive: true, force: true, maxRetries: 10, retryDelay: 200 });
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
describe.skipIf(!runnable)('#318 concurrent browse sessions (real processes)', () => {
|
|
89
|
+
for (const trial of [1, 2, 3, 4, 5]) {
|
|
90
|
+
it(`trial ${trial}: two bare \`open\` calls each get their own browser, and each close kills only its own`, async () => {
|
|
91
|
+
const root = await mkdtemp(join(process.env.TMPDIR ?? tmpdir(), 'monobrowse-318-'));
|
|
92
|
+
dirs.push(root);
|
|
93
|
+
const page = join(root, 'fixture.html');
|
|
94
|
+
await writeFile(page, '<!doctype html><title>Fixture</title><h1>hello</h1>');
|
|
95
|
+
const url = `file://${page}`;
|
|
96
|
+
// The reported race: two uncoordinated invocations, same cwd, no --port.
|
|
97
|
+
const [a, b] = await Promise.all([
|
|
98
|
+
runCli(['open', url], root, root),
|
|
99
|
+
runCli(['open', url], root, root),
|
|
100
|
+
]);
|
|
101
|
+
expect(a.code, `open A failed: ${a.stdout}${a.stderr}`).toBe(0);
|
|
102
|
+
expect(b.code, `open B failed: ${b.stdout}${b.stderr}`).toBe(0);
|
|
103
|
+
const portA = reportedPort(a);
|
|
104
|
+
const portB = reportedPort(b);
|
|
105
|
+
expect(portA, `open A did not report a session port: ${a.stdout}`).not.toBeNull();
|
|
106
|
+
expect(portB, `open B did not report a session port: ${b.stdout}`).not.toBeNull();
|
|
107
|
+
expect(portA).not.toBe(portB);
|
|
108
|
+
expect(await cdpAlive(portA)).toBe(true);
|
|
109
|
+
expect(await cdpAlive(portB)).toBe(true);
|
|
110
|
+
// Closing A must leave B's browser running.
|
|
111
|
+
const closeA = await runCli(['close', '--port', String(portA)], root, root);
|
|
112
|
+
expect(closeA.code, `close A failed: ${closeA.stdout}${closeA.stderr}`).toBe(0);
|
|
113
|
+
expect(await cdpAlive(portA)).toBe(false);
|
|
114
|
+
expect(await cdpAlive(portB)).toBe(true);
|
|
115
|
+
const closeB = await runCli(['close', '--port', String(portB)], root, root);
|
|
116
|
+
expect(closeB.code, `close B failed: ${closeB.stdout}${closeB.stderr}`).toBe(0);
|
|
117
|
+
expect(await cdpAlive(portB)).toBe(false);
|
|
118
|
+
}, 90_000);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* Upgrading monobrowse while a session was open used to strand its Chrome:
|
|
123
|
+
* the handle lived in `active-port.json`, which the per-port store replaced.
|
|
124
|
+
* The new CLI adopts that record instead — the same real-process shape as
|
|
125
|
+
* above, since the whole point is what a *later* process can still do.
|
|
126
|
+
*/
|
|
127
|
+
describe.skipIf(!runnable)('#318 adoption of a pre-#318 session (real processes)', () => {
|
|
128
|
+
/** Open a session, then rewrite its state as a pre-#318 install left it. */
|
|
129
|
+
async function openThenDowngradeState(root, url) {
|
|
130
|
+
const opened = await runCli(['open', url], root, root);
|
|
131
|
+
expect(opened.code, `open failed: ${opened.stdout}${opened.stderr}`).toBe(0);
|
|
132
|
+
const port = reportedPort(opened);
|
|
133
|
+
expect(port).not.toBeNull();
|
|
134
|
+
const stateDir = join(root, '.monomind', 'monobrowse');
|
|
135
|
+
const record = await readFile(join(stateDir, 'sessions', `${port}.json`), 'utf8');
|
|
136
|
+
await writeFile(join(stateDir, 'active-port.json'), record);
|
|
137
|
+
await rm(join(stateDir, 'sessions'), { recursive: true, force: true });
|
|
138
|
+
return port;
|
|
139
|
+
}
|
|
140
|
+
it('a later command adopts the legacy session, and close then kills that browser', async () => {
|
|
141
|
+
const root = await mkdtemp(join(process.env.TMPDIR ?? tmpdir(), 'monobrowse-318-legacy-'));
|
|
142
|
+
dirs.push(root);
|
|
143
|
+
const page = join(root, 'fixture.html');
|
|
144
|
+
await writeFile(page, '<!doctype html><title>Fixture</title><h1>hello</h1>');
|
|
145
|
+
const port = await openThenDowngradeState(root, `file://${page}`);
|
|
146
|
+
// A later, separate process with no --port finds it.
|
|
147
|
+
const title = await runCli(['get', 'title'], root, root);
|
|
148
|
+
expect(title.code, `get title failed: ${title.stdout}${title.stderr}`).toBe(0);
|
|
149
|
+
expect(title.stdout).toContain('Fixture');
|
|
150
|
+
// Adopted: it is an ordinary per-port record now, and the old file is gone.
|
|
151
|
+
const stateDir = join(root, '.monomind', 'monobrowse');
|
|
152
|
+
expect(existsSync(join(stateDir, 'sessions', `${port}.json`))).toBe(true);
|
|
153
|
+
expect(existsSync(join(stateDir, 'active-port.json'))).toBe(false);
|
|
154
|
+
// And `--port` works on it exactly like a native session.
|
|
155
|
+
const closed = await runCli(['close', '--port', String(port)], root, root);
|
|
156
|
+
expect(closed.code, `close failed: ${closed.stdout}${closed.stderr}`).toBe(0);
|
|
157
|
+
expect(await cdpAlive(port)).toBe(false);
|
|
158
|
+
}, 90_000);
|
|
159
|
+
it('a legacy record whose browser is gone is cleaned up, and the command still works', async () => {
|
|
160
|
+
const root = await mkdtemp(join(process.env.TMPDIR ?? tmpdir(), 'monobrowse-318-legacy-'));
|
|
161
|
+
dirs.push(root);
|
|
162
|
+
const stateDir = join(root, '.monomind', 'monobrowse');
|
|
163
|
+
await mkdir(stateDir, { recursive: true });
|
|
164
|
+
// A port nothing is listening on — the state an upgrade finds after the
|
|
165
|
+
// old browser died (or was killed) with its record left behind.
|
|
166
|
+
await writeFile(join(stateDir, 'active-port.json'), JSON.stringify({ port: 23499, launched: true, pid: 999999, savedAt: Date.now() }));
|
|
167
|
+
const closed = await runCli(['close'], root, root);
|
|
168
|
+
expect(closed.code, `close failed: ${closed.stdout}${closed.stderr}`).toBe(0);
|
|
169
|
+
expect(closed.stdout).toContain('No active browser session');
|
|
170
|
+
expect(existsSync(join(stateDir, 'active-port.json'))).toBe(false);
|
|
171
|
+
}, 60_000);
|
|
172
|
+
it('adoption does not change bare `open`: it still starts a browser of its own', async () => {
|
|
173
|
+
const root = await mkdtemp(join(process.env.TMPDIR ?? tmpdir(), 'monobrowse-318-legacy-'));
|
|
174
|
+
dirs.push(root);
|
|
175
|
+
const page = join(root, 'fixture.html');
|
|
176
|
+
await writeFile(page, '<!doctype html><title>Fixture</title><h1>hello</h1>');
|
|
177
|
+
const url = `file://${page}`;
|
|
178
|
+
const legacyPort = await openThenDowngradeState(root, url);
|
|
179
|
+
const fresh = await runCli(['open', url], root, root);
|
|
180
|
+
expect(fresh.code, `open failed: ${fresh.stdout}${fresh.stderr}`).toBe(0);
|
|
181
|
+
const freshPort = reportedPort(fresh);
|
|
182
|
+
expect(freshPort).not.toBe(legacyPort);
|
|
183
|
+
// Neither joined nor disturbed: both browsers are up, and the legacy
|
|
184
|
+
// record is still waiting to be adopted by whoever needs it.
|
|
185
|
+
expect(await cdpAlive(legacyPort)).toBe(true);
|
|
186
|
+
expect(await cdpAlive(freshPort)).toBe(true);
|
|
187
|
+
expect(existsSync(join(root, '.monomind', 'monobrowse', 'active-port.json'))).toBe(true);
|
|
188
|
+
// Closing the new session leaves the legacy browser alone; a second
|
|
189
|
+
// close then adopts and ends it.
|
|
190
|
+
const closeFresh = await runCli(['close', '--port', String(freshPort)], root, root);
|
|
191
|
+
expect(closeFresh.code).toBe(0);
|
|
192
|
+
expect(await cdpAlive(legacyPort)).toBe(true);
|
|
193
|
+
const closeLegacy = await runCli(['close'], root, root);
|
|
194
|
+
expect(closeLegacy.code, `close failed: ${closeLegacy.stdout}${closeLegacy.stderr}`).toBe(0);
|
|
195
|
+
expect(await cdpAlive(legacyPort)).toBe(false);
|
|
196
|
+
}, 90_000);
|
|
197
|
+
});
|
|
198
|
+
//# sourceMappingURL=browse-concurrency.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browse-concurrency.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-concurrency.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,10 +8,13 @@
|
|
|
8
8
|
* Fixed port range (23470-23479) chosen to avoid colliding with real
|
|
9
9
|
* services; each test binds/tears down its own listeners.
|
|
10
10
|
*/
|
|
11
|
+
import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
11
12
|
import { createServer as createHttpServer } from 'node:http';
|
|
12
13
|
import { createServer as createTcpServer } from 'node:net';
|
|
14
|
+
import { tmpdir } from 'node:os';
|
|
15
|
+
import { join } from 'node:path';
|
|
13
16
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
14
|
-
import { launchBrowser } from '../browser/browser.js';
|
|
17
|
+
import { getLaunchedPid, getLaunchedUserDataDir, launchBrowser } from '../browser/browser.js';
|
|
15
18
|
const BASE = 23470;
|
|
16
19
|
let servers = [];
|
|
17
20
|
let sockets = [];
|
|
@@ -98,4 +101,132 @@ describe('launchBrowser — port scan/attach decisions', () => {
|
|
|
98
101
|
await expect(launchBrowser({ port })).rejects.toThrow(new RegExp(`Ports ${port}-${port + 9} are all occupied`));
|
|
99
102
|
}, 15000); // generous margin — 10 candidates, each a fast isTcpPortOpen check
|
|
100
103
|
});
|
|
104
|
+
// A stand-in for the Chrome binary: like real Chrome given
|
|
105
|
+
// --remote-debugging-port=0, it binds a kernel-assigned port and only then
|
|
106
|
+
// writes that port to <user-data-dir>/DevToolsActivePort.
|
|
107
|
+
const FAKE_CHROME = `#!/usr/bin/env node
|
|
108
|
+
const { createServer } = require('node:http');
|
|
109
|
+
const { writeFileSync } = require('node:fs');
|
|
110
|
+
const { join } = require('node:path');
|
|
111
|
+
const dir = process.argv.find((a) => a.startsWith('--user-data-dir=')).slice('--user-data-dir='.length);
|
|
112
|
+
const server = createServer((req, res) => {
|
|
113
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
114
|
+
res.end(req.url === '/json/version' ? JSON.stringify({ Browser: 'Chrome/999.0.0.0' }) : '[]');
|
|
115
|
+
});
|
|
116
|
+
// Start slower than launchBrowser's first poll, so a stale file is read first.
|
|
117
|
+
setTimeout(() => server.listen(0, '127.0.0.1', () => {
|
|
118
|
+
writeFileSync(join(dir, 'DevToolsActivePort'), server.address().port + '\\n/devtools/browser/fake');
|
|
119
|
+
}), 600);
|
|
120
|
+
`;
|
|
121
|
+
describe.skipIf(process.platform === 'win32')('launchBrowser — port 0 (Chrome picks the port)', () => {
|
|
122
|
+
it('returns the port its own Chrome reported, never another CDP endpoint', async () => {
|
|
123
|
+
const dir = mkdtempSync(join(tmpdir(), 'monobrowse-port0-'));
|
|
124
|
+
const exe = join(dir, 'fake-chrome.cjs');
|
|
125
|
+
writeFileSync(exe, FAKE_CHROME);
|
|
126
|
+
chmodSync(exe, 0o755);
|
|
127
|
+
const profile = join(dir, 'profile');
|
|
128
|
+
// A Chrome-looking endpoint that is NOT ours, named by a stale
|
|
129
|
+
// DevToolsActivePort left in the profile dir by an earlier run.
|
|
130
|
+
const foreign = BASE + 5;
|
|
131
|
+
const s = createHttpServer((req, res) => {
|
|
132
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
133
|
+
res.end(req.url === '/json/version' ? JSON.stringify({ Browser: 'Chrome/1.0' }) : '[]');
|
|
134
|
+
});
|
|
135
|
+
s.on('connection', (sock) => sockets.push(sock));
|
|
136
|
+
await new Promise((resolve) => s.listen(foreign, '127.0.0.1', () => resolve()));
|
|
137
|
+
servers.push(s);
|
|
138
|
+
mkdirSync(profile);
|
|
139
|
+
writeFileSync(join(profile, 'DevToolsActivePort'), `${foreign}\n/devtools/browser/stale`);
|
|
140
|
+
let port;
|
|
141
|
+
try {
|
|
142
|
+
port = await launchBrowser({ port: 0, userDataDir: profile, executablePath: exe });
|
|
143
|
+
expect(port).not.toBe(foreign);
|
|
144
|
+
expect(port).toBeGreaterThan(0);
|
|
145
|
+
expect(getLaunchedPid(port)).toBeTypeOf('number');
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
const pid = port === undefined ? undefined : getLaunchedPid(port);
|
|
149
|
+
if (pid)
|
|
150
|
+
process.kill(pid, 'SIGKILL');
|
|
151
|
+
rmSync(dir, { recursive: true, force: true });
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
it('refuses port 0 without a dedicated userDataDir', async () => {
|
|
155
|
+
await expect(launchBrowser({ port: 0 })).rejects.toThrow(/requires a dedicated userDataDir/);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
// A stand-in for the Chrome binary that, unlike FAKE_CHROME above, actually
|
|
159
|
+
// binds the FIXED port it is given via --remote-debugging-port (real Chrome,
|
|
160
|
+
// launched with no --port flag, always resolves to the same literal default
|
|
161
|
+
// port too — see cli/commands.ts's `port` option default). If the bind
|
|
162
|
+
// fails (another process already has it), it exits the way real Chrome does
|
|
163
|
+
// when a concurrent launch wins the same "free-looking" port: before its
|
|
164
|
+
// CDP endpoint ever opens.
|
|
165
|
+
const FAKE_CHROME_FIXED_PORT = `#!/usr/bin/env node
|
|
166
|
+
const { createServer } = require('node:http');
|
|
167
|
+
const { writeFileSync, mkdirSync } = require('node:fs');
|
|
168
|
+
const { join } = require('node:path');
|
|
169
|
+
const port = Number(
|
|
170
|
+
process.argv.find((a) => a.startsWith('--remote-debugging-port=')).slice('--remote-debugging-port='.length),
|
|
171
|
+
);
|
|
172
|
+
const dir = process.argv.find((a) => a.startsWith('--user-data-dir=')).slice('--user-data-dir='.length);
|
|
173
|
+
const server = createServer((req, res) => {
|
|
174
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
175
|
+
res.end(req.url === '/json/version' ? JSON.stringify({ Browser: 'Chrome/999.0.0.0' }) : '[]');
|
|
176
|
+
});
|
|
177
|
+
server.on('error', () => {
|
|
178
|
+
process.exit(21);
|
|
179
|
+
});
|
|
180
|
+
server.listen(port, '127.0.0.1', () => {
|
|
181
|
+
mkdirSync(dir, { recursive: true });
|
|
182
|
+
writeFileSync(join(dir, 'DevToolsActivePort'), port + '\\n/devtools/browser/fake');
|
|
183
|
+
});
|
|
184
|
+
`;
|
|
185
|
+
describe.skipIf(process.platform === 'win32')('launchBrowser — concurrent launches with no explicit --port (TOCTOU race)', () => {
|
|
186
|
+
it('two concurrent launches racing for the same default port both succeed, on different ports and profiles', async () => {
|
|
187
|
+
const dir = mkdtempSync(join(tmpdir(), 'monobrowse-concurrent-'));
|
|
188
|
+
const exe = join(dir, 'fake-chrome.cjs');
|
|
189
|
+
writeFileSync(exe, FAKE_CHROME_FIXED_PORT);
|
|
190
|
+
chmodSync(exe, 0o755);
|
|
191
|
+
// Both calls target the SAME literal port on purpose: that is exactly
|
|
192
|
+
// what two real `monomind browse open` invocations with no --port flag
|
|
193
|
+
// do, since the CLI's `port` option always defaults to the same value
|
|
194
|
+
// whether or not the user passed it (cli/commands.ts:288).
|
|
195
|
+
const port = BASE + 10;
|
|
196
|
+
let ports = [];
|
|
197
|
+
try {
|
|
198
|
+
ports = await Promise.all([
|
|
199
|
+
launchBrowser({ port, executablePath: exe, launchTimeoutMs: 5000 }),
|
|
200
|
+
launchBrowser({ port, executablePath: exe, launchTimeoutMs: 5000 }),
|
|
201
|
+
]);
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
for (const p of ports) {
|
|
205
|
+
const pid = getLaunchedPid(p);
|
|
206
|
+
if (pid) {
|
|
207
|
+
try {
|
|
208
|
+
process.kill(pid, 'SIGKILL');
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
/* already gone */
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
rmSync(dir, { recursive: true, force: true });
|
|
216
|
+
}
|
|
217
|
+
expect(ports).toHaveLength(2);
|
|
218
|
+
// The old probe-then-launch race let both calls observe the same
|
|
219
|
+
// candidate as free and spawn Chrome on it — one bind wins, the
|
|
220
|
+
// other's Chrome exits before its CDP endpoint opens and the whole
|
|
221
|
+
// launchBrowser() call rejects. Both resolving at all is the
|
|
222
|
+
// regression check; landing on different ports (rather than one
|
|
223
|
+
// silently adopting the other's browser) proves the scan actually
|
|
224
|
+
// moved on instead of colliding.
|
|
225
|
+
expect(ports[0]).not.toBe(ports[1]);
|
|
226
|
+
const dirs = ports.map((p) => getLaunchedUserDataDir(p));
|
|
227
|
+
expect(dirs[0]).not.toBe(dirs[1]);
|
|
228
|
+
expect(dirs[0]).toBeTruthy();
|
|
229
|
+
expect(dirs[1]).toBeTruthy();
|
|
230
|
+
}, 15000);
|
|
231
|
+
});
|
|
101
232
|
//# sourceMappingURL=browser-launch.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-launch.test.js","sourceRoot":"","sources":["../../../src/__tests__/browser-launch.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAA6B,MAAM,WAAW,CAAC;AACxF,OAAO,EAAE,YAAY,IAAI,eAAe,EAAyC,MAAM,UAAU,CAAC;AAClG,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-launch.test.js","sourceRoot":"","sources":["../../../src/__tests__/browser-launch.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -68,9 +68,9 @@ afterEach(async () => {
|
|
|
68
68
|
await rm(tempDir, { recursive: true, force: true });
|
|
69
69
|
});
|
|
70
70
|
async function writePersistedPort(port, pid, savedAt) {
|
|
71
|
-
const dir = join(tempDir, '.monomind', 'monobrowse');
|
|
71
|
+
const dir = join(tempDir, '.monomind', 'monobrowse', 'sessions');
|
|
72
72
|
await mkdir(dir, { recursive: true });
|
|
73
|
-
await writeFile(join(dir,
|
|
73
|
+
await writeFile(join(dir, `${port}.json`), JSON.stringify({ port, pid, launched: true, savedAt }), 'utf-8');
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
76
|
* Block (in REAL time) until closeBrowser()'s process-exit poll has actually
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"close-browser.test.js","sourceRoot":"","sources":["../../../src/__tests__/close-browser.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"close-browser.test.js","sourceRoot":"","sources":["../../../src/__tests__/close-browser.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,15 @@ const mocks = vi.hoisted(() => {
|
|
|
18
18
|
sessionId: 'S-PAGE',
|
|
19
19
|
target: { id: 'T-PAGE', url: 'https://x.test' },
|
|
20
20
|
})),
|
|
21
|
-
|
|
21
|
+
listSessionRecords: vi.fn(async () => []),
|
|
22
|
+
loadSessionRecord: vi.fn(async () => null),
|
|
23
|
+
loadLegacySessionRecord: vi.fn(async () => null),
|
|
24
|
+
removeLegacySessionRecord: vi.fn(async () => { }),
|
|
25
|
+
saveSessionRecord: vi.fn(async () => { }),
|
|
26
|
+
removeSessionRecord: vi.fn(async () => { }),
|
|
27
|
+
clearRefCache: vi.fn(async () => { }),
|
|
28
|
+
getLaunchedPid: vi.fn(() => undefined),
|
|
29
|
+
getLaunchedUserDataDir: vi.fn(() => undefined),
|
|
22
30
|
loadRefCache: vi.fn(async () => null),
|
|
23
31
|
switchToFrame: vi.fn(async () => ({
|
|
24
32
|
url: 'https://f.test/frame',
|
|
@@ -48,7 +56,9 @@ const ctx = (args) => ({
|
|
|
48
56
|
});
|
|
49
57
|
beforeEach(() => {
|
|
50
58
|
vi.clearAllMocks();
|
|
51
|
-
mocks.browser.
|
|
59
|
+
mocks.browser.listSessionRecords.mockResolvedValue([]);
|
|
60
|
+
mocks.browser.loadSessionRecord.mockResolvedValue(null);
|
|
61
|
+
mocks.browser.loadLegacySessionRecord.mockResolvedValue(null);
|
|
52
62
|
mocks.browser.loadRefCache.mockResolvedValue(null);
|
|
53
63
|
mocks.browser.switchToFrame.mockResolvedValue({
|
|
54
64
|
url: 'https://f.test/frame',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-command.test.js","sourceRoot":"","sources":["../../../src/__tests__/frame-command.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9D,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;IAC5B,MAAM,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,OAAe,EAAE,OAAiB,EAAE,IAAa,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACjE,OAAO;QACL,IAAI;QACJ,MAAM;QACN,OAAO,EAAE;YACP,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC;YACtC,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAClC,MAAM;gBACN,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE;aAChD,CAAC,CAAC;YACH,kBAAkB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"frame-command.test.js","sourceRoot":"","sources":["../../../src/__tests__/frame-command.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -102,13 +102,14 @@ function fakeChrome(port, targets) {
|
|
|
102
102
|
});
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
// Sessions are recorded one file per port (#318).
|
|
106
|
+
const PORT_FILE = (port) => join(tempDir, '.monomind', 'monobrowse', 'sessions', `${port}.json`);
|
|
106
107
|
async function writePersistedPort(record) {
|
|
107
|
-
await mkdir(join(tempDir, '.monomind', 'monobrowse'), { recursive: true });
|
|
108
|
-
await writeFile(PORT_FILE(), JSON.stringify(record), 'utf-8');
|
|
108
|
+
await mkdir(join(tempDir, '.monomind', 'monobrowse', 'sessions'), { recursive: true });
|
|
109
|
+
await writeFile(PORT_FILE(record.port), JSON.stringify(record), 'utf-8');
|
|
109
110
|
}
|
|
110
|
-
async function portFileExists() {
|
|
111
|
-
return readFile(PORT_FILE(), 'utf-8').then(() => true, () => false);
|
|
111
|
+
async function portFileExists(port) {
|
|
112
|
+
return readFile(PORT_FILE(port), 'utf-8').then(() => true, () => false);
|
|
112
113
|
}
|
|
113
114
|
async function loadBrowser() {
|
|
114
115
|
vi.resetModules();
|
|
@@ -140,7 +141,7 @@ describe('#310 reapIdleLaunchedBrowser — give back a CDP port nothing is using
|
|
|
140
141
|
expect(lastSocket?.methods()).toContain('Browser.close');
|
|
141
142
|
// The port file is the session handle — a reaped session must not leave
|
|
142
143
|
// one behind for the next command to chase.
|
|
143
|
-
expect(await portFileExists()).toBe(false);
|
|
144
|
+
expect(await portFileExists(port)).toBe(false);
|
|
144
145
|
});
|
|
145
146
|
it('does NOT reap a launched instance that still has open page targets', async () => {
|
|
146
147
|
const port = BASE + 1;
|
|
@@ -155,7 +156,7 @@ describe('#310 reapIdleLaunchedBrowser — give back a CDP port nothing is using
|
|
|
155
156
|
await expect(reapIdleLaunchedBrowser()).resolves.toBeNull();
|
|
156
157
|
expect(lastSocket).toBeNull();
|
|
157
158
|
expect(killSpy).not.toHaveBeenCalled();
|
|
158
|
-
expect(await portFileExists()).toBe(true);
|
|
159
|
+
expect(await portFileExists(port)).toBe(true);
|
|
159
160
|
});
|
|
160
161
|
it('does NOT reap a browser this tool never launched, however idle or old it is', async () => {
|
|
161
162
|
// `connect` records launched:false — that browser belongs to the user.
|
|
@@ -171,7 +172,7 @@ describe('#310 reapIdleLaunchedBrowser — give back a CDP port nothing is using
|
|
|
171
172
|
await expect(reapIdleLaunchedBrowser()).resolves.toBeNull();
|
|
172
173
|
expect(lastSocket).toBeNull();
|
|
173
174
|
expect(killSpy).not.toHaveBeenCalled();
|
|
174
|
-
expect(await portFileExists()).toBe(true);
|
|
175
|
+
expect(await portFileExists(port)).toBe(true);
|
|
175
176
|
});
|
|
176
177
|
it('does NOT reap while a client is still attached to a target', async () => {
|
|
177
178
|
// Chrome omits webSocketDebuggerUrl from a target that already has a
|
|
@@ -189,7 +190,7 @@ describe('#310 reapIdleLaunchedBrowser — give back a CDP port nothing is using
|
|
|
189
190
|
const { reapIdleLaunchedBrowser } = await loadBrowser();
|
|
190
191
|
await expect(reapIdleLaunchedBrowser()).resolves.toBeNull();
|
|
191
192
|
expect(lastSocket).toBeNull();
|
|
192
|
-
expect(await portFileExists()).toBe(true);
|
|
193
|
+
expect(await portFileExists(port)).toBe(true);
|
|
193
194
|
});
|
|
194
195
|
it('does NOT reap an instance that is still inside the idle threshold', async () => {
|
|
195
196
|
// A live session can momentarily have no targets (last tab closed, next
|
|
@@ -200,13 +201,12 @@ describe('#310 reapIdleLaunchedBrowser — give back a CDP port nothing is using
|
|
|
200
201
|
const { reapIdleLaunchedBrowser } = await loadBrowser();
|
|
201
202
|
await expect(reapIdleLaunchedBrowser()).resolves.toBeNull();
|
|
202
203
|
expect(lastSocket).toBeNull();
|
|
203
|
-
expect(await portFileExists()).toBe(true);
|
|
204
|
+
expect(await portFileExists(port)).toBe(true);
|
|
204
205
|
});
|
|
205
206
|
it('does NOT reap when the persisted record has no savedAt (age unknowable)', async () => {
|
|
206
207
|
const port = BASE + 5;
|
|
207
208
|
await fakeChrome(port, []);
|
|
208
|
-
await
|
|
209
|
-
await writeFile(PORT_FILE(), JSON.stringify({ port, pid: 54326, launched: true }), 'utf-8');
|
|
209
|
+
await writePersistedPort({ port, pid: 54326, launched: true });
|
|
210
210
|
const { reapIdleLaunchedBrowser } = await loadBrowser();
|
|
211
211
|
await expect(reapIdleLaunchedBrowser()).resolves.toBeNull();
|
|
212
212
|
expect(lastSocket).toBeNull();
|
|
@@ -232,7 +232,7 @@ describe('#310 reapIdleLaunchedBrowser — give back a CDP port nothing is using
|
|
|
232
232
|
// the reap rather than spawning a real browser.
|
|
233
233
|
await expect(launchBrowser({ port })).resolves.toBe(port);
|
|
234
234
|
expect(lastSocket?.methods()).toContain('Browser.close');
|
|
235
|
-
expect(await portFileExists()).toBe(false);
|
|
235
|
+
expect(await portFileExists(port)).toBe(false);
|
|
236
236
|
});
|
|
237
237
|
});
|
|
238
238
|
//# sourceMappingURL=reap-idle-browser.test.js.map
|