@monoes/monobrowse 1.0.27 → 1.0.30
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__/browser-launch-double-loss.test.d.ts +16 -0
- package/dist/src/__tests__/browser-launch-double-loss.test.d.ts.map +1 -0
- package/dist/src/__tests__/browser-launch-double-loss.test.js +119 -0
- package/dist/src/__tests__/browser-launch-double-loss.test.js.map +1 -0
- package/dist/src/__tests__/chrome-fallback.test.d.ts +2 -0
- package/dist/src/__tests__/chrome-fallback.test.d.ts.map +1 -0
- package/dist/src/__tests__/chrome-fallback.test.js +63 -0
- package/dist/src/__tests__/chrome-fallback.test.js.map +1 -0
- package/dist/src/__tests__/disconnect-session.test.d.ts +13 -0
- package/dist/src/__tests__/disconnect-session.test.d.ts.map +1 -0
- package/dist/src/__tests__/disconnect-session.test.js +37 -0
- package/dist/src/__tests__/disconnect-session.test.js.map +1 -0
- package/dist/src/__tests__/profile-cleanup-close.test.d.ts +16 -0
- package/dist/src/__tests__/profile-cleanup-close.test.d.ts.map +1 -0
- package/dist/src/__tests__/profile-cleanup-close.test.js +250 -0
- package/dist/src/__tests__/profile-cleanup-close.test.js.map +1 -0
- package/dist/src/__tests__/profile-dir.test.d.ts +10 -0
- package/dist/src/__tests__/profile-dir.test.d.ts.map +1 -0
- package/dist/src/__tests__/profile-dir.test.js +160 -0
- package/dist/src/__tests__/profile-dir.test.js.map +1 -0
- package/dist/src/__tests__/setup/isolated-tmpdir.global.d.ts +2 -0
- package/dist/src/__tests__/setup/isolated-tmpdir.global.d.ts.map +1 -0
- package/dist/src/__tests__/setup/isolated-tmpdir.global.js +30 -0
- package/dist/src/__tests__/setup/isolated-tmpdir.global.js.map +1 -0
- package/dist/src/browser/browser-discovery.d.ts +8 -0
- package/dist/src/browser/browser-discovery.d.ts.map +1 -1
- package/dist/src/browser/browser-discovery.js +25 -0
- package/dist/src/browser/browser-discovery.js.map +1 -1
- package/dist/src/browser/browser-launch.d.ts.map +1 -1
- package/dist/src/browser/browser-launch.js +48 -10
- package/dist/src/browser/browser-launch.js.map +1 -1
- package/dist/src/browser/browser-lifecycle.d.ts +5 -0
- package/dist/src/browser/browser-lifecycle.d.ts.map +1 -1
- package/dist/src/browser/browser-lifecycle.js +23 -11
- package/dist/src/browser/browser-lifecycle.js.map +1 -1
- package/dist/src/browser/browser-state.d.ts +4 -0
- package/dist/src/browser/browser-state.d.ts.map +1 -1
- package/dist/src/browser/browser-state.js +10 -2
- package/dist/src/browser/browser-state.js.map +1 -1
- package/dist/src/browser/browser.d.ts +2 -2
- package/dist/src/browser/browser.d.ts.map +1 -1
- package/dist/src/browser/browser.js +2 -2
- package/dist/src/browser/browser.js.map +1 -1
- package/dist/src/browser/profile-dir.d.ts +88 -0
- package/dist/src/browser/profile-dir.d.ts.map +1 -0
- package/dist/src/browser/profile-dir.js +242 -0
- package/dist/src/browser/profile-dir.js.map +1 -0
- package/dist/src/browser/ref-cache.d.ts +4 -0
- package/dist/src/browser/ref-cache.d.ts.map +1 -1
- package/dist/src/browser/ref-cache.js +2 -0
- package/dist/src/browser/ref-cache.js.map +1 -1
- package/dist/src/browser/types.d.ts +6 -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.d.ts +1 -0
- package/dist/src/cli/commands.d.ts.map +1 -1
- package/dist/src/cli/commands.js +2 -0
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/session.d.ts +9 -0
- package/dist/src/cli/session.d.ts.map +1 -1
- package/dist/src/cli/session.js +21 -4
- package/dist/src/cli/session.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/__tests__/browser-launch-double-loss.test.ts +128 -0
- package/src/__tests__/chrome-fallback.test.ts +74 -0
- package/src/__tests__/disconnect-session.test.ts +42 -0
- package/src/__tests__/profile-cleanup-close.test.ts +285 -0
- package/src/__tests__/profile-dir.test.ts +196 -0
- package/src/__tests__/setup/isolated-tmpdir.global.ts +28 -0
- package/src/browser/browser-discovery.ts +25 -0
- package/src/browser/browser-launch.ts +49 -11
- package/src/browser/browser-lifecycle.ts +20 -10
- package/src/browser/browser-state.ts +11 -2
- package/src/browser/browser.ts +6 -2
- package/src/browser/profile-dir.ts +249 -0
- package/src/browser/ref-cache.ts +7 -0
- package/src/browser/types.ts +6 -0
- package/src/cli/commands.ts +2 -0
- package/src/cli/session.ts +22 -4
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #395: the crash sweep and ownership checks for the temp Chrome profiles
|
|
3
|
+
* monobrowse creates (profile-dir.ts).
|
|
4
|
+
*
|
|
5
|
+
* Every test sweeps a root of its own made with mkdtemp — never the real
|
|
6
|
+
* /tmp, where other sessions' live Chrome profiles live. (The whole package
|
|
7
|
+
* run also gets a throwaway TMPDIR, see setup/isolated-tmpdir.global.ts.)
|
|
8
|
+
*/
|
|
9
|
+
import { spawn } from 'node:child_process';
|
|
10
|
+
import { existsSync } from 'node:fs';
|
|
11
|
+
import { lutimes, mkdir, mkdtemp, rm, symlink, utimes, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { tmpdir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
15
|
+
import { isOwnedProfileDir, isProfileDirInUse, profileDirOwnerPid, removeOwnedProfileDir, sweepStaleProfileDirs, } from '../browser/profile-dir.js';
|
|
16
|
+
let root;
|
|
17
|
+
let outside;
|
|
18
|
+
const children = [];
|
|
19
|
+
const HOUR_AGO = new Date(Date.now() - 60 * 60 * 1000);
|
|
20
|
+
beforeEach(async () => {
|
|
21
|
+
root = await mkdtemp(join(tmpdir(), 'monobrowse-sweep-root-'));
|
|
22
|
+
outside = await mkdtemp(join(tmpdir(), 'monobrowse-sweep-outside-'));
|
|
23
|
+
});
|
|
24
|
+
afterEach(async () => {
|
|
25
|
+
for (const child of children.splice(0))
|
|
26
|
+
child.kill('SIGKILL');
|
|
27
|
+
await rm(root, { recursive: true, force: true });
|
|
28
|
+
await rm(outside, { recursive: true, force: true });
|
|
29
|
+
});
|
|
30
|
+
/** A pid that belonged to a process which has since exited. */
|
|
31
|
+
async function deadPid() {
|
|
32
|
+
const child = spawn(process.execPath, ['-e', ''], { stdio: 'ignore' });
|
|
33
|
+
await new Promise((resolve) => child.once('exit', resolve));
|
|
34
|
+
return child.pid;
|
|
35
|
+
}
|
|
36
|
+
/** A live process whose command line passes `--user-data-dir=<dir>`, the way
|
|
37
|
+
* Chrome's own does. */
|
|
38
|
+
async function holder(dir) {
|
|
39
|
+
const child = spawn(process.execPath, ['-e', 'setInterval(() => {}, 1000)', '--', `--user-data-dir=${dir}`], { stdio: 'ignore' });
|
|
40
|
+
children.push(child);
|
|
41
|
+
await new Promise((resolve) => child.once('spawn', resolve));
|
|
42
|
+
return child;
|
|
43
|
+
}
|
|
44
|
+
/** A profile-looking directory with some content, backdated past the grace. */
|
|
45
|
+
async function profile(name, opts = {}) {
|
|
46
|
+
const dir = join(root, name);
|
|
47
|
+
await mkdir(join(dir, 'Default'), { recursive: true });
|
|
48
|
+
await writeFile(join(dir, 'Default', 'Preferences'), '{}');
|
|
49
|
+
if (!opts.young)
|
|
50
|
+
await utimes(dir, HOUR_AGO, HOUR_AGO);
|
|
51
|
+
return dir;
|
|
52
|
+
}
|
|
53
|
+
describe('#395 profileDirOwnerPid', () => {
|
|
54
|
+
it('reads the pid from exactly our two name patterns', () => {
|
|
55
|
+
expect(profileDirOwnerPid('monomind-browser-9222-1234-0a1b2c3d')).toBe(1234);
|
|
56
|
+
expect(profileDirOwnerPid('monomind-browse-4321-0a1b2c3d')).toBe(4321);
|
|
57
|
+
for (const name of [
|
|
58
|
+
'monomind-browse-4321-0A1B2C3D',
|
|
59
|
+
'monomind-browse-4321-0a1b2c3d0',
|
|
60
|
+
'monomind-browse-x-0a1b2c3d',
|
|
61
|
+
'monomind-browser-4321-0a1b2c3d',
|
|
62
|
+
'xmonomind-browse-4321-0a1b2c3d',
|
|
63
|
+
'org.chromium.Chromium.abc123',
|
|
64
|
+
]) {
|
|
65
|
+
expect(profileDirOwnerPid(name), name).toBeNull();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe('#395 sweepStaleProfileDirs', () => {
|
|
70
|
+
it('deletes stale dirs whose owner is dead and nothing uses', async () => {
|
|
71
|
+
const pid = await deadPid();
|
|
72
|
+
const a = await profile(`monomind-browser-9222-${pid}-aaaaaaaa`);
|
|
73
|
+
const b = await profile(`monomind-browse-${pid}-bbbbbbbb`);
|
|
74
|
+
const removed = await sweepStaleProfileDirs({ root });
|
|
75
|
+
expect(removed.sort()).toEqual([a, b].sort());
|
|
76
|
+
expect(existsSync(a)).toBe(false);
|
|
77
|
+
expect(existsSync(b)).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
it('keeps young dirs, dirs whose pid is alive, non-matching names, symlinks and files', async () => {
|
|
80
|
+
const pid = await deadPid();
|
|
81
|
+
const young = await profile(`monomind-browse-${pid}-cccccccc`, { young: true });
|
|
82
|
+
const alive = await profile(`monomind-browse-${process.pid}-dddddddd`);
|
|
83
|
+
const foreign = [
|
|
84
|
+
await profile('org.chromium.Chromium.abc123'),
|
|
85
|
+
await profile(`monomind-browse-${pid}-ABCDEF12`),
|
|
86
|
+
await profile(`monomind-browse-${pid}-abcdef12-extra`),
|
|
87
|
+
await profile(`other-monomind-browse-${pid}-abcdef12`),
|
|
88
|
+
];
|
|
89
|
+
// A symlink with our name, pointing out of the root at a real profile.
|
|
90
|
+
const target = join(outside, 'victim');
|
|
91
|
+
await mkdir(target);
|
|
92
|
+
await writeFile(join(target, 'keep.txt'), 'keep');
|
|
93
|
+
const link = join(root, `monomind-browse-${pid}-11111111`);
|
|
94
|
+
await symlink(target, link);
|
|
95
|
+
await lutimes(link, HOUR_AGO, HOUR_AGO);
|
|
96
|
+
// A plain file with our name.
|
|
97
|
+
const file = join(root, `monomind-browse-${pid}-22222222`);
|
|
98
|
+
await writeFile(file, 'not a dir');
|
|
99
|
+
await utimes(file, HOUR_AGO, HOUR_AGO);
|
|
100
|
+
expect(await sweepStaleProfileDirs({ root })).toEqual([]);
|
|
101
|
+
for (const kept of [young, alive, ...foreign, link, file])
|
|
102
|
+
expect(existsSync(kept)).toBe(true);
|
|
103
|
+
expect(existsSync(join(target, 'keep.txt'))).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
it.skipIf(process.platform !== 'linux')('keeps a dir a live process uses as --user-data-dir, though its named pid is dead', async () => {
|
|
106
|
+
// A CLI `open` exits right after launching, so the pid in the name is
|
|
107
|
+
// dead while its Chrome runs on: only the live user of the dir says so.
|
|
108
|
+
const pid = await deadPid();
|
|
109
|
+
const inUse = await profile(`monomind-browse-${pid}-eeeeeeee`);
|
|
110
|
+
await holder(inUse);
|
|
111
|
+
expect(await sweepStaleProfileDirs({ root })).toEqual([]);
|
|
112
|
+
expect(existsSync(inUse)).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
it('without /proc, keeps a dir whose SingletonLock names a live pid', async () => {
|
|
115
|
+
const pid = await deadPid();
|
|
116
|
+
const locked = await profile(`monomind-browse-${pid}-ffffffff`);
|
|
117
|
+
await symlink(`somehost-${process.pid}`, join(locked, 'SingletonLock'));
|
|
118
|
+
await utimes(locked, HOUR_AGO, HOUR_AGO);
|
|
119
|
+
const staleLock = await profile(`monomind-browse-${pid}-99999999`);
|
|
120
|
+
await symlink(`somehost-${pid}`, join(staleLock, 'SingletonLock'));
|
|
121
|
+
await utimes(staleLock, HOUR_AGO, HOUR_AGO);
|
|
122
|
+
expect(await sweepStaleProfileDirs({ root, procDir: null })).toEqual([staleLock]);
|
|
123
|
+
expect(existsSync(locked)).toBe(true);
|
|
124
|
+
});
|
|
125
|
+
it('never throws, and sweeps nothing, when the root is missing', async () => {
|
|
126
|
+
await expect(sweepStaleProfileDirs({ root: join(root, 'missing') })).resolves.toEqual([]);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
describe('#395 isOwnedProfileDir / removeOwnedProfileDir', () => {
|
|
130
|
+
it('refuses a caller-supplied dir, a dir outside the root, and a symlink', async () => {
|
|
131
|
+
const caller = join(root, 'my-profile');
|
|
132
|
+
await mkdir(caller);
|
|
133
|
+
const nested = join(root, 'sub', `monomind-browse-${process.pid}-aaaaaaaa`);
|
|
134
|
+
await mkdir(nested, { recursive: true });
|
|
135
|
+
const target = join(outside, 'victim');
|
|
136
|
+
await mkdir(target);
|
|
137
|
+
const link = join(root, `monomind-browse-${process.pid}-bbbbbbbb`);
|
|
138
|
+
await symlink(target, link);
|
|
139
|
+
for (const dir of [caller, nested, link]) {
|
|
140
|
+
expect(await isOwnedProfileDir(dir, root), dir).toBe(false);
|
|
141
|
+
expect(await removeOwnedProfileDir(dir, { root }), dir).toBe(false);
|
|
142
|
+
expect(existsSync(dir), dir).toBe(true);
|
|
143
|
+
}
|
|
144
|
+
expect(existsSync(target)).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
it('removes an owned dir once its browser pid has exited', async () => {
|
|
147
|
+
const dir = await profile(`monomind-browse-${process.pid}-cccccccc`, { young: true });
|
|
148
|
+
const pid = await deadPid();
|
|
149
|
+
expect(await removeOwnedProfileDir(dir, { root, pid })).toBe(true);
|
|
150
|
+
expect(existsSync(dir)).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
it.skipIf(process.platform !== 'linux')('keeps an owned dir while a live process still uses it', async () => {
|
|
153
|
+
const dir = await profile(`monomind-browse-${process.pid}-dddddddd`, { young: true });
|
|
154
|
+
const child = await holder(dir);
|
|
155
|
+
expect(await isProfileDirInUse(dir)).toBe(true);
|
|
156
|
+
expect(await removeOwnedProfileDir(dir, { root, pid: child.pid })).toBe(false);
|
|
157
|
+
expect(existsSync(dir)).toBe(true);
|
|
158
|
+
}, 15_000);
|
|
159
|
+
});
|
|
160
|
+
//# sourceMappingURL=profile-dir.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-dir.test.js","sourceRoot":"","sources":["../../../src/__tests__/profile-dir.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolated-tmpdir.global.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/setup/isolated-tmpdir.global.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,OAAO,UAAU,KAAK,IAAI,MAAM,IAAI,CAY1C"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest globalSetup: run every monobrowse test worker against a throwaway
|
|
3
|
+
* TMPDIR (#395).
|
|
4
|
+
*
|
|
5
|
+
* launchBrowser() sweeps stale `monomind-browser-*` / `monomind-browse-*`
|
|
6
|
+
* profile dirs out of os.tmpdir() on every launch. The sweep only removes
|
|
7
|
+
* dead, idle, unused dirs, but a test run must never touch the real /tmp at
|
|
8
|
+
* all: other sessions' live Chrome profiles live there. Set in the main
|
|
9
|
+
* process before any worker starts, so workers and the CLI processes tests
|
|
10
|
+
* spawn inherit it.
|
|
11
|
+
*/
|
|
12
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
13
|
+
import { tmpdir } from 'node:os';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
export default function setup() {
|
|
16
|
+
const saved = process.env.TMPDIR;
|
|
17
|
+
// Short on purpose: real-Chrome tests nest their own dirs under it, and
|
|
18
|
+
// Chrome aborts at startup (SIGABRT) once the unix socket path it makes in
|
|
19
|
+
// TMPDIR (…/org.chromium.Chromium.XXXXXX/SingletonSocket) passes ~107 bytes.
|
|
20
|
+
const dir = mkdtempSync(join(tmpdir(), 'mb-'));
|
|
21
|
+
process.env.TMPDIR = dir;
|
|
22
|
+
return () => {
|
|
23
|
+
if (saved === undefined)
|
|
24
|
+
delete process.env.TMPDIR;
|
|
25
|
+
else
|
|
26
|
+
process.env.TMPDIR = saved;
|
|
27
|
+
rmSync(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 });
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=isolated-tmpdir.global.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolated-tmpdir.global.js","sourceRoot":"","sources":["../../../../src/__tests__/setup/isolated-tmpdir.global.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,OAAO,UAAU,KAAK;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;IACjC,wEAAwE;IACxE,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;IACzB,OAAO,GAAG,EAAE;QACV,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;;YAC9C,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC;QAChC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IAChF,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
export declare function findChrome(executablePath?: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* Registers where launchBrowser() gets a browser when findChrome() finds none
|
|
4
|
+
* (monomind downloads one on first use). Pass undefined to clear it.
|
|
5
|
+
*/
|
|
6
|
+
export declare function setChromeFallback(fallback: (() => Promise<string>) | undefined): void;
|
|
7
|
+
/** findChrome(), then the registered fallback when no browser is installed.
|
|
8
|
+
* An explicit executablePath never falls back. */
|
|
9
|
+
export declare function resolveChrome(executablePath?: string): Promise<string>;
|
|
2
10
|
export declare function isPortOpen(port: number): Promise<boolean>;
|
|
3
11
|
/**
|
|
4
12
|
* Confirm the CDP endpoint on `port` actually identifies as Chrome/Chromium
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-discovery.d.ts","sourceRoot":"","sources":["../../../src/browser/browser-discovery.ts"],"names":[],"mappings":"AAQA,wBAAgB,UAAU,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"browser-discovery.d.ts","sourceRoot":"","sources":["../../../src/browser/browser-discovery.ts"],"names":[],"mappings":"AAQA,wBAAgB,UAAU,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CA0B1D;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAErF;AAED;mDACmD;AACnD,wBAAsB,aAAa,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5E;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAErE;AAED;;+CAE+C;AAC/C,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC,CAgB1F;AAED,2GAA2G;AAC3G,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAY9E;AAED;kEACkE;AAClE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOlE;AAED;yDACyD;AACzD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED;;gFAEgF;AAChF,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQnF"}
|
|
@@ -24,8 +24,33 @@ export function findChrome(executablePath) {
|
|
|
24
24
|
catch {
|
|
25
25
|
// ignore
|
|
26
26
|
}
|
|
27
|
+
// A browser some other tool fetched for us (monomind sets this for its own
|
|
28
|
+
// child processes). Last, so an installed browser always wins.
|
|
29
|
+
const fromEnv = process.env.MONOBROWSE_CHROME_PATH;
|
|
30
|
+
if (fromEnv && existsSync(fromEnv))
|
|
31
|
+
return fromEnv;
|
|
27
32
|
throw new Error('No supported browser found. Install Google Chrome, Microsoft Edge, or Chromium — or pass executablePath in BrowserConfig.');
|
|
28
33
|
}
|
|
34
|
+
let chromeFallback;
|
|
35
|
+
/**
|
|
36
|
+
* Registers where launchBrowser() gets a browser when findChrome() finds none
|
|
37
|
+
* (monomind downloads one on first use). Pass undefined to clear it.
|
|
38
|
+
*/
|
|
39
|
+
export function setChromeFallback(fallback) {
|
|
40
|
+
chromeFallback = fallback;
|
|
41
|
+
}
|
|
42
|
+
/** findChrome(), then the registered fallback when no browser is installed.
|
|
43
|
+
* An explicit executablePath never falls back. */
|
|
44
|
+
export async function resolveChrome(executablePath) {
|
|
45
|
+
try {
|
|
46
|
+
return findChrome(executablePath);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (executablePath || !chromeFallback)
|
|
50
|
+
throw err;
|
|
51
|
+
return chromeFallback();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
29
54
|
export async function isPortOpen(port) {
|
|
30
55
|
try {
|
|
31
56
|
await fetchTargets(port);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-discovery.js","sourceRoot":"","sources":["../../../src/browser/browser-discovery.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"browser-discovery.js","sourceRoot":"","sources":["../../../src/browser/browser-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-launch.d.ts","sourceRoot":"","sources":["../../../src/browser/browser-launch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser-launch.d.ts","sourceRoot":"","sources":["../../../src/browser/browser-launch.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkBhD,wBAAsB,aAAa,CAAC,MAAM,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+G/E"}
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
4
|
import { rmSync } from 'node:fs';
|
|
5
|
-
import { tmpdir } from 'node:os';
|
|
6
5
|
import { join } from 'node:path';
|
|
7
|
-
import { browserIdOf, chromeIdentity, fetchBrowserWebSocketUrl,
|
|
6
|
+
import { browserIdOf, chromeIdentity, fetchBrowserWebSocketUrl, isChromeIdentity, isPortOpen, isTcpPortOpen, readDevToolsActivePort, resolveChrome, } from './browser-discovery.js';
|
|
8
7
|
import { reapIdleLaunchedBrowser } from './browser-lifecycle.js';
|
|
9
|
-
import { launchedPids, launchedUserDataDirs } from './browser-state.js';
|
|
8
|
+
import { launchedPids, launchedUserDataDirs, ownedUserDataDirPorts } from './browser-state.js';
|
|
9
|
+
import { launchProfileDirPath, removeOwnedProfileDir, sweepStaleProfileDirs, } from './profile-dir.js';
|
|
10
10
|
const DEFAULT_PORT = 9222;
|
|
11
11
|
const LAUNCH_TIMEOUT = 10_000;
|
|
12
12
|
const POLL_INTERVAL = 200;
|
|
@@ -18,6 +18,9 @@ const POLL_INTERVAL = 200;
|
|
|
18
18
|
* requested port is still returned as-is (existing "attach, don't relaunch"
|
|
19
19
|
* behavior). */
|
|
20
20
|
const LAUNCH_PORT_SCAN_TRIES = 10;
|
|
21
|
+
/** Chrome's process exited before its CDP endpoint opened. */
|
|
22
|
+
class ChromeExitedEarlyError extends Error {
|
|
23
|
+
}
|
|
21
24
|
export async function launchBrowser(config = {}) {
|
|
22
25
|
const rawPort = config.port ?? DEFAULT_PORT;
|
|
23
26
|
// Port 0 means "let Chrome bind a free port and tell us which" — see
|
|
@@ -36,6 +39,10 @@ export async function launchBrowser(config = {}) {
|
|
|
36
39
|
// is no daemon to do it on a timer. Bounded and non-throwing; a stale
|
|
37
40
|
// instance on the port we are about to use is freed before we probe it.
|
|
38
41
|
await reapIdleLaunchedBrowser();
|
|
42
|
+
// Same reasoning for temp profile dirs (#395): a process that crashed or
|
|
43
|
+
// was killed never deleted the one its browser used. Only dead, idle,
|
|
44
|
+
// unused dirs of our own naming go — see sweepStaleProfileDirs.
|
|
45
|
+
await sweepStaleProfileDirs();
|
|
39
46
|
if (rawPort === 0)
|
|
40
47
|
return launchOnFreePort(config, 0);
|
|
41
48
|
// strictPort: fail fast on the exact requested port, matching the old
|
|
@@ -54,6 +61,9 @@ export async function launchBrowser(config = {}) {
|
|
|
54
61
|
const candidates = [];
|
|
55
62
|
for (let i = 0; i < LAUNCH_PORT_SCAN_TRIES && rawPort + i <= 65535; i++)
|
|
56
63
|
candidates.push(rawPort + i);
|
|
64
|
+
// See the catch below: one early Chrome exit on a candidate nobody holds
|
|
65
|
+
// afterwards is read as a lost port race, not a broken Chrome.
|
|
66
|
+
let toleratedEarlyExit = null;
|
|
57
67
|
for (const candidate of candidates) {
|
|
58
68
|
// TCP-level check for "is anything at all listening" — isPortOpen()
|
|
59
69
|
// does a full CDP /json fetch, which returns false BOTH for a genuinely
|
|
@@ -92,11 +102,26 @@ export async function launchBrowser(config = {}) {
|
|
|
92
102
|
// was not a moment ago — a losing race, not a broken Chrome install —
|
|
93
103
|
// so try the next candidate exactly like an already-occupied one,
|
|
94
104
|
// instead of failing the whole launch outright. A candidate that
|
|
95
|
-
// fails with nothing now listening
|
|
96
|
-
// executable, sandbox refusal, etc.)
|
|
97
|
-
//
|
|
105
|
+
// fails with nothing now listening is usually a real launch failure
|
|
106
|
+
// (bad executable, sandbox refusal, etc.) that the next candidate would
|
|
107
|
+
// only repeat, so it is surfaced as-is.
|
|
98
108
|
if (!isLastCandidate && (await isTcpPortOpen(candidate)))
|
|
99
109
|
continue;
|
|
110
|
+
// Usually, but not always (#491): two launches that call listen() on
|
|
111
|
+
// the same port at the same instant can BOTH lose it on Linux — each
|
|
112
|
+
// socket is marked LISTEN before the kernel checks the port for
|
|
113
|
+
// conflicts, so each sees the other and gets EADDRINUSE. Both Chromes
|
|
114
|
+
// exit early and the port is free again, which is indistinguishable
|
|
115
|
+
// from a Chrome that cannot start. Move on once; a Chrome that really
|
|
116
|
+
// cannot start exits the same way on the next candidate, and the first
|
|
117
|
+
// of the two identical failures is surfaced.
|
|
118
|
+
if (err instanceof ChromeExitedEarlyError) {
|
|
119
|
+
if (!isLastCandidate && !toleratedEarlyExit) {
|
|
120
|
+
toleratedEarlyExit = err;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
throw toleratedEarlyExit ?? err;
|
|
124
|
+
}
|
|
100
125
|
throw err;
|
|
101
126
|
}
|
|
102
127
|
}
|
|
@@ -130,15 +155,17 @@ export async function launchBrowser(config = {}) {
|
|
|
130
155
|
* doomed pid there. It also covers Chrome's [::1] fallback described above.
|
|
131
156
|
*/
|
|
132
157
|
async function launchOnFreePort(config, port) {
|
|
133
|
-
const chromePath =
|
|
158
|
+
const chromePath = await resolveChrome(config.executablePath);
|
|
134
159
|
// Unique per launch, not just per port and pid: two concurrent launches
|
|
135
160
|
// that both probe the same candidate port as free (the race this function
|
|
136
161
|
// exists to survive — see the retry-on-collision caller above) would
|
|
137
162
|
// otherwise share one profile directory (lock files, preferences, the
|
|
138
163
|
// DevToolsActivePort file itself) — including two launches from the same
|
|
139
164
|
// process, where a pid suffix alone is identical.
|
|
140
|
-
const userDataDir = config.userDataDir ??
|
|
141
|
-
|
|
165
|
+
const userDataDir = config.userDataDir ?? launchProfileDirPath(port, randomUUID().slice(0, 8));
|
|
166
|
+
// A dir we created is deleted once its browser is gone (#395); a
|
|
167
|
+
// caller-supplied one only when the caller says it made it for us.
|
|
168
|
+
const ownsUserDataDir = config.userDataDir === undefined || config.ownsUserDataDir === true;
|
|
142
169
|
const activePortFile = join(userDataDir, 'DevToolsActivePort');
|
|
143
170
|
// A reused profile dir may hold a previous run's file naming a port some
|
|
144
171
|
// other process now owns.
|
|
@@ -220,7 +247,7 @@ async function launchOnFreePort(config, port) {
|
|
|
220
247
|
earlyFailure ??= new Error(`Chrome failed to start on port ${port}: ${err.message}`);
|
|
221
248
|
});
|
|
222
249
|
child.on('exit', (code, signal) => {
|
|
223
|
-
earlyFailure ??= new
|
|
250
|
+
earlyFailure ??= new ChromeExitedEarlyError(`Chrome exited before the CDP endpoint opened on port ${port} ` +
|
|
224
251
|
`(code=${code ?? 'null'}, signal=${signal ?? 'null'})`);
|
|
225
252
|
});
|
|
226
253
|
child.unref();
|
|
@@ -229,6 +256,10 @@ async function launchOnFreePort(config, port) {
|
|
|
229
256
|
return;
|
|
230
257
|
launchedPids.set(boundPort, child.pid);
|
|
231
258
|
launchedUserDataDirs.set(boundPort, userDataDir);
|
|
259
|
+
if (ownsUserDataDir)
|
|
260
|
+
ownedUserDataDirPorts.add(boundPort);
|
|
261
|
+
else
|
|
262
|
+
ownedUserDataDirPorts.delete(boundPort);
|
|
232
263
|
};
|
|
233
264
|
// Tracked only once Chrome is CONFIRMED up on `boundPort`, not right after
|
|
234
265
|
// spawn(). For port !== 0 this used to track(port) unconditionally the
|
|
@@ -264,6 +295,7 @@ async function launchOnFreePort(config, port) {
|
|
|
264
295
|
};
|
|
265
296
|
const launchTimeout = config.launchTimeoutMs ?? LAUNCH_TIMEOUT;
|
|
266
297
|
const deadline = Date.now() + launchTimeout;
|
|
298
|
+
let launched = false;
|
|
267
299
|
try {
|
|
268
300
|
while (Date.now() < deadline) {
|
|
269
301
|
if (earlyFailure)
|
|
@@ -277,6 +309,7 @@ async function launchOnFreePort(config, port) {
|
|
|
277
309
|
if (identity === 'chrome') {
|
|
278
310
|
if (await isOwnEndpoint(boundPort)) {
|
|
279
311
|
track(boundPort);
|
|
312
|
+
launched = true;
|
|
280
313
|
return boundPort;
|
|
281
314
|
}
|
|
282
315
|
// Some Chrome answers on the port, but not the one we started: a
|
|
@@ -316,6 +349,11 @@ async function launchOnFreePort(config, port) {
|
|
|
316
349
|
}
|
|
317
350
|
finally {
|
|
318
351
|
child.stderr?.destroy();
|
|
352
|
+
// A failed launch (lost port race, refusal, timeout) is never tracked,
|
|
353
|
+
// so no close will ever clean its profile — and the port-scan retry in
|
|
354
|
+
// launchBrowser can make several of these per call.
|
|
355
|
+
if (!launched && ownsUserDataDir)
|
|
356
|
+
await removeOwnedProfileDir(userDataDir, { pid: child.pid });
|
|
319
357
|
}
|
|
320
358
|
}
|
|
321
359
|
function sleep(ms) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-launch.js","sourceRoot":"","sources":["../../../src/browser/browser-launch.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"browser-launch.js","sourceRoot":"","sources":["../../../src/browser/browser-launch.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,11 @@ import { CdpClient } from './cdp.js';
|
|
|
16
16
|
* singleton lock, and if the caller's process exited first the kill never
|
|
17
17
|
* happened at all. Callers reasonably read a resolved close() as "that
|
|
18
18
|
* browser is gone"; on the graceful path it now means that.
|
|
19
|
+
*
|
|
20
|
+
* A profile directory monobrowse created for that browser (the default temp
|
|
21
|
+
* profile, or a CLI session's — never a caller-supplied one) is deleted once
|
|
22
|
+
* the process is gone, on both paths (#395). In a fresh process the dir and
|
|
23
|
+
* its ownership come from the persisted session record.
|
|
19
24
|
*/
|
|
20
25
|
export declare function closeBrowser(client: CdpClient, port: number): Promise<void>;
|
|
21
26
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/browser/browser-lifecycle.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAgB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/browser/browser-lifecycle.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAgB,MAAM,UAAU,CAAC;AAuBnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFjF;AAgCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOtE"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Split out of browser.ts (file-size sweep). Pure move: no behaviour change.
|
|
2
2
|
import { fetchBrowserWebSocketUrl } from './browser-discovery.js';
|
|
3
|
-
import { launchedPids, launchedUserDataDirs } from './browser-state.js';
|
|
3
|
+
import { launchedPids, launchedUserDataDirs, ownedUserDataDirPorts } from './browser-state.js';
|
|
4
4
|
import { CdpClient, fetchTargets } from './cdp.js';
|
|
5
|
+
import { removeOwnedProfileDir } from './profile-dir.js';
|
|
5
6
|
import { listSessionRecords, loadSessionRecord, removeSessionRecord, } from './ref-cache.js';
|
|
6
7
|
const BROWSER_CLOSE_TIMEOUT_MS = 3000;
|
|
7
8
|
// How long closeBrowser() waits for the process to actually disappear before
|
|
@@ -33,6 +34,11 @@ const REAP_CONNECT_TIMEOUT_MS = 3000;
|
|
|
33
34
|
* singleton lock, and if the caller's process exited first the kill never
|
|
34
35
|
* happened at all. Callers reasonably read a resolved close() as "that
|
|
35
36
|
* browser is gone"; on the graceful path it now means that.
|
|
37
|
+
*
|
|
38
|
+
* A profile directory monobrowse created for that browser (the default temp
|
|
39
|
+
* profile, or a CLI session's — never a caller-supplied one) is deleted once
|
|
40
|
+
* the process is gone, on both paths (#395). In a fresh process the dir and
|
|
41
|
+
* its ownership come from the persisted session record.
|
|
36
42
|
*/
|
|
37
43
|
export async function closeBrowser(client, port) {
|
|
38
44
|
let gracefullyClosed = false;
|
|
@@ -61,6 +67,7 @@ export async function closeBrowser(client, port) {
|
|
|
61
67
|
clearTimeout(closeTimer);
|
|
62
68
|
}
|
|
63
69
|
let pid = launchedPids.get(port);
|
|
70
|
+
let profileDir = ownedUserDataDirPorts.has(port) ? launchedUserDataDirs.get(port) : undefined;
|
|
64
71
|
if (pid === undefined) {
|
|
65
72
|
// Fresh process (each CLI invocation is its own node process — see
|
|
66
73
|
// module header) — launchedPids is per-process and empty here even
|
|
@@ -79,6 +86,8 @@ export async function closeBrowser(client, port) {
|
|
|
79
86
|
const age = persisted.savedAt !== undefined ? Date.now() - persisted.savedAt : undefined;
|
|
80
87
|
if (age === undefined || age <= PERSISTED_PID_MAX_AGE_MS) {
|
|
81
88
|
pid = persisted.pid;
|
|
89
|
+
if (persisted.ownsUserDataDir)
|
|
90
|
+
profileDir = persisted.userDataDir;
|
|
82
91
|
}
|
|
83
92
|
}
|
|
84
93
|
}
|
|
@@ -89,6 +98,7 @@ export async function closeBrowser(client, port) {
|
|
|
89
98
|
if (pid === undefined)
|
|
90
99
|
return; // not a process we launched, or too stale to trust — nothing to kill
|
|
91
100
|
launchedPids.delete(port);
|
|
101
|
+
ownedUserDataDirPorts.delete(port);
|
|
92
102
|
// Liveness-check before every SIGKILL (not just the safety-net path below)
|
|
93
103
|
// — process.kill(pid, 0) throws ESRCH if the PID is no longer running,
|
|
94
104
|
// which also catches the case where the PID has already been recycled by
|
|
@@ -101,18 +111,20 @@ export async function closeBrowser(client, port) {
|
|
|
101
111
|
catch {
|
|
102
112
|
/* already exited, or never was — nothing to do */
|
|
103
113
|
}
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
// Browser.close was acknowledged — wait for the process to actually go away,
|
|
107
|
-
// then force-kill as a safety net in case it hung.
|
|
108
|
-
if (await waitForProcessExit(pid))
|
|
109
|
-
return;
|
|
110
|
-
try {
|
|
111
|
-
process.kill(pid, 'SIGKILL');
|
|
112
114
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
else if (!(await waitForProcessExit(pid))) {
|
|
116
|
+
// Browser.close was acknowledged — wait for the process to actually go
|
|
117
|
+
// away, then force-kill as a safety net in case it hung.
|
|
118
|
+
try {
|
|
119
|
+
process.kill(pid, 'SIGKILL');
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
/* raced us to exit — expected */
|
|
123
|
+
}
|
|
115
124
|
}
|
|
125
|
+
// Waits (bounded) for the killed process to be gone before deleting.
|
|
126
|
+
if (profileDir)
|
|
127
|
+
await removeOwnedProfileDir(profileDir, { pid });
|
|
116
128
|
}
|
|
117
129
|
/** Poll until `pid` is gone or PROCESS_EXIT_TIMEOUT_MS elapses. Returns
|
|
118
130
|
* whether it exited. `process.kill(pid, 0)` throws once the process is no
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-lifecycle.js","sourceRoot":"","sources":["../../../src/browser/browser-lifecycle.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-lifecycle.js","sourceRoot":"","sources":["../../../src/browser/browser-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export declare const launchedPids: Map<number, number>;
|
|
2
2
|
export declare const launchedUserDataDirs: Map<number, string>;
|
|
3
|
+
export declare const ownedUserDataDirPorts: Set<number>;
|
|
3
4
|
/** PID of the Chrome instance *this process* launched on `port`, if any. */
|
|
4
5
|
export declare function getLaunchedPid(port: number): number | undefined;
|
|
5
6
|
/** userDataDir of the Chrome instance *this process* launched on `port`, if any. */
|
|
6
7
|
export declare function getLaunchedUserDataDir(port: number): string | undefined;
|
|
8
|
+
/** Whether the userDataDir of the Chrome *this process* launched on `port`
|
|
9
|
+
* was created by monobrowse, and so is deleted when that browser closes. */
|
|
10
|
+
export declare function ownsLaunchedUserDataDir(port: number): boolean;
|
|
7
11
|
//# sourceMappingURL=browser-state.d.ts.map
|