flashwright 1.64.1-flashwright.2 → 1.64.1-flashwright.3

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/lib/codeCache.js CHANGED
@@ -41,7 +41,14 @@ var import_path = __toESM(require("path"));
41
41
  var import_vm = __toESM(require("vm"));
42
42
  var minimumSize = 32 * 1024;
43
43
  var pending = [];
44
+ var loaded = [];
44
45
  var installed = false;
46
+ var ranTests = false;
47
+ var refreshAtExit = false;
48
+ globalThis[/* @__PURE__ */ Symbol.for("flashwright.codeCache")] = {
49
+ ranTests: () => ranTests = true,
50
+ refreshAtExit: () => refreshAtExit = true
51
+ };
45
52
  function installCodeCache(role) {
46
53
  if (installed || process.env.NODE_DISABLE_COMPILE_CACHE || process.env.FLASHWRIGHT_DISABLE_CODE_CACHE || process.env.NODE_V8_COVERAGE)
47
54
  return;
@@ -50,6 +57,7 @@ function installCodeCache(role) {
50
57
  if (!importModuleDynamically || typeof originalCompile !== "function")
51
58
  return;
52
59
  installed = true;
60
+ ranTests = ranTests || role === "cli";
53
61
  silenceDefaultLoaderWarning(importModuleDynamically);
54
62
  const roots = packageLibDirs();
55
63
  const cacheDir = import_path.default.join(import_os.default.tmpdir(), "flashwright-code-cache", `${process.version}-${process.arch}`, role);
@@ -101,6 +109,8 @@ function compileWithCache(content, filename, cacheDir, importModuleDynamically)
101
109
  const script = new import_vm.default.Script(import_module.default.wrap(content), { filename, cachedData, importModuleDynamically });
102
110
  if (!cachedData || script.cachedDataRejected)
103
111
  pending.push({ script, cacheFile, staleFiles: staleCacheFiles(cacheDir, fileKey, cacheFile) });
112
+ else
113
+ loaded.push({ script, cacheFile, size: cachedData.length });
104
114
  return script.runInThisContext({ displayErrors: true });
105
115
  }
106
116
  function staleCacheFiles(cacheDir, fileKey, cacheFile) {
@@ -121,16 +131,27 @@ function makeRequireFunction(mod) {
121
131
  return require2;
122
132
  }
123
133
  function writeCodeCaches() {
124
- for (const { script, cacheFile, staleFiles } of pending.splice(0)) {
125
- try {
126
- import_fs.default.mkdirSync(import_path.default.dirname(cacheFile), { recursive: true });
127
- const temporary = `${cacheFile}.${process.pid}`;
128
- import_fs.default.writeFileSync(temporary, script.createCachedData());
129
- import_fs.default.renameSync(temporary, cacheFile);
130
- for (const file of staleFiles)
131
- import_fs.default.rmSync(file, { force: true });
132
- } catch {
133
- }
134
+ if (!ranTests)
135
+ return;
136
+ for (const { script, cacheFile, staleFiles } of pending.splice(0))
137
+ writeCodeCache(cacheFile, script.createCachedData(), staleFiles);
138
+ if (!refreshAtExit)
139
+ return;
140
+ for (const { script, cacheFile, size } of loaded.splice(0)) {
141
+ const data = script.createCachedData();
142
+ if (data.length > size * 1.1)
143
+ writeCodeCache(cacheFile, data, []);
144
+ }
145
+ }
146
+ function writeCodeCache(cacheFile, data, staleFiles) {
147
+ try {
148
+ import_fs.default.mkdirSync(import_path.default.dirname(cacheFile), { recursive: true });
149
+ const temporary = `${cacheFile}.${process.pid}`;
150
+ import_fs.default.writeFileSync(temporary, data);
151
+ import_fs.default.renameSync(temporary, cacheFile);
152
+ for (const file of staleFiles)
153
+ import_fs.default.rmSync(file, { force: true });
154
+ } catch {
134
155
  }
135
156
  }
136
157
  if (/workerProcessEntry\.js$/.test(process.argv[1] || ""))
@@ -1,8 +1,8 @@
1
1
  # packages/playwright/lib/codeCache.js
2
- # total: 6.4 KB
2
+ # total: 7.0 KB
3
3
 
4
4
  ## Inlined (1)
5
- 4.9 KB packages/playwright/src/codeCache.ts
5
+ 5.5 KB packages/playwright/src/codeCache.ts
6
6
 
7
7
  ## External (1)
8
8
  playwright-core/package.json
@@ -40,6 +40,7 @@ __export(index_exports, {
40
40
  fixtures: () => fixtures_exports,
41
41
  ipc: () => ipc_exports,
42
42
  mergeTests: () => mergeTests,
43
+ originalProcessExit: () => originalProcessExit,
43
44
  poolBuilder: () => poolBuilder_exports,
44
45
  processRunner: () => process_exports,
45
46
  startProcessRunner: () => startProcessRunner,
@@ -1920,6 +1921,7 @@ var PoolBuilder = class _PoolBuilder {
1920
1921
  var process_exports = {};
1921
1922
  __export(process_exports, {
1922
1923
  ProcessRunner: () => ProcessRunner,
1924
+ originalProcessExit: () => originalProcessExit,
1923
1925
  startProcessRunner: () => startProcessRunner
1924
1926
  });
1925
1927
  var import_bootstrap = require("playwright-core/lib/bootstrap");
@@ -1930,6 +1932,10 @@ var { setBoxedStackPrefixes } = require("playwright-core/lib/coreBundle").utils;
1930
1932
  var ProcessRunner = class {
1931
1933
  async gracefullyClose() {
1932
1934
  }
1935
+ // Flashwright: see WorkerMain.canDetachTeardown.
1936
+ canDetachTeardown() {
1937
+ return false;
1938
+ }
1933
1939
  dispatchEvent(method, params) {
1934
1940
  const response = { method, params };
1935
1941
  sendMessageToParent({ method: "__dispatch__", params: response });
@@ -1946,6 +1952,7 @@ var gracefullyCloseCalled = false;
1946
1952
  var forceExitInitiated = false;
1947
1953
  var processRunner;
1948
1954
  var startingEnv = { ...process.env };
1955
+ var originalProcessExit = process.exit;
1949
1956
  setBoxedStackPrefixes([import_package4.packageRoot]);
1950
1957
  function startProcessRunner(create) {
1951
1958
  sendMessageToParent({ method: "ready" });
@@ -1969,6 +1976,10 @@ function startProcessRunner(create) {
1969
1976
  const keys = /* @__PURE__ */ new Set([...Object.keys(process.env), ...Object.keys(startingEnv)]);
1970
1977
  const producedEnv = [...keys].filter((key) => startingEnv[key] !== process.env[key]).map((key) => [key, process.env[key] ?? null]);
1971
1978
  sendMessageToParent({ method: "__env_produced__", params: producedEnv });
1979
+ if (processRunner?.canDetachTeardown()) {
1980
+ sendMessageToParent({ method: "__teardown_detached__" });
1981
+ globalThis[/* @__PURE__ */ Symbol.for("flashwright.codeCache")]?.refreshAtExit();
1982
+ }
1972
1983
  await gracefullyCloseAndExit(false);
1973
1984
  return;
1974
1985
  }
@@ -2963,6 +2974,7 @@ function serializeLoadError(file2, error) {
2963
2974
  fixtures,
2964
2975
  ipc,
2965
2976
  mergeTests,
2977
+ originalProcessExit,
2966
2978
  poolBuilder,
2967
2979
  processRunner,
2968
2980
  startProcessRunner,
@@ -1,5 +1,5 @@
1
1
  # packages/playwright/lib/common/index.js
2
- # total: 115.2 KB
2
+ # total: 115.6 KB
3
3
 
4
4
  ## Inlined (20)
5
5
  12.6 KB packages/playwright/src/common/config.ts
@@ -8,7 +8,7 @@
8
8
  0.8 KB packages/playwright/src/common/index.ts
9
9
  1.3 KB packages/playwright/src/common/ipc.ts
10
10
  2.1 KB packages/playwright/src/common/poolBuilder.ts
11
- 4.4 KB packages/playwright/src/common/process.ts
11
+ 4.8 KB packages/playwright/src/common/process.ts
12
12
  4.9 KB packages/playwright/src/common/suiteUtils.ts
13
13
  8.7 KB packages/playwright/src/common/test.ts
14
14
  2.0 KB packages/playwright/src/common/testLoader.ts
@@ -13160,7 +13160,7 @@ function indent2(snapshot, indent3) {
13160
13160
  }
13161
13161
 
13162
13162
  // packages/playwright/src/matchers/expect.ts
13163
- var { parseStackFrame, captureRawStack } = require("playwright-core/lib/coreBundle").utils;
13163
+ var { captureFilteredStackTrace, captureRawStack, filteredStackTrace, parseStackFrame } = require("playwright-core/lib/coreBundle").utils;
13164
13164
  var { escapeWithQuotes, isString: isString4 } = require("playwright-core/lib/coreBundle").iso;
13165
13165
  var { pollAgainstDeadline: pollAgainstDeadline2 } = require("playwright-core/lib/coreBundle").iso;
13166
13166
  var { currentZone } = require("playwright-core/lib/coreBundle").utils;
@@ -13313,7 +13313,8 @@ function callMatcherAsStep(matcherName, info, actual, matcher, args, promise) {
13313
13313
  const suffixes = computeMatcherTitleSuffix(matcherName, actual, args);
13314
13314
  const defaultTitle = `${info.poll ? "poll " : ""}${info.isSoft ? "soft " : ""}${info.isNot ? "not " : ""}${matcherName}${suffixes.titleSuffix || ""}`;
13315
13315
  const title = customMessage || `Expect ${escapeWithQuotes(defaultTitle, '"')}`;
13316
- const stackFrames = expectConfig().filteredStackTrace(captureRawStack());
13316
+ const filter = expectConfig().filteredStackTrace;
13317
+ const stackFrames = filter === filteredStackTrace ? captureFilteredStackTrace() : filter(captureRawStack());
13317
13318
  const params = { ...suffixes.params };
13318
13319
  if (args[0])
13319
13320
  params.expected = args[0];
@@ -1,5 +1,5 @@
1
1
  # packages/playwright/lib/matchers/expect.js
2
- # total: 534.4 KB
2
+ # total: 534.5 KB
3
3
 
4
4
  ## Inlined (59)
5
5
  7.9 KB node_modules/@babel/code-frame/lib/index.js
@@ -51,7 +51,7 @@
51
51
  7.6 KB node_modules/stack-utils/index.js
52
52
  0.4 KB node_modules/stack-utils/node_modules/escape-string-regexp/index.js
53
53
  3.1 KB node_modules/supports-color/index.js
54
- 10.3 KB packages/playwright/src/matchers/expect.ts
54
+ 10.4 KB packages/playwright/src/matchers/expect.ts
55
55
  45.3 KB packages/playwright/src/matchers/expectLibrary.ts
56
56
  3.3 KB packages/playwright/src/matchers/matcherHint.ts
57
57
  17.4 KB packages/playwright/src/matchers/matchers.ts
@@ -1901,6 +1901,7 @@ var debug3 = require("playwright-core/lib/utilsBundle").debug;
1901
1901
  var { assert } = require("playwright-core/lib/coreBundle").iso;
1902
1902
  var { monotonicTime: monotonicTime3, timeOrigin } = require("playwright-core/lib/coreBundle").iso;
1903
1903
  var { raceAgainstDeadline: raceAgainstDeadline2 } = require("playwright-core/lib/coreBundle").iso;
1904
+ var { ManualPromise: ManualPromise2 } = require("playwright-core/lib/coreBundle").iso;
1904
1905
  var { killProcessTree } = require("playwright-core/lib/coreBundle").utils;
1905
1906
  var ProcessHost = class extends import_events.EventEmitter {
1906
1907
  constructor(entryScript, processName, env) {
@@ -1912,6 +1913,8 @@ var ProcessHost = class extends import_events.EventEmitter {
1912
1913
  this._callbacks = /* @__PURE__ */ new Map();
1913
1914
  this._producedEnv = {};
1914
1915
  this._requestHandlers = /* @__PURE__ */ new Map();
1916
+ // Flashwright: resolved when a stopping worker says that it can finish on its own (see stop).
1917
+ this._teardownDetached = new ManualPromise2();
1915
1918
  this._entryScript = entryScript;
1916
1919
  this._processName = processName;
1917
1920
  this._extraEnv = env;
@@ -1951,7 +1954,9 @@ var ProcessHost = class extends import_events.EventEmitter {
1951
1954
  return;
1952
1955
  if (debug3.enabled("pw:test:protocol"))
1953
1956
  debug3("pw:test:protocol")("\u25C0 RECV " + JSON.stringify(message));
1954
- if (message.method === "__env_produced__") {
1957
+ if (message.method === "__teardown_detached__") {
1958
+ this._teardownDetached.resolve(true);
1959
+ } else if (message.method === "__env_produced__") {
1955
1960
  const producedEnv = message.params;
1956
1961
  this._producedEnv = Object.fromEntries(producedEnv.map((e) => [e[0], e[1] ?? void 0]));
1957
1962
  } else if (message.method === "__dispatch__") {
@@ -2028,14 +2033,18 @@ var ProcessHost = class extends import_events.EventEmitter {
2028
2033
  onRequest(method, handler) {
2029
2034
  this._requestHandlers.set(method, handler);
2030
2035
  }
2031
- async stop() {
2036
+ // Flashwright: with `detachTeardown`, also returns once the process says that what it has left to
2037
+ // do cannot change the run's outcome (see WorkerMain.canDetachTeardown); the warm session's
2038
+ // runner waits for it to exit before it exits itself.
2039
+ async stop(options = {}) {
2032
2040
  if (!this._processDidExit && !this._didSendStop) {
2033
2041
  this.send({ method: "__stop__" });
2034
2042
  this._didSendStop = true;
2035
2043
  }
2036
2044
  if (this._didExitAndRanOnExit)
2037
2045
  return;
2038
- const exitPromise = new Promise((f) => this.once("exit", () => f()));
2046
+ const exited = new Promise((f) => this.once("exit", () => f(false)));
2047
+ const exitPromise = options.detachTeardown ? Promise.race([exited, this._teardownDetached]) : exited;
2039
2048
  const timeout = +(process.env.PWTEST_CHILD_PROCESS_TIMEOUT || 5 * 60 * 1e3);
2040
2049
  let lastHeartbeat = monotonicTime3();
2041
2050
  const onHeartbeat = () => lastHeartbeat = monotonicTime3();
@@ -2043,8 +2052,11 @@ var ProcessHost = class extends import_events.EventEmitter {
2043
2052
  try {
2044
2053
  while (true) {
2045
2054
  const result = await raceAgainstDeadline2(() => exitPromise, lastHeartbeat + timeout);
2046
- if (!result.timedOut)
2055
+ if (!result.timedOut) {
2056
+ if (result.result)
2057
+ (0, import_session.trackDetachedTeardown)(exited);
2047
2058
  return;
2059
+ }
2048
2060
  if (monotonicTime3() < lastHeartbeat + timeout)
2049
2061
  continue;
2050
2062
  this.emit("processError", { message: `Error: ${this._processName} process did not exit within ${timeout}ms after stop, force-killed it` });
@@ -3092,7 +3104,7 @@ var TeleReporterEmitter = class {
3092
3104
  // packages/playwright/src/reporters/blob.ts
3093
3105
  var mime = require("playwright-core/lib/utilsBundle").mime;
3094
3106
  var yazl = require("playwright-core/lib/utilsBundle").yazl;
3095
- var { ManualPromise: ManualPromise2 } = require("playwright-core/lib/coreBundle").iso;
3107
+ var { ManualPromise: ManualPromise3 } = require("playwright-core/lib/coreBundle").iso;
3096
3108
  var { calculateSha1: calculateSha12, createGuid: createGuid2 } = require("playwright-core/lib/coreBundle").utils;
3097
3109
  var { removeFolders, sanitizeForFilePath } = require("playwright-core/lib/coreBundle").utils;
3098
3110
  var currentBlobReportVersion = 2;
@@ -3128,7 +3140,7 @@ var BlobReporter = class extends TeleReporterEmitter {
3128
3140
  await super.onEnd(result);
3129
3141
  const zipFileName = await this._prepareOutputFile();
3130
3142
  const zipFile = new yazl.ZipFile();
3131
- const zipFinishPromise = new ManualPromise2();
3143
+ const zipFinishPromise = new ManualPromise3();
3132
3144
  const finishPromise = zipFinishPromise.catch((e) => {
3133
3145
  throw new Error(`Failed to write report ${zipFileName}: ` + e.message);
3134
3146
  });
@@ -5677,10 +5689,10 @@ var WorkerHost = class extends ProcessHost {
5677
5689
  async onExit() {
5678
5690
  await removeFolders3([this._params.artifactsDir]);
5679
5691
  }
5680
- async stop(didFail) {
5681
- if (didFail)
5692
+ async stop(options = {}) {
5693
+ if (options.didFail)
5682
5694
  this._didFail = true;
5683
- await super.stop();
5695
+ await super.stop(options);
5684
5696
  }
5685
5697
  runTestGroup(runPayload) {
5686
5698
  this.sendMessageNoReply({ method: "runTestGroup", params: runPayload });
@@ -5707,7 +5719,7 @@ var import_workerStandby2 = require("./workerStandby");
5707
5719
  var import_common7 = require("../common");
5708
5720
  var import_util13 = require("../util");
5709
5721
  var colors4 = require("playwright-core/lib/utilsBundle").colors;
5710
- var { ManualPromise: ManualPromise3 } = require("playwright-core/lib/coreBundle").iso;
5722
+ var { ManualPromise: ManualPromise4 } = require("playwright-core/lib/coreBundle").iso;
5711
5723
  var { eventsHelper } = require("playwright-core/lib/coreBundle").utils;
5712
5724
  var Dispatcher = class {
5713
5725
  constructor(testRun, options = {}) {
@@ -5717,7 +5729,7 @@ var Dispatcher = class {
5717
5729
  this._isolatedJobs = /* @__PURE__ */ new Set();
5718
5730
  this._workerLimitPerProjectId = /* @__PURE__ */ new Map();
5719
5731
  this._queuedOrRunningHashCount = /* @__PURE__ */ new Map();
5720
- this._finished = new ManualPromise3();
5732
+ this._finished = new ManualPromise4();
5721
5733
  this._isStopped = true;
5722
5734
  this._extraEnvByProjectId = /* @__PURE__ */ new Map();
5723
5735
  this._producedEnvByProjectId = /* @__PURE__ */ new Map();
@@ -5808,10 +5820,7 @@ var Dispatcher = class {
5808
5820
  const result = await jobDispatcher.jobResult;
5809
5821
  this._updateCounterForWorkerHash(job.workerHash, -1);
5810
5822
  if (result.didFail) {
5811
- void worker.stop(
5812
- true
5813
- /* didFail */
5814
- );
5823
+ void worker.stop({ didFail: true });
5815
5824
  (0, import_workerStandby2.recordWorkerRestart)(!!result.remainingJob || !!this._queue.length);
5816
5825
  } else if (this._isWorkerRedundant(worker)) {
5817
5826
  void worker.stop();
@@ -5918,17 +5927,17 @@ var Dispatcher = class {
5918
5927
  producedEnvByProjectId() {
5919
5928
  return this._producedEnvByProjectId;
5920
5929
  }
5921
- async stop() {
5930
+ async stop(options) {
5922
5931
  if (this._isStopped)
5923
5932
  return;
5924
5933
  this._isStopped = true;
5925
- await Promise.all(this._workerSlots.map(({ worker }) => worker?.stop()));
5934
+ await Promise.all(this._workerSlots.map(({ worker }) => worker?.stop(options)));
5926
5935
  this._checkFinished();
5927
5936
  }
5928
5937
  };
5929
5938
  var JobDispatcher = class {
5930
5939
  constructor(job, testRun, onMaxFailuresReached) {
5931
- this.jobResult = new ManualPromise3();
5940
+ this.jobResult = new ManualPromise4();
5932
5941
  this._listeners = [];
5933
5942
  this._failedTests = /* @__PURE__ */ new Set();
5934
5943
  this._failedWithNonRetriableError = /* @__PURE__ */ new Set();
@@ -6245,6 +6254,7 @@ function chunkFromParams(params) {
6245
6254
 
6246
6255
  // packages/playwright/src/runner/tasks.ts
6247
6256
  var import_workerStandby3 = require("./workerStandby");
6257
+ var import_session2 = require("./session");
6248
6258
 
6249
6259
  // packages/playwright/src/runner/sigIntWatcher.ts
6250
6260
  var SigIntWatcher = class {
@@ -6321,7 +6331,7 @@ var FixedNodeSIGINTHandler = class {
6321
6331
  var import_util14 = require("../util");
6322
6332
  var colors5 = require("playwright-core/lib/utilsBundle").colors;
6323
6333
  var debug4 = require("playwright-core/lib/utilsBundle").debug;
6324
- var { ManualPromise: ManualPromise4 } = require("playwright-core/lib/coreBundle").iso;
6334
+ var { ManualPromise: ManualPromise5 } = require("playwright-core/lib/coreBundle").iso;
6325
6335
  var { monotonicTime: monotonicTime4 } = require("playwright-core/lib/coreBundle").iso;
6326
6336
  var TaskRunner = class _TaskRunner {
6327
6337
  constructor(reporter, globalTimeoutForError) {
@@ -6340,7 +6350,7 @@ var TaskRunner = class _TaskRunner {
6340
6350
  const teardownStatus = await cleanup();
6341
6351
  return status === "passed" ? teardownStatus : status;
6342
6352
  }
6343
- async runDeferCleanup(context, deadline, cancelPromise = new ManualPromise4()) {
6353
+ async runDeferCleanup(context, deadline, cancelPromise = new ManualPromise5()) {
6344
6354
  const sigintWatcher = new SigIntWatcher();
6345
6355
  const timeoutWatcher = new TimeoutWatcher(deadline);
6346
6356
  const teardownRunner = new _TaskRunner(this._reporter, this._globalTimeoutForError);
@@ -6398,7 +6408,7 @@ var TaskRunner = class _TaskRunner {
6398
6408
  var TimeoutWatcher = class {
6399
6409
  constructor(deadline) {
6400
6410
  this._timedOut = false;
6401
- this.promise = new ManualPromise4();
6411
+ this.promise = new ManualPromise5();
6402
6412
  if (!deadline)
6403
6413
  return;
6404
6414
  if (deadline - monotonicTime4() <= 0) {
@@ -6522,7 +6532,7 @@ function orderTestGroupsByDuration(testGroups, durations) {
6522
6532
  // packages/playwright/src/runner/tasks.ts
6523
6533
  var import_util16 = require("../util");
6524
6534
  var debug5 = require("playwright-core/lib/utilsBundle").debug;
6525
- var { ManualPromise: ManualPromise5 } = require("playwright-core/lib/coreBundle").iso;
6535
+ var { ManualPromise: ManualPromise6 } = require("playwright-core/lib/coreBundle").iso;
6526
6536
  var { monotonicTime: monotonicTime5 } = require("playwright-core/lib/coreBundle").iso;
6527
6537
  var { removeFolders: removeFolders4 } = require("playwright-core/lib/coreBundle").utils;
6528
6538
  var readDirAsync2 = (0, import_util15.promisify)(import_fs14.default.readdir);
@@ -6858,7 +6868,8 @@ function createRunTestsTask() {
6858
6868
  orderTestGroupsByDuration(phaseTestGroups, durations);
6859
6869
  if (phaseTestGroups.length) {
6860
6870
  await dispatcher.run(phaseTestGroups, extraEnvByProjectId);
6861
- await dispatcher.stop();
6871
+ globalThis[/* @__PURE__ */ Symbol.for("flashwright.codeCache")]?.ranTests();
6872
+ await dispatcher.stop({ detachTeardown: !nextPhase && (0, import_session2.isWarmSessionRun)() });
6862
6873
  for (const [projectId, envProduced] of dispatcher.producedEnvByProjectId()) {
6863
6874
  const extraEnv = extraEnvByProjectId.get(projectId) || {};
6864
6875
  extraEnvByProjectId.set(projectId, { ...extraEnv, ...envProduced });
@@ -6936,7 +6947,7 @@ var LastRunReporter = class {
6936
6947
  };
6937
6948
 
6938
6949
  // packages/playwright/src/runner/testRunner.ts
6939
- var { ManualPromise: ManualPromise6 } = require("playwright-core/lib/coreBundle").iso;
6950
+ var { ManualPromise: ManualPromise7 } = require("playwright-core/lib/coreBundle").iso;
6940
6951
  var { setPlaywrightTestProcessEnv } = require("playwright-core/lib/coreBundle").utils;
6941
6952
  var { gracefullyProcessExitDoNotHang: gracefullyProcessExitDoNotHang2 } = require("playwright-core/lib/coreBundle").utils;
6942
6953
  var TestRunnerEvent = {
@@ -7139,7 +7150,7 @@ var TestRunner = class extends import_events3.default {
7139
7150
  };
7140
7151
  const configReporters = params.disableConfigReporters ? [] : await createReporters(config2, "test", void 0, options);
7141
7152
  const reporter = new InternalReporter([...configReporters, userReporter]);
7142
- const stop = new ManualPromise6();
7153
+ const stop = new ManualPromise7();
7143
7154
  const testRun = new TestRun(config2, reporter, options);
7144
7155
  if (params.testIds) {
7145
7156
  const testIdSet = new Set(params.testIds);
@@ -7273,7 +7284,7 @@ var uiModeReporter_default = UIModeReporter;
7273
7284
  // packages/playwright/src/runner/testServer.ts
7274
7285
  var debug6 = require("playwright-core/lib/utilsBundle").debug;
7275
7286
  var open2 = require("playwright-core/lib/utilsBundle").open;
7276
- var { ManualPromise: ManualPromise7 } = require("playwright-core/lib/coreBundle").iso;
7287
+ var { ManualPromise: ManualPromise8 } = require("playwright-core/lib/coreBundle").iso;
7277
7288
  var { isUnderTest } = require("playwright-core/lib/coreBundle").utils;
7278
7289
  var { HttpServer: HttpServer2 } = require("playwright-core/lib/coreBundle").utils;
7279
7290
  var { gracefullyProcessExitDoNotHang: gracefullyProcessExitDoNotHang3 } = require("playwright-core/lib/coreBundle").utils;
@@ -7480,7 +7491,7 @@ async function runTestServer(configFile, configCLIOverrides, options) {
7480
7491
  }
7481
7492
  async function innerRunTestServer(configLocation, configCLIOverrides, options, openUI) {
7482
7493
  const testServer = new TestServer(configLocation, configCLIOverrides);
7483
- const cancelPromise = new ManualPromise7();
7494
+ const cancelPromise = new ManualPromise8();
7484
7495
  const sigintWatcher = new SigIntWatcher();
7485
7496
  process.stdin.on("close", () => gracefullyProcessExitDoNotHang3(0));
7486
7497
  void sigintWatcher.promise().then(() => cancelPromise.resolve());
@@ -7856,7 +7867,7 @@ var TestServerConnection = class {
7856
7867
  // packages/playwright/src/runner/watchMode.ts
7857
7868
  var colors6 = require("playwright-core/lib/utilsBundle").colors;
7858
7869
  var enquirer = require("playwright-core/lib/utilsBundle").enquirer;
7859
- var { ManualPromise: ManualPromise8 } = require("playwright-core/lib/coreBundle").iso;
7870
+ var { ManualPromise: ManualPromise9 } = require("playwright-core/lib/coreBundle").iso;
7860
7871
  var { createGuid: createGuid3 } = require("playwright-core/lib/coreBundle").utils;
7861
7872
  var { getPackageManagerExecCommand: getPackageManagerExecCommand3 } = require("playwright-core/lib/coreBundle").utils;
7862
7873
  var { eventsHelper: eventsHelper2 } = require("playwright-core/lib/coreBundle").utils;
@@ -7907,7 +7918,7 @@ async function runWatchModeLoop(configLocation, initialOptions) {
7907
7918
  } });
7908
7919
  const dirtyTestFiles = /* @__PURE__ */ new Set();
7909
7920
  const dirtyTestIds = /* @__PURE__ */ new Set();
7910
- let onDirtyTests = new ManualPromise8();
7921
+ let onDirtyTests = new ManualPromise9();
7911
7922
  let queue = Promise.resolve();
7912
7923
  const changedFiles = /* @__PURE__ */ new Set();
7913
7924
  testServerConnection.onTestFilesChanged(({ testFiles }) => {
@@ -7926,7 +7937,7 @@ async function runWatchModeLoop(configLocation, initialOptions) {
7926
7937
  changedFiles.clear();
7927
7938
  if (dirtyTestIds.size > 0) {
7928
7939
  onDirtyTests.resolve("changed");
7929
- onDirtyTests = new ManualPromise8();
7940
+ onDirtyTests = new ManualPromise9();
7930
7941
  }
7931
7942
  });
7932
7943
  });
@@ -8053,7 +8064,7 @@ async function runWatchModeLoop(configLocation, initialOptions) {
8053
8064
  return result === "passed" ? teardown.status : result;
8054
8065
  }
8055
8066
  function readKeyPress(handler) {
8056
- const promise = new ManualPromise8();
8067
+ const promise = new ManualPromise9();
8057
8068
  const rl = import_readline.default.createInterface({ input: process.stdin, escapeCodeTimeout: 50 });
8058
8069
  import_readline.default.emitKeypressEvents(process.stdin, rl);
8059
8070
  if (process.stdin.isTTY)
@@ -1,5 +1,5 @@
1
1
  # packages/playwright/lib/runner/index.js
2
- # total: 321.4 KB
2
+ # total: 322.4 KB
3
3
 
4
4
  ## Inlined (49)
5
5
  1.3 KB packages/playwright/src/isomorphic/events.ts
@@ -35,14 +35,14 @@
35
35
  1.7 KB packages/playwright/src/runner/lastRun.ts
36
36
  1.6 KB packages/playwright/src/runner/loaderHost.ts
37
37
  13.3 KB packages/playwright/src/runner/loadUtils.ts
38
- 6.5 KB packages/playwright/src/runner/processHost.ts
38
+ 7.3 KB packages/playwright/src/runner/processHost.ts
39
39
  7.9 KB packages/playwright/src/runner/projectUtils.ts
40
40
  5.5 KB packages/playwright/src/runner/rebase.ts
41
41
  3.4 KB packages/playwright/src/runner/reporters.ts
42
42
  2.4 KB packages/playwright/src/runner/reporterTestRun.ts
43
43
  1.6 KB packages/playwright/src/runner/sigIntWatcher.ts
44
44
  3.5 KB packages/playwright/src/runner/taskRunner.ts
45
- 15.9 KB packages/playwright/src/runner/tasks.ts
45
+ 16.1 KB packages/playwright/src/runner/tasks.ts
46
46
  2.6 KB packages/playwright/src/runner/testDurations.ts
47
47
  4.4 KB packages/playwright/src/runner/testGroups.ts
48
48
  13.2 KB packages/playwright/src/runner/testRunner.ts
@@ -31,17 +31,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var session_exports = {};
32
32
  __export(session_exports, {
33
33
  flushSessionBrowsers: () => flushSessionBrowsers,
34
+ isWarmSessionRun: () => isWarmSessionRun,
34
35
  receiveWorkerMessage: () => receiveWorkerMessage,
35
36
  requestSessionBrowser: () => requestSessionBrowser,
36
37
  runCli: () => runCli,
37
38
  sessionStandbyEnv: () => sessionStandbyEnv,
39
+ trackDetachedTeardown: () => trackDetachedTeardown,
38
40
  trackSessionWorker: () => trackSessionWorker
39
41
  });
40
42
  module.exports = __toCommonJS(session_exports);
41
- var import_child_process = __toESM(require("child_process"));
42
- var import_crypto = __toESM(require("crypto"));
43
43
  var import_fs = __toESM(require("fs"));
44
- var import_inspector = __toESM(require("inspector"));
45
44
  var import_net = __toESM(require("net"));
46
45
  var import_os = __toESM(require("os"));
47
46
  var import_path = __toESM(require("path"));
@@ -84,17 +83,26 @@ function runLocally(argv, hooks, startSessionWith) {
84
83
  hooks.loadProgram().parse(argv);
85
84
  }
86
85
  function sessionRequested() {
87
- if (process.env.PWDEBUG || process.env.PWTEST_WATCH || import_inspector.default.url() || process.platform === "win32")
86
+ if (process.env.PWDEBUG || process.env.PWTEST_WATCH || debuggerAttached() || process.platform === "win32")
88
87
  return false;
89
88
  const value = process.env.FLASHWRIGHT_SESSION;
90
89
  if (value)
91
90
  return value !== "0" && value !== "false";
92
91
  return !process.env.CI;
93
92
  }
93
+ function debuggerAttached() {
94
+ if (!process.execArgv.length && !process.env.NODE_OPTIONS)
95
+ return false;
96
+ return !!require("inspector").url();
97
+ }
98
+ function childProcess() {
99
+ return require("child_process");
100
+ }
94
101
  function buildStamp() {
95
102
  const files = ["program.js", "common/index.js", "runner/index.js", "runner/session.js", "worker/workerProcessEntry.js"].map((file) => import_path.default.join(__dirname, "..", file));
103
+ const coreBundle = import_path.default.join(__dirname, "..", "..", "..", "playwright-core", "lib", "coreBundle.js");
96
104
  try {
97
- files.push(require.resolve("playwright-core/lib/coreBundle"));
105
+ files.push(import_fs.default.existsSync(coreBundle) ? coreBundle : require.resolve("playwright-core/lib/coreBundle"));
98
106
  } catch {
99
107
  }
100
108
  return files.map((file) => {
@@ -135,7 +143,7 @@ function createRequest(argv) {
135
143
  }
136
144
  function warmKey(request) {
137
145
  const env = Object.entries(stableEnv(request.env)).sort(([a], [b]) => a < b ? -1 : 1);
138
- return import_crypto.default.createHash("sha1").update(JSON.stringify([env, request.execPath, request.execArgv, request.cliPath, request.build, request.profile])).digest("hex");
146
+ return require("crypto").createHash("sha1").update(JSON.stringify([env, request.execPath, request.execArgv, request.cliPath, request.build, request.profile])).digest("hex");
139
147
  }
140
148
  function sessionSocketPath(cwd) {
141
149
  const uid = import_os.default.userInfo().uid;
@@ -151,10 +159,16 @@ function sessionSocketPath(cwd) {
151
159
  } catch {
152
160
  return;
153
161
  }
154
- const id = import_crypto.default.createHash("sha1").update([import_path.default.join(__dirname, ".."), process.execPath, cwd].join("\0")).digest("hex").slice(0, 16);
162
+ const id = fnv1a64([import_path.default.join(__dirname, ".."), process.execPath, cwd].join("\0"));
155
163
  const socketFile = import_path.default.join(directory, `${id}.sock`);
156
164
  return Buffer.byteLength(socketFile) < 100 ? socketFile : void 0;
157
165
  }
166
+ function fnv1a64(text) {
167
+ let hash = 0xcbf29ce484222325n;
168
+ for (const byte of Buffer.from(text))
169
+ hash = BigInt.asUintN(64, (hash ^ BigInt(byte)) * 0x100000001b3n);
170
+ return hash.toString(16).padStart(16, "0");
171
+ }
158
172
  function runInSession(request) {
159
173
  const socketFile = sessionSocketPath(request.cwd);
160
174
  if (!socketFile)
@@ -217,7 +231,7 @@ function startSession(request) {
217
231
  const socketFile = sessionSocketPath(request.cwd);
218
232
  if (!socketFile)
219
233
  return;
220
- const child = import_child_process.default.spawn(process.execPath, [__filename, "--flashwright-session", socketFile, request.build], {
234
+ const child = childProcess().spawn(process.execPath, [__filename, "--flashwright-session", socketFile, request.build], {
221
235
  detached: true,
222
236
  stdio: ["ignore", "ignore", "ignore", "ipc"],
223
237
  env: { ...process.env, FLASHWRIGHT_SESSION_ROLE: "session" }
@@ -279,19 +293,27 @@ function forwardBrowser(browser) {
279
293
  }
280
294
  pendingSends.add(sendBrowser(sessionChannel, browser));
281
295
  }
296
+ function isWarmSessionRun() {
297
+ return !!outputBytes;
298
+ }
299
+ var detachedTeardowns = /* @__PURE__ */ new Set();
300
+ function trackDetachedTeardown(exited) {
301
+ detachedTeardowns.add(exited);
302
+ void exited.finally(() => detachedTeardowns.delete(exited));
303
+ }
282
304
  async function flushSessionBrowsers(exitCode) {
283
305
  if (!sessionChannel)
284
306
  return;
307
+ if (outputBytes && exitCode !== void 0 && sessionChannel.connected)
308
+ await new Promise((resolve) => sessionChannel.send({ type: "exiting", code: exitCode, ...outputBytes }, void 0, resolve));
285
309
  await Promise.all([...sessionStandbys].map(returnStandbyBrowser));
286
310
  const deadline = Date.now() + 2e3;
287
- while (sessionWorkers.size && Date.now() < deadline)
288
- await new Promise((resolve) => setTimeout(resolve, 5));
311
+ while ((sessionWorkers.size || detachedTeardowns.size) && Date.now() < deadline)
312
+ await Promise.race([...detachedTeardowns, new Promise((resolve) => setTimeout(resolve, 5))]);
289
313
  await Promise.all(pendingSends);
290
314
  for (const parts of workerParts.values())
291
315
  killBrowser(parts);
292
316
  workerParts.clear();
293
- if (outputBytes && exitCode !== void 0 && sessionChannel.connected)
294
- await new Promise((resolve) => sessionChannel.send({ type: "exiting", code: exitCode, ...outputBytes }, void 0, resolve));
295
317
  if (sessionChannel.connected)
296
318
  sessionChannel.disconnect();
297
319
  }
@@ -485,7 +507,7 @@ function runSession(socketFile, build) {
485
507
  if (warmProcesses.some((warm2) => warm2.key === key && !warm2.running))
486
508
  return;
487
509
  const standbys = browsers.filter((browser) => browser.key === key).length;
488
- const child = import_child_process.default.spawn(request.execPath, [...request.execArgv, request.cliPath, ...request.argv.slice(2)], {
510
+ const child = childProcess().spawn(request.execPath, [...request.execArgv, request.cliPath, ...request.argv.slice(2)], {
489
511
  cwd: request.cwd,
490
512
  env: { ...warmEnv(request), FLASHWRIGHT_SESSION_ROLE: "warm", FLASHWRIGHT_SESSION_STANDBYS: String(standbys) },
491
513
  stdio: ["ignore", "pipe", "pipe", "ipc"]
@@ -556,6 +578,7 @@ function runSession(socketFile, build) {
556
578
  finished = true;
557
579
  send({ type: "exit", code, signal });
558
580
  socket.end();
581
+ spawnWarm(lastRequest ?? request);
559
582
  };
560
583
  const finishIfRelayed = () => {
561
584
  if (exiting && relayed.stdout >= exiting.stdout && relayed.stderr >= exiting.stderr)
@@ -584,7 +607,7 @@ function runSession(socketFile, build) {
584
607
  }
585
608
  });
586
609
  socket.on("close", () => {
587
- if (warm.child.exitCode === null && warm.child.signalCode === null)
610
+ if (!finished && warm.child.exitCode === null && warm.child.signalCode === null)
588
611
  warm.child.kill("SIGINT");
589
612
  });
590
613
  warm.child.once("exit", (code, signal) => {
@@ -594,7 +617,6 @@ function runSession(socketFile, build) {
594
617
  finish(code, signal);
595
618
  else
596
619
  warm.child.once("close", () => finish(code, signal));
597
- spawnWarm(lastRequest ?? request);
598
620
  });
599
621
  warm.child.send(request);
600
622
  };
@@ -707,6 +729,7 @@ async function runWarmProcess(hooks) {
707
729
  if (request.profile.stdinTTY)
708
730
  Object.assign(process.stdin, { isTTY: true });
709
731
  countOutputBytes();
732
+ globalThis[/* @__PURE__ */ Symbol.for("flashwright.codeCache")]?.refreshAtExit();
710
733
  hooks.retargetWorkers(request.argv);
711
734
  program.parse(request.argv);
712
735
  }
@@ -715,9 +738,11 @@ if (process.argv[2] === "--flashwright-session")
715
738
  // Annotate the CommonJS export names for ESM import in node:
716
739
  0 && (module.exports = {
717
740
  flushSessionBrowsers,
741
+ isWarmSessionRun,
718
742
  receiveWorkerMessage,
719
743
  requestSessionBrowser,
720
744
  runCli,
721
745
  sessionStandbyEnv,
746
+ trackDetachedTeardown,
722
747
  trackSessionWorker
723
748
  });
@@ -1,8 +1,8 @@
1
1
  # packages/playwright/lib/runner/session.js
2
- # total: 25.0 KB
2
+ # total: 25.9 KB
3
3
 
4
4
  ## Inlined (1)
5
- 23.4 KB packages/playwright/src/runner/session.ts
5
+ 24.2 KB packages/playwright/src/runner/session.ts
6
6
 
7
7
  ## External (1)
8
8
  playwright-core/lib/coreBundle
@@ -152,6 +152,7 @@ function prepareSpeculativeContext() {
152
152
  const contextHintFile = import_path.default.join(import_os.default.tmpdir(), "flashwright-context-hints.json");
153
153
  const maxContextHints = 200;
154
154
  let rememberedContextHint = false;
155
+ let hintReadAhead;
155
156
  function readContextHints() {
156
157
  try {
157
158
  return JSON.parse(import_fs.default.readFileSync(contextHintFile, "utf8"));
@@ -161,7 +162,10 @@ function readContextHints() {
161
162
  }
162
163
  function readContextHint() {
163
164
  const key = process.env.FLASHWRIGHT_CONTEXT_HINT_KEY;
164
- return key ? readContextHints()[key] : void 0;
165
+ if (!key)
166
+ return;
167
+ hintReadAhead = { key, hint: readContextHints()[key] };
168
+ return hintReadAhead.hint;
165
169
  }
166
170
  function rememberRecycledContext(browser) {
167
171
  const key = process.env.FLASHWRIGHT_CONTEXT_HINT_KEY;
@@ -172,6 +176,9 @@ function rememberRecycledContext(browser) {
172
176
  if (rememberedContextHint || !key || !Object.keys(params).length || mayHoldSecrets || !isPlainJSON(params))
173
177
  return;
174
178
  rememberedContextHint = true;
179
+ const hint = hintReadAhead?.key === key ? hintReadAhead.hint : void 0;
180
+ if (hint && JSON.stringify(hint.params) === JSON.stringify(params) && hint.storageState === storageState)
181
+ return;
175
182
  try {
176
183
  const hints = readContextHints();
177
184
  if (JSON.stringify(hints[key]?.params) === JSON.stringify(params) && hints[key]?.storageState === storageState)
@@ -24,12 +24,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
 
25
25
  // packages/playwright/src/worker/workerProcessEntry.ts
26
26
  var import_codeCache = require("../codeCache");
27
- var import_path5 = __toESM(require("path"));
27
+ var import_path6 = __toESM(require("path"));
28
28
  var import_common4 = require("../common");
29
29
 
30
30
  // packages/playwright/src/worker/workerMain.ts
31
+ var import_path4 = __toESM(require("path"));
31
32
  var import_common3 = require("../common");
32
33
  var globals = __toESM(require("../globals"));
34
+ var import_package = require("../package");
33
35
  var import_expect = require("../matchers/expect");
34
36
 
35
37
  // packages/playwright/src/util.ts
@@ -837,7 +839,7 @@ function testInfoError(error) {
837
839
  // packages/playwright/src/worker/testInfo.ts
838
840
  var import_common2 = require("../common");
839
841
  var { ManualPromise: ManualPromise4 } = require("playwright-core/lib/coreBundle").iso;
840
- var { captureRawStack, stringifyStackFrames: stringifyStackFrames2, filteredStackTrace: filteredStackTrace3 } = require("playwright-core/lib/coreBundle").utils;
842
+ var { captureFilteredStackTrace, stringifyStackFrames: stringifyStackFrames2 } = require("playwright-core/lib/coreBundle").utils;
841
843
  var { escapeWithQuotes: escapeWithQuotes2 } = require("playwright-core/lib/coreBundle").iso;
842
844
  var { monotonicTime: monotonicTime3 } = require("playwright-core/lib/coreBundle").iso;
843
845
  var { createCallIdGenerator } = require("playwright-core/lib/coreBundle").iso;
@@ -996,10 +998,10 @@ var TestInfoImpl = class {
996
998
  let boxedStack = parentStep?.boxedStack;
997
999
  let stack = data.stack;
998
1000
  if (!boxedStack && data.box) {
999
- boxedStack = filteredStackTrace3(captureRawStack()).slice(1);
1001
+ boxedStack = captureFilteredStackTrace().slice(1);
1000
1002
  stack ??= boxedStack;
1001
1003
  }
1002
- stack ??= filteredStackTrace3(captureRawStack());
1004
+ stack ??= captureFilteredStackTrace();
1003
1005
  const step = {
1004
1006
  ...data,
1005
1007
  stepId,
@@ -1352,7 +1354,7 @@ var colors2 = require("playwright-core/lib/utilsBundle").colors;
1352
1354
  var { ManualPromise: ManualPromise5 } = require("playwright-core/lib/coreBundle").iso;
1353
1355
  var { removeFolders } = require("playwright-core/lib/coreBundle").utils;
1354
1356
  var { gracefullyCloseAll } = require("playwright-core/lib/coreBundle").utils;
1355
- var { filteredStackTrace: filteredStackTrace4 } = require("playwright-core/lib/coreBundle").utils;
1357
+ var { filteredStackTrace: filteredStackTrace3 } = require("playwright-core/lib/coreBundle").utils;
1356
1358
  var WorkerMain = class extends import_common3.ProcessRunner {
1357
1359
  constructor(params) {
1358
1360
  super();
@@ -1406,6 +1408,20 @@ var WorkerMain = class extends import_common3.ProcessRunner {
1406
1408
  }
1407
1409
  return this._runFinished;
1408
1410
  }
1411
+ // Flashwright: in a warm session, the runner reports a run's outcome without waiting for its
1412
+ // workers to exit, when what a stopping worker has left to do cannot change it: no test is
1413
+ // running, no error is waiting to be reported, and only Playwright's own worker fixtures remain,
1414
+ // which hand the browser over to the session (see the runner's session.ts). A worker whose
1415
+ // process.exit was replaced may never exit, which the runner reports after a timeout.
1416
+ canDetachTeardown() {
1417
+ if (!process.env.FLASHWRIGHT_SESSION_HANDOFF || process.env.DEBUG || process.exit !== import_common3.originalProcessExit)
1418
+ return false;
1419
+ if (!this._runFinished.isDone() || this._currentTest || this._fatalErrors.length)
1420
+ return false;
1421
+ return [...this._fixtureRunner.instanceForId.values()].every(({ registration }) => {
1422
+ return registration.scope !== "worker" || typeof registration.fn !== "function" || registration.location.file.startsWith(import_package.packageRoot + import_path4.default.sep);
1423
+ });
1424
+ }
1409
1425
  async gracefullyClose() {
1410
1426
  try {
1411
1427
  await this._stop();
@@ -1522,6 +1538,8 @@ var WorkerMain = class extends import_common3.ProcessRunner {
1522
1538
  await this._runTest(tests[i], entry.retry, tests[i + 1]);
1523
1539
  debugTest(`test finished "${tests[i].title}"`);
1524
1540
  }
1541
+ if (tests.length)
1542
+ globalThis[/* @__PURE__ */ Symbol.for("flashwright.codeCache")]?.ranTests();
1525
1543
  } catch (e) {
1526
1544
  this._fatalErrors.push(testInfoError(e));
1527
1545
  void this._stop();
@@ -1599,7 +1617,7 @@ var WorkerMain = class extends import_common3.ProcessRunner {
1599
1617
  globals.setCurrentTestInfo(testInfo);
1600
1618
  (0, import_expect.setExpectConfig)({
1601
1619
  testInfo,
1602
- filteredStackTrace: filteredStackTrace4,
1620
+ filteredStackTrace: filteredStackTrace3,
1603
1621
  ignoreSnapshots: testInfo._projectInternal.project.ignoreSnapshots,
1604
1622
  updateSnapshots: testInfo.config.updateSnapshots,
1605
1623
  timeout: testInfo._projectInternal.expect?.timeout,
@@ -1730,7 +1748,7 @@ var WorkerMain = class extends import_common3.ProcessRunner {
1730
1748
  testInfo.duration = testInfo._timeoutManager.defaultSlot().elapsed + afterHooksSlot.elapsed | 0;
1731
1749
  this._currentTest = null;
1732
1750
  globals.setCurrentTestInfo(null);
1733
- (0, import_expect.setExpectConfig)({ testInfo: null, filteredStackTrace: filteredStackTrace4, ignoreSnapshots: false, updateSnapshots: "default" });
1751
+ (0, import_expect.setExpectConfig)({ testInfo: null, filteredStackTrace: filteredStackTrace3, ignoreSnapshots: false, updateSnapshots: "default" });
1734
1752
  this.dispatchEvent("testEnd", buildTestEndPayload(testInfo));
1735
1753
  const preserveOutput = this._config.config.preserveOutput === "always" || this._config.config.preserveOutput === "failures-only" && testInfo._isFailure();
1736
1754
  if (!preserveOutput)
@@ -1861,7 +1879,7 @@ var create = (params) => new WorkerMain(params);
1861
1879
  // packages/playwright/src/speculativeBrowser.ts
1862
1880
  var import_fs4 = __toESM(require("fs"));
1863
1881
  var import_os = __toESM(require("os"));
1864
- var import_path4 = __toESM(require("path"));
1882
+ var import_path5 = __toESM(require("path"));
1865
1883
  var speculativeOptions = { handleSIGINT: false, headless: true, ...process.env.FLASHWRIGHT_ISOLATION === "strict" ? {} : { recycleContexts: true } };
1866
1884
  var speculativeKey = /* @__PURE__ */ Symbol.for("flashwright.speculativeBrowser");
1867
1885
  function launchSpeculativeBrowser() {
@@ -1971,7 +1989,8 @@ function prepareSpeculativeContext() {
1971
1989
  return browser;
1972
1990
  });
1973
1991
  }
1974
- var contextHintFile = import_path4.default.join(import_os.default.tmpdir(), "flashwright-context-hints.json");
1992
+ var contextHintFile = import_path5.default.join(import_os.default.tmpdir(), "flashwright-context-hints.json");
1993
+ var hintReadAhead;
1975
1994
  function readContextHints() {
1976
1995
  try {
1977
1996
  return JSON.parse(import_fs4.default.readFileSync(contextHintFile, "utf8"));
@@ -1981,7 +2000,10 @@ function readContextHints() {
1981
2000
  }
1982
2001
  function readContextHint() {
1983
2002
  const key = process.env.FLASHWRIGHT_CONTEXT_HINT_KEY;
1984
- return key ? readContextHints()[key] : void 0;
2003
+ if (!key)
2004
+ return;
2005
+ hintReadAhead = { key, hint: readContextHints()[key] };
2006
+ return hintReadAhead.hint;
1985
2007
  }
1986
2008
  async function returnSpeculativeBrowser() {
1987
2009
  const launch = globalThis[speculativeKey];
@@ -2005,7 +2027,7 @@ if (process.env.FLASHWRIGHT_SPECULATIVE_BROWSER) {
2005
2027
  if (initialized)
2006
2028
  return;
2007
2029
  try {
2008
- require(import_path5.default.join(__dirname, "..", "..", "test.js"));
2030
+ require(import_path6.default.join(__dirname, "..", "..", "test.js"));
2009
2031
  } catch {
2010
2032
  }
2011
2033
  if (!initialized)
@@ -1,5 +1,5 @@
1
1
  # packages/playwright/lib/worker/workerProcessEntry.js
2
- # total: 79.7 KB
2
+ # total: 81.0 KB
3
3
 
4
4
  ## Inlined (9)
5
5
  4.6 KB packages/playwright/src/speculativeBrowser.ts
@@ -9,14 +9,15 @@
9
9
  11.9 KB packages/playwright/src/worker/testTracing.ts
10
10
  5.4 KB packages/playwright/src/worker/timeoutManager.ts
11
11
  0.3 KB packages/playwright/src/worker/util.ts
12
- 21.3 KB packages/playwright/src/worker/workerMain.ts
12
+ 22.5 KB packages/playwright/src/worker/workerMain.ts
13
13
  1.0 KB packages/playwright/src/worker/workerProcessEntry.ts
14
14
 
15
- ## External (7)
15
+ ## External (8)
16
16
  ../codeCache
17
17
  ../common
18
18
  ../globals
19
19
  ../matchers/expect
20
+ ../package
20
21
  playwright-core
21
22
  playwright-core/lib/coreBundle
22
23
  playwright-core/lib/utilsBundle
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flashwright",
3
- "version": "1.64.1-flashwright.2",
3
+ "version": "1.64.1-flashwright.3",
4
4
  "description": "Flashwright: a faster drop-in replacement for Playwright (fork of Playwright 1.64.1)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "license": "Apache-2.0",
50
50
  "dependencies": {
51
- "playwright-core": "npm:flashwright-core@1.64.1-flashwright.2"
51
+ "playwright-core": "npm:flashwright-core@1.64.1-flashwright.3"
52
52
  },
53
53
  "bugs": {
54
54
  "url": "https://github.com/xcodebeast/flashwright/issues"