flashwright 0.0.0-stage → 1.64.1-flashwright.2

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.
Files changed (67) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +17 -2
  4. package/ThirdPartyNotices.txt +14 -0
  5. package/cli.js +37 -0
  6. package/index.d.ts +17 -0
  7. package/index.js +17 -0
  8. package/index.mjs +18 -0
  9. package/lib/agents/agentParser.js +89 -0
  10. package/lib/agents/copilot-setup-steps.yml +34 -0
  11. package/lib/agents/generateAgents.js +395 -0
  12. package/lib/agents/playwright-test-coverage.prompt.md +31 -0
  13. package/lib/agents/playwright-test-generate.prompt.md +8 -0
  14. package/lib/agents/playwright-test-generator.agent.md +88 -0
  15. package/lib/agents/playwright-test-heal.prompt.md +6 -0
  16. package/lib/agents/playwright-test-healer.agent.md +56 -0
  17. package/lib/agents/playwright-test-plan.prompt.md +9 -0
  18. package/lib/agents/playwright-test-planner.agent.md +74 -0
  19. package/lib/cli/reportActions.js +78 -0
  20. package/lib/cli/testActions.js +219 -0
  21. package/lib/codeCache.js +141 -0
  22. package/lib/codeCache.js.txt +8 -0
  23. package/lib/common/index.js +2974 -0
  24. package/lib/common/index.js.txt +33 -0
  25. package/lib/errorContext.js +129 -0
  26. package/lib/globals.js +58 -0
  27. package/lib/index.js +896 -0
  28. package/lib/isomorphic.js +260 -0
  29. package/lib/isomorphic.js.txt +9 -0
  30. package/lib/loader/loaderProcessEntry.js +34 -0
  31. package/lib/loader/loaderProcessEntry.js.txt +9 -0
  32. package/lib/matchers/expect.js +13496 -0
  33. package/lib/matchers/expect.js.LICENSE +640 -0
  34. package/lib/matchers/expect.js.txt +67 -0
  35. package/lib/mcp/test/browserBackend.js +135 -0
  36. package/lib/mcp/test/generatorTools.js +122 -0
  37. package/lib/mcp/test/plannerTools.js +150 -0
  38. package/lib/mcp/test/seed.js +82 -0
  39. package/lib/mcp/test/streams.js +44 -0
  40. package/lib/mcp/test/testBackend.js +99 -0
  41. package/lib/mcp/test/testContext.js +306 -0
  42. package/lib/mcp/test/testTool.js +30 -0
  43. package/lib/mcp/test/testTools.js +98 -0
  44. package/lib/package.js +47 -0
  45. package/lib/program.js +248 -0
  46. package/lib/runner/index.js +8819 -0
  47. package/lib/runner/index.js.txt +65 -0
  48. package/lib/runner/session.js +723 -0
  49. package/lib/runner/session.js.txt +8 -0
  50. package/lib/runner/workerStandby.js +206 -0
  51. package/lib/runner/workerStandby.js.txt +8 -0
  52. package/lib/speculativeBrowser.js +228 -0
  53. package/lib/transform/babelBundle.js +72490 -0
  54. package/lib/transform/babelBundle.js.LICENSE +2384 -0
  55. package/lib/transform/babelBundle.js.txt +328 -0
  56. package/lib/transform/esmLoader.js +8090 -0
  57. package/lib/transform/esmLoader.js.LICENSE +355 -0
  58. package/lib/transform/esmLoader.js.txt +60 -0
  59. package/lib/util.js +373 -0
  60. package/lib/worker/workerProcessEntry.js +2015 -0
  61. package/lib/worker/workerProcessEntry.js.txt +22 -0
  62. package/package.json +64 -4
  63. package/test.d.ts +18 -0
  64. package/test.js +40 -0
  65. package/test.mjs +35 -0
  66. package/types/test.d.ts +11316 -0
  67. package/types/testReporter.d.ts +950 -0
