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 +31 -10
- package/lib/codeCache.js.txt +2 -2
- package/lib/common/index.js +27 -2
- package/lib/common/index.js.txt +3 -3
- package/lib/matchers/expect.js +3 -2
- package/lib/matchers/expect.js.txt +2 -2
- package/lib/runner/index.js +42 -31
- package/lib/runner/index.js.txt +3 -3
- package/lib/runner/session.js +40 -15
- package/lib/runner/session.js.txt +2 -2
- package/lib/speculativeBrowser.js +8 -1
- package/lib/transform/esmLoader.js +37 -2
- package/lib/transform/esmLoader.js.txt +6 -5
- package/lib/worker/workerProcessEntry.js +42 -11
- package/lib/worker/workerProcessEntry.js.txt +5 -4
- package/package.json +2 -2
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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] || ""))
|
package/lib/codeCache.js.txt
CHANGED
package/lib/common/index.js
CHANGED
|
@@ -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
|
|
101
|
-
|
|
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,
|
package/lib/common/index.js.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# packages/playwright/lib/common/index.js
|
|
2
|
-
# total:
|
|
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.
|
|
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
|
-
|
|
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
|
package/lib/matchers/expect.js
CHANGED
|
@@ -13160,7 +13160,7 @@ function indent2(snapshot, indent3) {
|
|
|
13160
13160
|
}
|
|
13161
13161
|
|
|
13162
13162
|
// packages/playwright/src/matchers/expect.ts
|
|
13163
|
-
var {
|
|
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
|
|
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.
|
|
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.
|
|
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
|
package/lib/runner/index.js
CHANGED
|
@@ -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 === "
|
|
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
|
-
|
|
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
|
|
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:
|
|
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
|
|
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(
|
|
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:
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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)
|
package/lib/runner/index.js.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# packages/playwright/lib/runner/index.js
|
|
2
|
-
# total:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/lib/runner/session.js
CHANGED
|
@@ -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 ||
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
});
|
|
@@ -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
|
-
|
|
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
|
|
4248
|
-
|
|
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:
|
|
2
|
+
# total: 285.0 KB
|
|
3
3
|
|
|
4
|
-
## Inlined (
|
|
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
|
-
|
|
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.
|
|
54
|
+
0.2 KB packages/utils/debug.ts
|
|
54
55
|
0.5 KB packages/utils/env.ts
|
|
55
|
-
0.
|
|
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
|
|
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 {
|
|
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 =
|
|
1006
|
+
boxedStack = captureFilteredStackTrace().slice(1);
|
|
1000
1007
|
stack ??= boxedStack;
|
|
1001
1008
|
}
|
|
1002
|
-
stack ??=
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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.
|
|
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
|
-
|
|
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 (
|
|
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.
|
|
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.
|
|
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"
|