flashwright 1.64.1-flashwright.2 → 1.64.1-flashwright.4

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,
@@ -89,6 +90,7 @@ function installSourceMapSupport() {
89
90
  Error.stackTraceLimit = 200;
90
91
  const runnerFramePrefix = import_package.packageRoot + import_path.default.sep;
91
92
  const formatRunnerFrames = showInternalStackFrames();
93
+ const mappedFrames = /* @__PURE__ */ new Map();
92
94
  setRawStackFormatter((error, callSites) => {
93
95
  const lines = [String(error)];
94
96
  for (const callSite of callSites) {
@@ -97,8 +99,20 @@ function installSourceMapSupport() {
97
99
  lines.push(` at ${fileName2}:${callSite.getLineNumber()}:${callSite.getColumnNumber()}`);
98
100
  continue;
99
101
  }
100
- const mapped = fileName2 && sourceMaps.has(fileName2) ? sourceMapSupport.wrapCallSite(callSite) : callSite;
101
- lines.push(" at " + String(mapped).replace(/^async /, ""));
102
+ const sourceMap = fileName2 ? sourceMaps.get(fileName2) : void 0;
103
+ if (!sourceMap) {
104
+ lines.push(" at " + String(callSite).replace(/^async /, ""));
105
+ continue;
106
+ }
107
+ const key = sourceMap + "\n" + String(callSite);
108
+ let line = mappedFrames.get(key);
109
+ if (line === void 0) {
110
+ line = " at " + String(sourceMapSupport.wrapCallSite(callSite)).replace(/^async /, "");
111
+ if (mappedFrames.size >= 1e4)
112
+ mappedFrames.clear();
113
+ mappedFrames.set(key, line);
114
+ }
115
+ lines.push(line);
102
116
  }
103
117
  return lines.join("\n");
104
118
  });
@@ -1920,6 +1934,7 @@ var PoolBuilder = class _PoolBuilder {
1920
1934
  var process_exports = {};
1921
1935
  __export(process_exports, {
1922
1936
  ProcessRunner: () => ProcessRunner,
1937
+ originalProcessExit: () => originalProcessExit,
1923
1938
  startProcessRunner: () => startProcessRunner
1924
1939
  });
1925
1940
  var import_bootstrap = require("playwright-core/lib/bootstrap");
@@ -1930,6 +1945,10 @@ var { setBoxedStackPrefixes } = require("playwright-core/lib/coreBundle").utils;
1930
1945
  var ProcessRunner = class {
1931
1946
  async gracefullyClose() {
1932
1947
  }
1948
+ // Flashwright: see WorkerMain.canDetachTeardown.
1949
+ canDetachTeardown() {
1950
+ return false;
1951
+ }
1933
1952
  dispatchEvent(method, params) {
1934
1953
  const response = { method, params };
1935
1954
  sendMessageToParent({ method: "__dispatch__", params: response });
@@ -1946,6 +1965,7 @@ var gracefullyCloseCalled = false;
1946
1965
  var forceExitInitiated = false;
1947
1966
  var processRunner;
1948
1967
  var startingEnv = { ...process.env };
1968
+ var originalProcessExit = process.exit;
1949
1969
  setBoxedStackPrefixes([import_package4.packageRoot]);
1950
1970
  function startProcessRunner(create) {
1951
1971
  sendMessageToParent({ method: "ready" });
@@ -1969,6 +1989,10 @@ function startProcessRunner(create) {
1969
1989
  const keys = /* @__PURE__ */ new Set([...Object.keys(process.env), ...Object.keys(startingEnv)]);
1970
1990
  const producedEnv = [...keys].filter((key) => startingEnv[key] !== process.env[key]).map((key) => [key, process.env[key] ?? null]);
1971
1991
  sendMessageToParent({ method: "__env_produced__", params: producedEnv });
1992
+ if (processRunner?.canDetachTeardown()) {
1993
+ sendMessageToParent({ method: "__teardown_detached__" });
1994
+ globalThis[/* @__PURE__ */ Symbol.for("flashwright.codeCache")]?.refreshAtExit();
1995
+ }
1972
1996
  await gracefullyCloseAndExit(false);
1973
1997
  return;
1974
1998
  }
@@ -2963,6 +2987,7 @@ function serializeLoadError(file2, error) {
2963
2987
  fixtures,
2964
2988
  ipc,
2965
2989
  mergeTests,
2990
+ originalProcessExit,
2966
2991
  poolBuilder,
2967
2992
  processRunner,
2968
2993
  startProcessRunner,
@@ -1,5 +1,5 @@
1
1
  # packages/playwright/lib/common/index.js
2
- # total: 115.2 KB
2
+ # total: 116.0 KB
3
3
 
4
4
  ## Inlined (20)
5
5
  12.6 KB packages/playwright/src/common/config.ts
@@ -8,14 +8,14 @@
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
15
15
  12.9 KB packages/playwright/src/common/testType.ts
16
16
  1.4 KB packages/playwright/src/common/validators.ts
17
17
  1.3 KB packages/playwright/src/isomorphic/teleReceiver.ts
18
- 8.6 KB packages/playwright/src/transform/compilationCache.ts
18
+ 9.0 KB packages/playwright/src/transform/compilationCache.ts
19
19
  1.7 KB packages/playwright/src/transform/esmLoaderSync.ts
20
20
  1.1 KB packages/playwright/src/transform/pirates.ts
21
21
  1.1 KB packages/playwright/src/transform/portTransport.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)
@@ -4188,6 +4188,12 @@ function calculateSha1(buffer) {
4188
4188
  return hash.digest("hex");
4189
4189
  }
4190
4190
 
4191
+ // packages/isomorphic/manualPromise.ts
4192
+ var captureRaceCallSite = () => new Error();
4193
+ function setRaceCallSiteCapture(capture) {
4194
+ captureRaceCallSite = capture;
4195
+ }
4196
+
4191
4197
  // packages/utils/env.ts
4192
4198
  function getFromENV(name) {
4193
4199
  let value = process.env[name];
@@ -4207,12 +4213,28 @@ function getAsBooleanFromENV(name, defaultValue) {
4207
4213
  // packages/utils/debug.ts
4208
4214
  var _debugMode = getFromENV("PWDEBUG") || "";
4209
4215
  var _isUnderTest = getAsBooleanFromENV("PWTEST_UNDER_TEST");
4216
+ function isUnderTest() {
4217
+ return _isUnderTest;
4218
+ }
4210
4219
 
4211
4220
  // packages/utils/stackTrace.ts
4212
4221
  var rawStackFormatter;
4213
4222
  function setRawStackFormatter(formatter) {
4214
4223
  rawStackFormatter = formatter;
4215
4224
  }
4225
+ function withShallowStack(create) {
4226
+ const stackTraceLimit = Error.stackTraceLimit;
4227
+ const limit = showInternalStackFrames() || isUnderTest() ? 10 : 0;
4228
+ if (stackTraceLimit <= limit)
4229
+ return create();
4230
+ Error.stackTraceLimit = limit;
4231
+ try {
4232
+ return create();
4233
+ } finally {
4234
+ Error.stackTraceLimit = stackTraceLimit;
4235
+ }
4236
+ }
4237
+ setRaceCallSiteCapture(() => withShallowStack(() => new Error()));
4216
4238
  var re = new RegExp(
4217
4239
  "^(?:\\s*at )?(?:(new) )?(?:(.*?) \\()?(?:eval at ([^ ]+) \\((.+?):(\\d+):(\\d+)\\), )?(?:(.+?):(\\d+):(\\d+)|(native))(\\)?)$"
4218
4240
  );
@@ -4236,6 +4258,7 @@ function installSourceMapSupport() {
4236
4258
  Error.stackTraceLimit = 200;
4237
4259
  const runnerFramePrefix = import_package.packageRoot + import_path.default.sep;
4238
4260
  const formatRunnerFrames = showInternalStackFrames();
4261
+ const mappedFrames = /* @__PURE__ */ new Map();
4239
4262
  setRawStackFormatter((error, callSites) => {
4240
4263
  const lines = [String(error)];
4241
4264
  for (const callSite of callSites) {
@@ -4244,8 +4267,20 @@ function installSourceMapSupport() {
4244
4267
  lines.push(` at ${fileName2}:${callSite.getLineNumber()}:${callSite.getColumnNumber()}`);
4245
4268
  continue;
4246
4269
  }
4247
- const mapped = fileName2 && sourceMaps.has(fileName2) ? import_source_map_support.default.wrapCallSite(callSite) : callSite;
4248
- lines.push(" at " + String(mapped).replace(/^async /, ""));
4270
+ const sourceMap = fileName2 ? sourceMaps.get(fileName2) : void 0;
4271
+ if (!sourceMap) {
4272
+ lines.push(" at " + String(callSite).replace(/^async /, ""));
4273
+ continue;
4274
+ }
4275
+ const key = sourceMap + "\n" + String(callSite);
4276
+ let line = mappedFrames.get(key);
4277
+ if (line === void 0) {
4278
+ line = " at " + String(import_source_map_support.default.wrapCallSite(callSite)).replace(/^async /, "");
4279
+ if (mappedFrames.size >= 1e4)
4280
+ mappedFrames.clear();
4281
+ mappedFrames.set(key, line);
4282
+ }
4283
+ lines.push(line);
4249
4284
  }
4250
4285
  return lines.join("\n");
4251
4286
  });
@@ -1,7 +1,7 @@
1
1
  # packages/playwright/lib/transform/esmLoader.js
2
- # total: 284.0 KB
2
+ # total: 285.0 KB
3
3
 
4
- ## Inlined (51)
4
+ ## Inlined (52)
5
5
  1.3 KB node_modules/balanced-match/dist/esm/index.js
6
6
  4.8 KB node_modules/brace-expansion/dist/esm/index.js
7
7
  1.8 KB node_modules/buffer-from/index.js
@@ -39,9 +39,10 @@
39
39
  8.6 KB node_modules/source-map/lib/util.js
40
40
  0.3 KB node_modules/source-map/source-map.js
41
41
  3.1 KB node_modules/supports-color/index.js
42
+ 0.1 KB packages/isomorphic/manualPromise.ts
42
43
  0.1 KB packages/isomorphic/rtti.ts
43
44
  0.2 KB packages/isomorphic/stringUtils.ts
44
- 6.7 KB packages/playwright/src/transform/compilationCache.ts
45
+ 7.1 KB packages/playwright/src/transform/compilationCache.ts
45
46
  3.1 KB packages/playwright/src/transform/esmLoader.ts
46
47
  1.7 KB packages/playwright/src/transform/esmLoaderSync.ts
47
48
  1.1 KB packages/playwright/src/transform/pirates.ts
@@ -50,9 +51,9 @@
50
51
  3.2 KB packages/playwright/src/transform/tsconfig-loader.ts
51
52
  4.7 KB packages/playwright/src/util.ts
52
53
  0.2 KB packages/utils/crypto.ts
53
- 0.1 KB packages/utils/debug.ts
54
+ 0.2 KB packages/utils/debug.ts
54
55
  0.5 KB packages/utils/env.ts
55
- 0.4 KB packages/utils/stackTrace.ts
56
+ 0.8 KB packages/utils/stackTrace.ts
56
57
 
57
58
  ## External (3)
58
59
  ../globals
@@ -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;
@@ -859,6 +861,9 @@ var TestInfoImpl = class {
859
861
  this._ariaSnapshotNames = { lastAnonymousSnapshotIndex: 0, lastNamedSnapshotIndex: {} };
860
862
  this._interruptedPromise = new ManualPromise4();
861
863
  this._steps = [];
864
+ // Flashwright: hook and fixture steps that have not finished. When there are none, as in the test
865
+ // body, looking for one does not walk all steps of the test for every API call.
866
+ this._unfinishedPredefinedSteps = 0;
862
867
  this._stepMap = /* @__PURE__ */ new Map();
863
868
  this._onDidFinishTestFunctionCallbacks = /* @__PURE__ */ new Set();
864
869
  this._hasNonRetriableError = false;
@@ -974,6 +979,8 @@ var TestInfoImpl = class {
974
979
  }
975
980
  }
976
981
  _findLastPredefinedStep(steps) {
982
+ if (!this._unfinishedPredefinedSteps)
983
+ return void 0;
977
984
  for (let i = steps.length - 1; i >= 0; i--) {
978
985
  const child = this._findLastPredefinedStep(steps[i].steps);
979
986
  if (child)
@@ -996,10 +1003,10 @@ var TestInfoImpl = class {
996
1003
  let boxedStack = parentStep?.boxedStack;
997
1004
  let stack = data.stack;
998
1005
  if (!boxedStack && data.box) {
999
- boxedStack = filteredStackTrace3(captureRawStack()).slice(1);
1006
+ boxedStack = captureFilteredStackTrace().slice(1);
1000
1007
  stack ??= boxedStack;
1001
1008
  }
1002
- stack ??= filteredStackTrace3(captureRawStack());
1009
+ stack ??= captureFilteredStackTrace();
1003
1010
  const step = {
1004
1011
  ...data,
1005
1012
  stepId,
@@ -1013,6 +1020,8 @@ var TestInfoImpl = class {
1013
1020
  if (step.endWallTime)
1014
1021
  return;
1015
1022
  step.endWallTime = Date.now();
1023
+ if (step.category === "hook" || step.category === "fixture")
1024
+ this._unfinishedPredefinedSteps--;
1016
1025
  if (result.attachments) {
1017
1026
  for (const attachment of result.attachments)
1018
1027
  this._attach(attachment, stepId);
@@ -1061,6 +1070,8 @@ ${stringifyStackFrames2(step.boxedStack).join("\n")}`;
1061
1070
  };
1062
1071
  const parentStepList = parentStep ? parentStep.steps : this._steps;
1063
1072
  parentStepList.push(step);
1073
+ if (step.category === "hook" || step.category === "fixture")
1074
+ this._unfinishedPredefinedSteps++;
1064
1075
  this._stepMap.set(stepId, step);
1065
1076
  if (!step.group) {
1066
1077
  const payload = {
@@ -1352,7 +1363,7 @@ var colors2 = require("playwright-core/lib/utilsBundle").colors;
1352
1363
  var { ManualPromise: ManualPromise5 } = require("playwright-core/lib/coreBundle").iso;
1353
1364
  var { removeFolders } = require("playwright-core/lib/coreBundle").utils;
1354
1365
  var { gracefullyCloseAll } = require("playwright-core/lib/coreBundle").utils;
1355
- var { filteredStackTrace: filteredStackTrace4 } = require("playwright-core/lib/coreBundle").utils;
1366
+ var { filteredStackTrace: filteredStackTrace3 } = require("playwright-core/lib/coreBundle").utils;
1356
1367
  var WorkerMain = class extends import_common3.ProcessRunner {
1357
1368
  constructor(params) {
1358
1369
  super();
@@ -1406,6 +1417,20 @@ var WorkerMain = class extends import_common3.ProcessRunner {
1406
1417
  }
1407
1418
  return this._runFinished;
1408
1419
  }
1420
+ // Flashwright: in a warm session, the runner reports a run's outcome without waiting for its
1421
+ // workers to exit, when what a stopping worker has left to do cannot change it: no test is
1422
+ // running, no error is waiting to be reported, and only Playwright's own worker fixtures remain,
1423
+ // which hand the browser over to the session (see the runner's session.ts). A worker whose
1424
+ // process.exit was replaced may never exit, which the runner reports after a timeout.
1425
+ canDetachTeardown() {
1426
+ if (!process.env.FLASHWRIGHT_SESSION_HANDOFF || process.env.DEBUG || process.exit !== import_common3.originalProcessExit)
1427
+ return false;
1428
+ if (!this._runFinished.isDone() || this._currentTest || this._fatalErrors.length)
1429
+ return false;
1430
+ return [...this._fixtureRunner.instanceForId.values()].every(({ registration }) => {
1431
+ return registration.scope !== "worker" || typeof registration.fn !== "function" || registration.location.file.startsWith(import_package.packageRoot + import_path4.default.sep);
1432
+ });
1433
+ }
1409
1434
  async gracefullyClose() {
1410
1435
  try {
1411
1436
  await this._stop();
@@ -1522,6 +1547,8 @@ var WorkerMain = class extends import_common3.ProcessRunner {
1522
1547
  await this._runTest(tests[i], entry.retry, tests[i + 1]);
1523
1548
  debugTest(`test finished "${tests[i].title}"`);
1524
1549
  }
1550
+ if (tests.length)
1551
+ globalThis[/* @__PURE__ */ Symbol.for("flashwright.codeCache")]?.ranTests();
1525
1552
  } catch (e) {
1526
1553
  this._fatalErrors.push(testInfoError(e));
1527
1554
  void this._stop();
@@ -1599,7 +1626,7 @@ var WorkerMain = class extends import_common3.ProcessRunner {
1599
1626
  globals.setCurrentTestInfo(testInfo);
1600
1627
  (0, import_expect.setExpectConfig)({
1601
1628
  testInfo,
1602
- filteredStackTrace: filteredStackTrace4,
1629
+ filteredStackTrace: filteredStackTrace3,
1603
1630
  ignoreSnapshots: testInfo._projectInternal.project.ignoreSnapshots,
1604
1631
  updateSnapshots: testInfo.config.updateSnapshots,
1605
1632
  timeout: testInfo._projectInternal.expect?.timeout,
@@ -1730,7 +1757,7 @@ var WorkerMain = class extends import_common3.ProcessRunner {
1730
1757
  testInfo.duration = testInfo._timeoutManager.defaultSlot().elapsed + afterHooksSlot.elapsed | 0;
1731
1758
  this._currentTest = null;
1732
1759
  globals.setCurrentTestInfo(null);
1733
- (0, import_expect.setExpectConfig)({ testInfo: null, filteredStackTrace: filteredStackTrace4, ignoreSnapshots: false, updateSnapshots: "default" });
1760
+ (0, import_expect.setExpectConfig)({ testInfo: null, filteredStackTrace: filteredStackTrace3, ignoreSnapshots: false, updateSnapshots: "default" });
1734
1761
  this.dispatchEvent("testEnd", buildTestEndPayload(testInfo));
1735
1762
  const preserveOutput = this._config.config.preserveOutput === "always" || this._config.config.preserveOutput === "failures-only" && testInfo._isFailure();
1736
1763
  if (!preserveOutput)
@@ -1861,7 +1888,7 @@ var create = (params) => new WorkerMain(params);
1861
1888
  // packages/playwright/src/speculativeBrowser.ts
1862
1889
  var import_fs4 = __toESM(require("fs"));
1863
1890
  var import_os = __toESM(require("os"));
1864
- var import_path4 = __toESM(require("path"));
1891
+ var import_path5 = __toESM(require("path"));
1865
1892
  var speculativeOptions = { handleSIGINT: false, headless: true, ...process.env.FLASHWRIGHT_ISOLATION === "strict" ? {} : { recycleContexts: true } };
1866
1893
  var speculativeKey = /* @__PURE__ */ Symbol.for("flashwright.speculativeBrowser");
1867
1894
  function launchSpeculativeBrowser() {
@@ -1971,7 +1998,8 @@ function prepareSpeculativeContext() {
1971
1998
  return browser;
1972
1999
  });
1973
2000
  }
1974
- var contextHintFile = import_path4.default.join(import_os.default.tmpdir(), "flashwright-context-hints.json");
2001
+ var contextHintFile = import_path5.default.join(import_os.default.tmpdir(), "flashwright-context-hints.json");
2002
+ var hintReadAhead;
1975
2003
  function readContextHints() {
1976
2004
  try {
1977
2005
  return JSON.parse(import_fs4.default.readFileSync(contextHintFile, "utf8"));
@@ -1981,7 +2009,10 @@ function readContextHints() {
1981
2009
  }
1982
2010
  function readContextHint() {
1983
2011
  const key = process.env.FLASHWRIGHT_CONTEXT_HINT_KEY;
1984
- return key ? readContextHints()[key] : void 0;
2012
+ if (!key)
2013
+ return;
2014
+ hintReadAhead = { key, hint: readContextHints()[key] };
2015
+ return hintReadAhead.hint;
1985
2016
  }
1986
2017
  async function returnSpeculativeBrowser() {
1987
2018
  const launch = globalThis[speculativeKey];
@@ -2005,7 +2036,7 @@ if (process.env.FLASHWRIGHT_SPECULATIVE_BROWSER) {
2005
2036
  if (initialized)
2006
2037
  return;
2007
2038
  try {
2008
- require(import_path5.default.join(__dirname, "..", "..", "test.js"));
2039
+ require(import_path6.default.join(__dirname, "..", "..", "test.js"));
2009
2040
  } catch {
2010
2041
  }
2011
2042
  if (!initialized)
@@ -1,22 +1,23 @@
1
1
  # packages/playwright/lib/worker/workerProcessEntry.js
2
- # total: 79.7 KB
2
+ # total: 81.5 KB
3
3
 
4
4
  ## Inlined (9)
5
5
  4.6 KB packages/playwright/src/speculativeBrowser.ts
6
6
  3.7 KB packages/playwright/src/util.ts
7
7
  8.7 KB packages/playwright/src/worker/fixtureRunner.ts
8
- 21.3 KB packages/playwright/src/worker/testInfo.ts
8
+ 21.8 KB packages/playwright/src/worker/testInfo.ts
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.4",
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.4"
52
52
  },
53
53
  "bugs": {
54
54
  "url": "https://github.com/xcodebeast/flashwright/issues"