@@ -0,0 +1,8 @@
1
+ # packages/playwright/lib/runner/session.js
2
+ # total: 25.0 KB
3
+
4
+ ## Inlined (1)
5
+ 23.4 KB packages/playwright/src/runner/session.ts
6
+
7
+ ## External (1)
8
+ playwright-core/lib/coreBundle
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // packages/playwright/src/runner/workerStandby.ts
31
+ var workerStandby_exports = {};
32
+ __export(workerStandby_exports, {
33
+ discardStandbys: () => discardStandbys,
34
+ ensureStandbys: () => ensureStandbys,
35
+ ensureStandbysForConfig: () => ensureStandbysForConfig,
36
+ prespawnWorkerForTestCommand: () => prespawnWorkerForTestCommand,
37
+ recordWorkerCount: () => recordWorkerCount,
38
+ recordWorkerRestart: () => recordWorkerRestart,
39
+ retargetStandbys: () => retargetStandbys,
40
+ takeStandby: () => takeStandby,
41
+ workerEntryScript: () => workerEntryScript,
42
+ workerEnv: () => workerEnv
43
+ });
44
+ module.exports = __toCommonJS(workerStandby_exports);
45
+ var import_child_process = __toESM(require("child_process"));
46
+ var import_crypto = __toESM(require("crypto"));
47
+ var import_fs = __toESM(require("fs"));
48
+ var import_os = __toESM(require("os"));
49
+ var import_path = __toESM(require("path"));
50
+ var import_session = require("./session");
51
+ var standbys = [];
52
+ var enabled = false;
53
+ var hintKey;
54
+ var workerCount = 0;
55
+ var restartCount = 0;
56
+ var keepSpare = false;
57
+ var cpus = 1;
58
+ var hadHint = false;
59
+ var loadTimeEnvPattern = /^(PW|PLAYWRIGHT|DEBUG|NODE|FORCE_COLOR|TS_NODE|TSX)/;
60
+ function workerEntryScript() {
61
+ return import_path.default.join(__dirname, "..", "worker", "workerProcessEntry.js");
62
+ }
63
+ function workerEnv(extraEnv) {
64
+ return {
65
+ ...process.env,
66
+ ...extraEnv,
67
+ FORCE_COLOR: "1",
68
+ DEBUG_COLORS: process.env.DEBUG_COLORS === void 0 ? "1" : process.env.DEBUG_COLORS
69
+ };
70
+ }
71
+ function prespawnWorkerForTestCommand(argv) {
72
+ if (enabled || argv[2] !== "test" || process.env.PW_DISABLE_WORKER_STANDBY || process.env.PWDEBUG)
73
+ return;
74
+ const interactive = ["--list", "--ui", "--ui-host", "--ui-port", "--debug", "-h", "--help", "--last-failed"];
75
+ if (argv.some((arg) => interactive.includes(arg.split("=")[0])))
76
+ return;
77
+ enabled = true;
78
+ hintKey = workerCountHintKey(argv);
79
+ process.env.FLASHWRIGHT_CONTEXT_HINT_KEY = hintKey;
80
+ cpus = import_os.default.availableParallelism?.() ?? import_os.default.cpus().length;
81
+ const hint = readWorkerCountHints()[hintKey];
82
+ hadHint = !!hint;
83
+ const sessionBrowsers = Number(process.env.FLASHWRIGHT_SESSION_STANDBYS) || 0;
84
+ const count = Math.max(1, Math.min(Math.max(hint?.workers || 1, sessionBrowsers), cpus));
85
+ keepSpare = !!hint?.restarts && count < cpus;
86
+ for (let i = 0; i < count + (keepSpare ? 1 : 0); i++)
87
+ spawnStandby();
88
+ process.once("exit", () => {
89
+ discardStandbys();
90
+ writeWorkerCountHint();
91
+ });
92
+ }
93
+ function spawnStandby(waitsForNextPhase = false) {
94
+ const entryScript = workerEntryScript();
95
+ const env = { ...workerEnv({}), PLAYWRIGHT_TEST: "1", FLASHWRIGHT_SPECULATIVE_BROWSER: waitsForNextPhase ? "next-phase" : "1", ...(0, import_session.sessionStandbyEnv)() };
96
+ const child = import_child_process.default.fork(entryScript, {
97
+ detached: false,
98
+ env,
99
+ stdio: ["ignore", "pipe", "pipe", "ipc"]
100
+ });
101
+ child.on("error", () => {
102
+ });
103
+ (0, import_session.requestSessionBrowser)(child);
104
+ const ready = new Promise((resolve) => {
105
+ const onMessage = (message) => {
106
+ if (message?.method === "ready") {
107
+ child.off("message", onMessage);
108
+ resolve(true);
109
+ }
110
+ };
111
+ child.on("message", onMessage);
112
+ child.once("exit", () => resolve(false));
113
+ });
114
+ standbys.push({ child, entryScript, env, ready });
115
+ child.unref();
116
+ child.channel?.unref?.();
117
+ }
118
+ function recordWorkerRestart(moreTestsToRun) {
119
+ restartCount++;
120
+ if (!moreTestsToRun)
121
+ return;
122
+ keepSpare = keepSpare || workerCount < cpus;
123
+ setImmediate(() => ensureStandbys(1));
124
+ }
125
+ function ensureStandbys(count, forNextPhase = false) {
126
+ if (!enabled)
127
+ return;
128
+ while (standbys.length < count)
129
+ spawnStandby(forNextPhase);
130
+ }
131
+ function ensureStandbysForConfig(configuredWorkers) {
132
+ if (enabled && !hadHint)
133
+ ensureStandbys(Math.min(configuredWorkers, cpus));
134
+ }
135
+ function retargetStandbys(argv) {
136
+ if (enabled)
137
+ hintKey = workerCountHintKey(argv);
138
+ }
139
+ function recordWorkerCount(count) {
140
+ workerCount = Math.max(workerCount, count);
141
+ }
142
+ function discardStandbys() {
143
+ for (const standby of standbys.splice(0))
144
+ release(standby.child);
145
+ }
146
+ function release(child) {
147
+ if (child.connected)
148
+ child.disconnect();
149
+ }
150
+ async function takeStandby(entryScript, env) {
151
+ const standby = standbys.shift();
152
+ if (!standby)
153
+ return;
154
+ if (keepSpare)
155
+ setImmediate(() => ensureStandbys(1));
156
+ const keys = /* @__PURE__ */ new Set([...Object.keys(env), ...Object.keys(standby.env)]);
157
+ const compatible = standby.entryScript === entryScript && [...keys].every((key) => !loadTimeEnvPattern.test(key) || env[key] === standby.env[key]);
158
+ if (!compatible || !await standby.ready) {
159
+ release(standby.child);
160
+ return;
161
+ }
162
+ standby.child.ref();
163
+ standby.child.channel?.ref?.();
164
+ return standby.child;
165
+ }
166
+ var hintFile = import_path.default.join(import_os.default.tmpdir(), "flashwright-worker-hints.json");
167
+ var maxHints = 500;
168
+ function workerCountHintKey(argv) {
169
+ const configIndex = argv.findIndex((arg) => arg === "-c" || arg === "--config" || arg.startsWith("--config="));
170
+ const config = configIndex === -1 ? "" : argv[configIndex].startsWith("--config=") ? argv[configIndex] : argv[configIndex + 1];
171
+ const workers = argv.find((arg) => arg.startsWith("--workers") || arg === "-j") ?? "";
172
+ return import_crypto.default.createHash("sha1").update([process.cwd(), config, workers].join("\0")).digest("hex").slice(0, 16);
173
+ }
174
+ function readWorkerCountHints() {
175
+ try {
176
+ return JSON.parse(import_fs.default.readFileSync(hintFile, "utf8"));
177
+ } catch {
178
+ return {};
179
+ }
180
+ }
181
+ function writeWorkerCountHint() {
182
+ if (!workerCount || !hintKey)
183
+ return;
184
+ try {
185
+ const hints = readWorkerCountHints();
186
+ hints[hintKey] = { workers: workerCount, restarts: restartCount, usedAt: Date.now() };
187
+ const recent = Object.entries(hints).sort((a, b) => b[1].usedAt - a[1].usedAt).slice(0, maxHints);
188
+ const temporary = `${hintFile}.${process.pid}`;
189
+ import_fs.default.writeFileSync(temporary, JSON.stringify(Object.fromEntries(recent)));
190
+ import_fs.default.renameSync(temporary, hintFile);
191
+ } catch {
192
+ }
193
+ }
194
+ // Annotate the CommonJS export names for ESM import in node:
195
+ 0 && (module.exports = {
196
+ discardStandbys,
197
+ ensureStandbys,
198
+ ensureStandbysForConfig,
199
+ prespawnWorkerForTestCommand,
200
+ recordWorkerCount,
201
+ recordWorkerRestart,
202
+ retargetStandbys,
203
+ takeStandby,
204
+ workerEntryScript,
205
+ workerEnv
206
+ });
@@ -0,0 +1,8 @@
1
+ # packages/playwright/lib/runner/workerStandby.js
2
+ # total: 7.6 KB
3
+
4
+ ## Inlined (1)
5
+ 5.9 KB packages/playwright/src/runner/workerStandby.ts
6
+
7
+ ## External (1)
8
+ ./session
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var speculativeBrowser_exports = {};
30
+ __export(speculativeBrowser_exports, {
31
+ handBrowsersToSession: () => handBrowsersToSession,
32
+ launchSpeculativeBrowser: () => launchSpeculativeBrowser,
33
+ prepareSpeculativeContext: () => prepareSpeculativeContext,
34
+ rememberRecycledContext: () => rememberRecycledContext,
35
+ returnSpeculativeBrowser: () => returnSpeculativeBrowser,
36
+ takeSpeculativeBrowser: () => takeSpeculativeBrowser
37
+ });
38
+ module.exports = __toCommonJS(speculativeBrowser_exports);
39
+ var import_fs = __toESM(require("fs"));
40
+ var import_os = __toESM(require("os"));
41
+ var import_path = __toESM(require("path"));
42
+ var import_util = require("util");
43
+ const speculativeOptions = { handleSIGINT: false, headless: true, ...process.env.FLASHWRIGHT_ISOLATION === "strict" ? {} : { recycleContexts: true } };
44
+ const speculativeKey = /* @__PURE__ */ Symbol.for("flashwright.speculativeBrowser");
45
+ function launchSpeculativeBrowser() {
46
+ const offered = process.env.FLASHWRIGHT_SESSION_OFFER ? receiveSessionBrowser() : Promise.resolve();
47
+ const launch = offered.then(() => require("playwright-core").chromium.launch(speculativeOptions)).catch(() => void 0);
48
+ globalThis[speculativeKey] = launch;
49
+ return launch;
50
+ }
51
+ const kBrowserMessage = "__flashwright_browser__";
52
+ const offerKey = /* @__PURE__ */ Symbol.for("flashwright.browserOffer");
53
+ let offeredLastUsed = 0;
54
+ const kOfferTimeoutAfterInit = 500;
55
+ function receiveSessionBrowser() {
56
+ return new Promise((resolve) => {
57
+ let answered = false;
58
+ let timer;
59
+ const answer = () => {
60
+ answered = true;
61
+ clearTimeout(timer);
62
+ resolve();
63
+ };
64
+ const parts = {};
65
+ const onMessage = (message, handle) => {
66
+ if (message?.method === "__init__" && !answered)
67
+ timer = setTimeout(answer, kOfferTimeoutAfterInit);
68
+ if (message?.method !== kBrowserMessage || message.params.sent)
69
+ return;
70
+ if (message.params.none) {
71
+ process.off("message", onMessage);
72
+ answer();
73
+ return;
74
+ }
75
+ parts[message.params.part] = handle;
76
+ parts.metadata ??= message.params.metadata;
77
+ if (!parts.write || !parts.read || !parts.metadata)
78
+ return;
79
+ process.off("message", onMessage);
80
+ if (answered) {
81
+ void sendToRunner(parts);
82
+ return;
83
+ }
84
+ globalThis[offerKey] = parts;
85
+ offeredLastUsed = parts.metadata.lastUsed ?? 0;
86
+ process.once("exit", () => {
87
+ if (globalThis[offerKey] === parts)
88
+ killHandedOverBrowser(parts.metadata);
89
+ });
90
+ answer();
91
+ };
92
+ process.on("message", onMessage);
93
+ });
94
+ }
95
+ async function handBrowsersToSession(browser, ranTests) {
96
+ if (!process.env.FLASHWRIGHT_SESSION_HANDOFF || !process.send)
97
+ return false;
98
+ const offer = globalThis[offerKey];
99
+ if (offer) {
100
+ delete globalThis[offerKey];
101
+ await sendToRunner(offer);
102
+ }
103
+ if (!browser)
104
+ return false;
105
+ const serverBrowser = browser._connection.toImpl?.(browser);
106
+ const handoff = await serverBrowser?.handoffForSession?.().catch(() => void 0);
107
+ if (!handoff)
108
+ return false;
109
+ handoff.metadata.lastUsed = ranTests ? Date.now() : offeredLastUsed;
110
+ await sendToRunner(handoff);
111
+ return true;
112
+ }
113
+ async function sendToRunner(browser) {
114
+ const id = `${process.pid}-${browser.metadata.pid}`;
115
+ const send = (params, handle) => new Promise((resolve) => {
116
+ if (!process.connected)
117
+ return resolve(false);
118
+ process.send({ method: kBrowserMessage, params }, handle, void 0, (error) => resolve(!error));
119
+ });
120
+ if (await send({ id, part: "write", metadata: browser.metadata }, browser.write) && await send({ id, part: "read" }, browser.read)) {
121
+ await send({ id, sent: true }, void 0);
122
+ return;
123
+ }
124
+ browser.write.destroy();
125
+ browser.read.destroy();
126
+ killHandedOverBrowser(browser.metadata);
127
+ }
128
+ function killHandedOverBrowser(metadata) {
129
+ try {
130
+ process.kill(-metadata.pid, "SIGKILL");
131
+ } catch {
132
+ }
133
+ for (const directory of metadata.tempDirectories) {
134
+ try {
135
+ import_fs.default.rmSync(directory, { recursive: true, force: true, maxRetries: 5 });
136
+ } catch {
137
+ }
138
+ }
139
+ }
140
+ function prepareSpeculativeContext() {
141
+ const launch = globalThis[speculativeKey];
142
+ const hint = speculativeOptions.recycleContexts ? readContextHint() : void 0;
143
+ if (!launch || !hint)
144
+ return;
145
+ globalThis[speculativeKey] = launch.then(async (browser) => {
146
+ const serverBrowser = browser && browser._connection.toImpl?.(browser);
147
+ await serverBrowser?.prepareRecycledContext(hint.params, { storageState: hint.storageState }).catch(() => {
148
+ });
149
+ return browser;
150
+ });
151
+ }
152
+ const contextHintFile = import_path.default.join(import_os.default.tmpdir(), "flashwright-context-hints.json");
153
+ const maxContextHints = 200;
154
+ let rememberedContextHint = false;
155
+ function readContextHints() {
156
+ try {
157
+ return JSON.parse(import_fs.default.readFileSync(contextHintFile, "utf8"));
158
+ } catch {
159
+ return {};
160
+ }
161
+ }
162
+ function readContextHint() {
163
+ const key = process.env.FLASHWRIGHT_CONTEXT_HINT_KEY;
164
+ return key ? readContextHints()[key] : void 0;
165
+ }
166
+ function rememberRecycledContext(browser) {
167
+ const key = process.env.FLASHWRIGHT_CONTEXT_HINT_KEY;
168
+ const params = { ...browser._lastRecycleParams };
169
+ const storageState = !!params.storageState;
170
+ delete params.storageState;
171
+ const mayHoldSecrets = params.httpCredentials || params.extraHTTPHeaders?.length || params.proxy || params.clientCertificates?.length;
172
+ if (rememberedContextHint || !key || !Object.keys(params).length || mayHoldSecrets || !isPlainJSON(params))
173
+ return;
174
+ rememberedContextHint = true;
175
+ try {
176
+ const hints = readContextHints();
177
+ if (JSON.stringify(hints[key]?.params) === JSON.stringify(params) && hints[key]?.storageState === storageState)
178
+ return;
179
+ hints[key] = { params, storageState, usedAt: Date.now() };
180
+ const recent = Object.entries(hints).sort((a, b) => b[1].usedAt - a[1].usedAt).slice(0, maxContextHints);
181
+ const temporary = `${contextHintFile}.${process.pid}`;
182
+ import_fs.default.writeFileSync(temporary, JSON.stringify(Object.fromEntries(recent)), { mode: 384 });
183
+ import_fs.default.renameSync(temporary, contextHintFile);
184
+ } catch {
185
+ }
186
+ }
187
+ function isPlainJSON(value) {
188
+ if (value === null || ["string", "number", "boolean", "undefined"].includes(typeof value))
189
+ return true;
190
+ if (Array.isArray(value))
191
+ return value.every(isPlainJSON);
192
+ return typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype && Object.values(value).every(isPlainJSON);
193
+ }
194
+ async function returnSpeculativeBrowser() {
195
+ const launch = globalThis[speculativeKey];
196
+ if (!launch || !process.env.FLASHWRIGHT_SESSION_HANDOFF)
197
+ return;
198
+ delete globalThis[speculativeKey];
199
+ await handBrowsersToSession(await launch, false);
200
+ }
201
+ async function takeSpeculativeBrowser(browserName, options) {
202
+ const launch = globalThis[speculativeKey];
203
+ if (!launch)
204
+ return;
205
+ delete globalThis[speculativeKey];
206
+ const { tracesDir, artifactsDir, ...rest } = options;
207
+ const browser = await launch;
208
+ if (!browser)
209
+ return;
210
+ const serverBrowser = browser._connection.toImpl?.(browser);
211
+ if (browserName !== "chromium" || !(0, import_util.isDeepStrictEqual)(rest, speculativeOptions) || !serverBrowser || !artifactsDir) {
212
+ browser._wrapApiCall(() => browser.close(), { internal: true }).catch(() => {
213
+ });
214
+ return;
215
+ }
216
+ await serverBrowser.setOutputDirs(artifactsDir, tracesDir || artifactsDir);
217
+ browser._connectToBrowserType(browser.browserType(), options, void 0);
218
+ return browser;
219
+ }
220
+ // Annotate the CommonJS export names for ESM import in node:
221
+ 0 && (module.exports = {
222
+ handBrowsersToSession,
223
+ launchSpeculativeBrowser,
224
+ prepareSpeculativeContext,
225
+ rememberRecycledContext,
226
+ returnSpeculativeBrowser,
227
+ takeSpeculativeBrowser
228
+ });