@stablyai/internal-playwright 0.1.0
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/LICENSE +202 -0
- package/NOTICE +5 -0
- package/README.md +168 -0
- package/ThirdPartyNotices.txt +6277 -0
- package/cli.js +19 -0
- package/index.d.ts +17 -0
- package/index.js +17 -0
- package/index.mjs +18 -0
- package/jsx-runtime.js +42 -0
- package/jsx-runtime.mjs +21 -0
- package/lib/agents/generateAgents.js +265 -0
- package/lib/agents/generator.md +102 -0
- package/lib/agents/healer.md +78 -0
- package/lib/agents/planner.md +135 -0
- package/lib/cli.js +274 -0
- package/lib/common/config.js +274 -0
- package/lib/common/config.js.map +7 -0
- package/lib/common/configLoader.js +377 -0
- package/lib/common/configLoader.js.map +7 -0
- package/lib/common/esmLoaderHost.js +102 -0
- package/lib/common/esmLoaderHost.js.map +7 -0
- package/lib/common/expectBundle.js +52 -0
- package/lib/common/expectBundle.js.map +7 -0
- package/lib/common/expectBundleImpl.js +389 -0
- package/lib/common/expectBundleImpl.js.map +7 -0
- package/lib/common/fixtures.js +302 -0
- package/lib/common/fixtures.js.map +7 -0
- package/lib/common/globals.js +58 -0
- package/lib/common/globals.js.map +7 -0
- package/lib/common/ipc.js +60 -0
- package/lib/common/ipc.js.map +7 -0
- package/lib/common/poolBuilder.js +85 -0
- package/lib/common/poolBuilder.js.map +7 -0
- package/lib/common/process.js +104 -0
- package/lib/common/process.js.map +7 -0
- package/lib/common/suiteUtils.js +140 -0
- package/lib/common/suiteUtils.js.map +7 -0
- package/lib/common/test.js +321 -0
- package/lib/common/test.js.map +7 -0
- package/lib/common/testLoader.js +100 -0
- package/lib/common/testLoader.js.map +7 -0
- package/lib/common/testType.js +310 -0
- package/lib/common/testType.js.map +7 -0
- package/lib/fsWatcher.js +67 -0
- package/lib/fsWatcher.js.map +7 -0
- package/lib/index.js +696 -0
- package/lib/index.js.map +7 -0
- package/lib/internalsForTest.js +42 -0
- package/lib/internalsForTest.js.map +7 -0
- package/lib/isomorphic/events.js +77 -0
- package/lib/isomorphic/events.js.map +7 -0
- package/lib/isomorphic/folders.js +30 -0
- package/lib/isomorphic/folders.js.map +7 -0
- package/lib/isomorphic/stringInternPool.js +69 -0
- package/lib/isomorphic/stringInternPool.js.map +7 -0
- package/lib/isomorphic/teleReceiver.js +507 -0
- package/lib/isomorphic/teleReceiver.js.map +7 -0
- package/lib/isomorphic/teleSuiteUpdater.js +137 -0
- package/lib/isomorphic/teleSuiteUpdater.js.map +7 -0
- package/lib/isomorphic/testServerConnection.js +211 -0
- package/lib/isomorphic/testServerConnection.js.map +7 -0
- package/lib/isomorphic/testServerInterface.js +16 -0
- package/lib/isomorphic/testServerInterface.js.map +7 -0
- package/lib/isomorphic/testTree.js +334 -0
- package/lib/isomorphic/testTree.js.map +7 -0
- package/lib/isomorphic/types.d.js +16 -0
- package/lib/isomorphic/types.d.js.map +7 -0
- package/lib/loader/loaderMain.js +59 -0
- package/lib/loader/loaderMain.js.map +7 -0
- package/lib/matchers/expect.js +325 -0
- package/lib/matchers/expect.js.map +7 -0
- package/lib/matchers/matcherHint.js +87 -0
- package/lib/matchers/matcherHint.js.map +7 -0
- package/lib/matchers/matchers.js +366 -0
- package/lib/matchers/matchers.js.map +7 -0
- package/lib/matchers/toBeTruthy.js +73 -0
- package/lib/matchers/toBeTruthy.js.map +7 -0
- package/lib/matchers/toEqual.js +99 -0
- package/lib/matchers/toEqual.js.map +7 -0
- package/lib/matchers/toHaveURL.js +102 -0
- package/lib/matchers/toHaveURL.js.map +7 -0
- package/lib/matchers/toMatchAriaSnapshot.js +159 -0
- package/lib/matchers/toMatchAriaSnapshot.js.map +7 -0
- package/lib/matchers/toMatchSnapshot.js +359 -0
- package/lib/matchers/toMatchSnapshot.js.map +7 -0
- package/lib/matchers/toMatchText.js +99 -0
- package/lib/matchers/toMatchText.js.map +7 -0
- package/lib/mcp/browser/actions.d.js +16 -0
- package/lib/mcp/browser/backend.js +93 -0
- package/lib/mcp/browser/backend.js.map +7 -0
- package/lib/mcp/browser/browserContextFactory.js +296 -0
- package/lib/mcp/browser/browserServerBackend.js +76 -0
- package/lib/mcp/browser/codegen.js +66 -0
- package/lib/mcp/browser/config.js +385 -0
- package/lib/mcp/browser/context.js +287 -0
- package/lib/mcp/browser/response.js +228 -0
- package/lib/mcp/browser/sessionLog.js +160 -0
- package/lib/mcp/browser/tab.js +277 -0
- package/lib/mcp/browser/tool.js +30 -0
- package/lib/mcp/browser/tool.js.map +7 -0
- package/lib/mcp/browser/tools/common.js +63 -0
- package/lib/mcp/browser/tools/console.js +44 -0
- package/lib/mcp/browser/tools/dialogs.js +60 -0
- package/lib/mcp/browser/tools/evaluate.js +70 -0
- package/lib/mcp/browser/tools/files.js +58 -0
- package/lib/mcp/browser/tools/form.js +74 -0
- package/lib/mcp/browser/tools/install.js +69 -0
- package/lib/mcp/browser/tools/keyboard.js +85 -0
- package/lib/mcp/browser/tools/mouse.js +107 -0
- package/lib/mcp/browser/tools/navigate.js +62 -0
- package/lib/mcp/browser/tools/network.js +54 -0
- package/lib/mcp/browser/tools/pdf.js +59 -0
- package/lib/mcp/browser/tools/screenshot.js +88 -0
- package/lib/mcp/browser/tools/snapshot.js +182 -0
- package/lib/mcp/browser/tools/tabs.js +67 -0
- package/lib/mcp/browser/tools/tool.js +49 -0
- package/lib/mcp/browser/tools/tracing.js +74 -0
- package/lib/mcp/browser/tools/utils.js +100 -0
- package/lib/mcp/browser/tools/verify.js +154 -0
- package/lib/mcp/browser/tools/wait.js +63 -0
- package/lib/mcp/browser/tools.js +80 -0
- package/lib/mcp/browser/tools.js.map +7 -0
- package/lib/mcp/browser/watchdog.js +44 -0
- package/lib/mcp/config.d.js +16 -0
- package/lib/mcp/extension/cdpRelay.js +351 -0
- package/lib/mcp/extension/extensionContextFactory.js +75 -0
- package/lib/mcp/extension/protocol.js +28 -0
- package/lib/mcp/index.js +61 -0
- package/lib/mcp/log.js +35 -0
- package/lib/mcp/program.js +96 -0
- package/lib/mcp/sdk/bundle.js +81 -0
- package/lib/mcp/sdk/bundle.js.map +7 -0
- package/lib/mcp/sdk/call.js +49 -0
- package/lib/mcp/sdk/call.js.map +7 -0
- package/lib/mcp/sdk/exports.js +32 -0
- package/lib/mcp/sdk/exports.js.map +7 -0
- package/lib/mcp/sdk/http.js +187 -0
- package/lib/mcp/sdk/http.js.map +7 -0
- package/lib/mcp/sdk/inProcessTransport.js +71 -0
- package/lib/mcp/sdk/inProcessTransport.js.map +7 -0
- package/lib/mcp/sdk/mdb.js +206 -0
- package/lib/mcp/sdk/mdb.js.map +7 -0
- package/lib/mcp/sdk/proxyBackend.js +128 -0
- package/lib/mcp/sdk/proxyBackend.js.map +7 -0
- package/lib/mcp/sdk/server.js +189 -0
- package/lib/mcp/sdk/server.js.map +7 -0
- package/lib/mcp/sdk/tool.js +51 -0
- package/lib/mcp/sdk/tool.js.map +7 -0
- package/lib/mcp/test/backend.js +67 -0
- package/lib/mcp/test/backend.js.map +7 -0
- package/lib/mcp/test/browserBackend.js +98 -0
- package/lib/mcp/test/context.js +48 -0
- package/lib/mcp/test/context.js.map +7 -0
- package/lib/mcp/test/generatorTools.js +122 -0
- package/lib/mcp/test/plannerTools.js +46 -0
- package/lib/mcp/test/seed.js +72 -0
- package/lib/mcp/test/streams.js +39 -0
- package/lib/mcp/test/streams.js.map +7 -0
- package/lib/mcp/test/testBackend.js +97 -0
- package/lib/mcp/test/testContext.js +176 -0
- package/lib/mcp/test/testTool.js +30 -0
- package/lib/mcp/test/testTools.js +115 -0
- package/lib/mcp/test/tool.js +30 -0
- package/lib/mcp/test/tool.js.map +7 -0
- package/lib/mcp/test/tools.js +150 -0
- package/lib/mcp/test/tools.js.map +7 -0
- package/lib/mcp/vscode/host.js +187 -0
- package/lib/mcp/vscode/main.js +77 -0
- package/lib/mcpBundleImpl.js +41 -0
- package/lib/mcpBundleImpl.js.map +7 -0
- package/lib/plugins/gitCommitInfoPlugin.js +198 -0
- package/lib/plugins/gitCommitInfoPlugin.js.map +7 -0
- package/lib/plugins/index.js +28 -0
- package/lib/plugins/index.js.map +7 -0
- package/lib/plugins/webServerPlugin.js +209 -0
- package/lib/plugins/webServerPlugin.js.map +7 -0
- package/lib/program.js +412 -0
- package/lib/program.js.map +7 -0
- package/lib/reporters/base.js +609 -0
- package/lib/reporters/base.js.map +7 -0
- package/lib/reporters/blob.js +135 -0
- package/lib/reporters/blob.js.map +7 -0
- package/lib/reporters/dot.js +82 -0
- package/lib/reporters/dot.js.map +7 -0
- package/lib/reporters/empty.js +32 -0
- package/lib/reporters/empty.js.map +7 -0
- package/lib/reporters/github.js +128 -0
- package/lib/reporters/github.js.map +7 -0
- package/lib/reporters/html.js +644 -0
- package/lib/reporters/html.js.map +7 -0
- package/lib/reporters/internalReporter.js +130 -0
- package/lib/reporters/internalReporter.js.map +7 -0
- package/lib/reporters/json.js +254 -0
- package/lib/reporters/json.js.map +7 -0
- package/lib/reporters/junit.js +230 -0
- package/lib/reporters/junit.js.map +7 -0
- package/lib/reporters/line.js +113 -0
- package/lib/reporters/line.js.map +7 -0
- package/lib/reporters/list.js +235 -0
- package/lib/reporters/list.js.map +7 -0
- package/lib/reporters/listModeReporter.js +69 -0
- package/lib/reporters/listModeReporter.js.map +7 -0
- package/lib/reporters/markdown.js +144 -0
- package/lib/reporters/markdown.js.map +7 -0
- package/lib/reporters/merge.js +535 -0
- package/lib/reporters/merge.js.map +7 -0
- package/lib/reporters/multiplexer.js +104 -0
- package/lib/reporters/multiplexer.js.map +7 -0
- package/lib/reporters/reporterV2.js +102 -0
- package/lib/reporters/reporterV2.js.map +7 -0
- package/lib/reporters/teleEmitter.js +297 -0
- package/lib/reporters/teleEmitter.js.map +7 -0
- package/lib/reporters/versions/blobV1.js +16 -0
- package/lib/reporters/versions/blobV1.js.map +7 -0
- package/lib/runner/dispatcher.js +491 -0
- package/lib/runner/dispatcher.js.map +7 -0
- package/lib/runner/failureTracker.js +72 -0
- package/lib/runner/failureTracker.js.map +7 -0
- package/lib/runner/lastRun.js +77 -0
- package/lib/runner/lastRun.js.map +7 -0
- package/lib/runner/loadUtils.js +333 -0
- package/lib/runner/loadUtils.js.map +7 -0
- package/lib/runner/loaderHost.js +89 -0
- package/lib/runner/loaderHost.js.map +7 -0
- package/lib/runner/processHost.js +161 -0
- package/lib/runner/processHost.js.map +7 -0
- package/lib/runner/projectUtils.js +241 -0
- package/lib/runner/projectUtils.js.map +7 -0
- package/lib/runner/rebase.js +189 -0
- package/lib/runner/rebase.js.map +7 -0
- package/lib/runner/reporters.js +137 -0
- package/lib/runner/reporters.js.map +7 -0
- package/lib/runner/runner.js +173 -0
- package/lib/runner/sigIntWatcher.js +96 -0
- package/lib/runner/sigIntWatcher.js.map +7 -0
- package/lib/runner/taskRunner.js +127 -0
- package/lib/runner/taskRunner.js.map +7 -0
- package/lib/runner/tasks.js +410 -0
- package/lib/runner/tasks.js.map +7 -0
- package/lib/runner/testGroups.js +117 -0
- package/lib/runner/testGroups.js.map +7 -0
- package/lib/runner/testRunner.js +390 -0
- package/lib/runner/testRunner.js.map +7 -0
- package/lib/runner/testServer.js +264 -0
- package/lib/runner/testServer.js.map +7 -0
- package/lib/runner/uiMode.js +271 -0
- package/lib/runner/uiModeReporter.js +30 -0
- package/lib/runner/uiModeReporter.js.map +7 -0
- package/lib/runner/vcs.js +72 -0
- package/lib/runner/vcs.js.map +7 -0
- package/lib/runner/watchMode.js +395 -0
- package/lib/runner/watchMode.js.map +7 -0
- package/lib/runner/workerHost.js +95 -0
- package/lib/runner/workerHost.js.map +7 -0
- package/lib/store.js +98 -0
- package/lib/third_party/pirates.js +62 -0
- package/lib/third_party/pirates.js.map +7 -0
- package/lib/third_party/tsconfig-loader.js +103 -0
- package/lib/third_party/tsconfig-loader.js.map +7 -0
- package/lib/transform/babelBundle.js +43 -0
- package/lib/transform/babelBundle.js.map +7 -0
- package/lib/transform/babelBundleImpl.js +461 -0
- package/lib/transform/babelBundleImpl.js.map +7 -0
- package/lib/transform/compilationCache.js +272 -0
- package/lib/transform/compilationCache.js.map +7 -0
- package/lib/transform/esmLoader.js +104 -0
- package/lib/transform/esmLoader.js.map +7 -0
- package/lib/transform/esmUtils.js +32 -0
- package/lib/transform/portTransport.js +67 -0
- package/lib/transform/portTransport.js.map +7 -0
- package/lib/transform/transform.js +293 -0
- package/lib/transform/transform.js.map +7 -0
- package/lib/util.js +403 -0
- package/lib/util.js.map +7 -0
- package/lib/utilsBundle.js +43 -0
- package/lib/utilsBundle.js.map +7 -0
- package/lib/utilsBundleImpl.js +100 -0
- package/lib/utilsBundleImpl.js.map +7 -0
- package/lib/worker/fixtureRunner.js +258 -0
- package/lib/worker/fixtureRunner.js.map +7 -0
- package/lib/worker/stepContext.js +34 -0
- package/lib/worker/testInfo.js +508 -0
- package/lib/worker/testInfo.js.map +7 -0
- package/lib/worker/testTracing.js +344 -0
- package/lib/worker/testTracing.js.map +7 -0
- package/lib/worker/timeoutManager.js +174 -0
- package/lib/worker/timeoutManager.js.map +7 -0
- package/lib/worker/util.js +31 -0
- package/lib/worker/util.js.map +7 -0
- package/lib/worker/workerMain.js +520 -0
- package/lib/worker/workerMain.js.map +7 -0
- package/package.json +74 -0
- package/test.d.ts +18 -0
- package/test.js +24 -0
- package/test.mjs +33 -0
- package/types/test.d.ts +10217 -0
- package/types/testReporter.d.ts +816 -0
@@ -0,0 +1,161 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __create = Object.create;
|
3
|
+
var __defProp = Object.defineProperty;
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
8
|
+
var __export = (target, all) => {
|
9
|
+
for (var name in all)
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
11
|
+
};
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
14
|
+
for (let key of __getOwnPropNames(from))
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
17
|
+
}
|
18
|
+
return to;
|
19
|
+
};
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
26
|
+
mod
|
27
|
+
));
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
29
|
+
var processHost_exports = {};
|
30
|
+
__export(processHost_exports, {
|
31
|
+
ProcessHost: () => ProcessHost
|
32
|
+
});
|
33
|
+
module.exports = __toCommonJS(processHost_exports);
|
34
|
+
var import_child_process = __toESM(require("child_process"));
|
35
|
+
var import_events = require("events");
|
36
|
+
var import_utils = require("playwright-core/lib/utils");
|
37
|
+
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
38
|
+
class ProcessHost extends import_events.EventEmitter {
|
39
|
+
constructor(runnerScript, processName, env) {
|
40
|
+
super();
|
41
|
+
this._didSendStop = false;
|
42
|
+
this._processDidExit = false;
|
43
|
+
this._didExitAndRanOnExit = false;
|
44
|
+
this._lastMessageId = 0;
|
45
|
+
this._callbacks = /* @__PURE__ */ new Map();
|
46
|
+
this._producedEnv = {};
|
47
|
+
this._runnerScript = runnerScript;
|
48
|
+
this._processName = processName;
|
49
|
+
this._extraEnv = env;
|
50
|
+
}
|
51
|
+
async startRunner(runnerParams, options = {}) {
|
52
|
+
(0, import_utils.assert)(!this.process, "Internal error: starting the same process twice");
|
53
|
+
this.process = import_child_process.default.fork(require.resolve("../common/process"), {
|
54
|
+
detached: false,
|
55
|
+
env: {
|
56
|
+
...process.env,
|
57
|
+
...this._extraEnv
|
58
|
+
},
|
59
|
+
stdio: [
|
60
|
+
"ignore",
|
61
|
+
options.onStdOut ? "pipe" : "inherit",
|
62
|
+
options.onStdErr && !process.env.PW_RUNNER_DEBUG ? "pipe" : "inherit",
|
63
|
+
"ipc"
|
64
|
+
]
|
65
|
+
});
|
66
|
+
this.process.on("exit", async (code, signal) => {
|
67
|
+
this._processDidExit = true;
|
68
|
+
await this.onExit();
|
69
|
+
this._didExitAndRanOnExit = true;
|
70
|
+
this.emit("exit", { unexpectedly: !this._didSendStop, code, signal });
|
71
|
+
});
|
72
|
+
this.process.on("error", (e) => {
|
73
|
+
});
|
74
|
+
this.process.on("message", (message) => {
|
75
|
+
if (import_utilsBundle.debug.enabled("pw:test:protocol"))
|
76
|
+
(0, import_utilsBundle.debug)("pw:test:protocol")("\u25C0 RECV " + JSON.stringify(message));
|
77
|
+
if (message.method === "__env_produced__") {
|
78
|
+
const producedEnv = message.params;
|
79
|
+
this._producedEnv = Object.fromEntries(producedEnv.map((e) => [e[0], e[1] ?? void 0]));
|
80
|
+
} else if (message.method === "__dispatch__") {
|
81
|
+
const { id, error: error2, method, params, result } = message.params;
|
82
|
+
if (id && this._callbacks.has(id)) {
|
83
|
+
const { resolve, reject } = this._callbacks.get(id);
|
84
|
+
this._callbacks.delete(id);
|
85
|
+
if (error2) {
|
86
|
+
const errorObject = new Error(error2.message);
|
87
|
+
errorObject.stack = error2.stack;
|
88
|
+
reject(errorObject);
|
89
|
+
} else {
|
90
|
+
resolve(result);
|
91
|
+
}
|
92
|
+
} else {
|
93
|
+
this.emit(method, params);
|
94
|
+
}
|
95
|
+
} else {
|
96
|
+
this.emit(message.method, message.params);
|
97
|
+
}
|
98
|
+
});
|
99
|
+
if (options.onStdOut)
|
100
|
+
this.process.stdout?.on("data", options.onStdOut);
|
101
|
+
if (options.onStdErr)
|
102
|
+
this.process.stderr?.on("data", options.onStdErr);
|
103
|
+
const error = await new Promise((resolve) => {
|
104
|
+
this.process.once("exit", (code, signal) => resolve({ unexpectedly: true, code, signal }));
|
105
|
+
this.once("ready", () => resolve(void 0));
|
106
|
+
});
|
107
|
+
if (error)
|
108
|
+
return error;
|
109
|
+
const processParams = {
|
110
|
+
processName: this._processName,
|
111
|
+
timeOrigin: (0, import_utils.timeOrigin)()
|
112
|
+
};
|
113
|
+
this.send({
|
114
|
+
method: "__init__",
|
115
|
+
params: {
|
116
|
+
processParams,
|
117
|
+
runnerScript: this._runnerScript,
|
118
|
+
runnerParams
|
119
|
+
}
|
120
|
+
});
|
121
|
+
}
|
122
|
+
sendMessage(message) {
|
123
|
+
const id = ++this._lastMessageId;
|
124
|
+
this.send({
|
125
|
+
method: "__dispatch__",
|
126
|
+
params: { id, ...message }
|
127
|
+
});
|
128
|
+
return new Promise((resolve, reject) => {
|
129
|
+
this._callbacks.set(id, { resolve, reject });
|
130
|
+
});
|
131
|
+
}
|
132
|
+
sendMessageNoReply(message) {
|
133
|
+
this.sendMessage(message).catch(() => {
|
134
|
+
});
|
135
|
+
}
|
136
|
+
async onExit() {
|
137
|
+
}
|
138
|
+
async stop() {
|
139
|
+
if (!this._processDidExit && !this._didSendStop) {
|
140
|
+
this.send({ method: "__stop__" });
|
141
|
+
this._didSendStop = true;
|
142
|
+
}
|
143
|
+
if (!this._didExitAndRanOnExit)
|
144
|
+
await new Promise((f) => this.once("exit", f));
|
145
|
+
}
|
146
|
+
didSendStop() {
|
147
|
+
return this._didSendStop;
|
148
|
+
}
|
149
|
+
producedEnv() {
|
150
|
+
return this._producedEnv;
|
151
|
+
}
|
152
|
+
send(message) {
|
153
|
+
if (import_utilsBundle.debug.enabled("pw:test:protocol"))
|
154
|
+
(0, import_utilsBundle.debug)("pw:test:protocol")("SEND \u25BA " + JSON.stringify(message));
|
155
|
+
this.process?.send(message);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
// Annotate the CommonJS export names for ESM import in node:
|
159
|
+
0 && (module.exports = {
|
160
|
+
ProcessHost
|
161
|
+
});
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../src/runner/processHost.ts"],
|
4
|
+
"sourcesContent": ["/**\n * Copyright Microsoft Corporation. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport child_process from 'child_process';\nimport { EventEmitter } from 'events';\n\nimport { assert, timeOrigin } from 'playwright-core/lib/utils';\nimport { debug } from 'playwright-core/lib/utilsBundle';\n\nimport type { EnvProducedPayload, ProcessInitParams } from '../common/ipc';\nimport type { ProtocolResponse } from '../common/process';\n\nexport type ProcessExitData = {\n unexpectedly: boolean;\n code: number | null;\n signal: NodeJS.Signals | null;\n};\n\nexport class ProcessHost extends EventEmitter {\n private process: child_process.ChildProcess | undefined;\n private _didSendStop = false;\n private _processDidExit = false;\n private _didExitAndRanOnExit = false;\n private _runnerScript: string;\n private _lastMessageId = 0;\n private _callbacks = new Map<number, { resolve: (result: any) => void, reject: (error: Error) => void }>();\n private _processName: string;\n private _producedEnv: Record<string, string | undefined> = {};\n private _extraEnv: Record<string, string | undefined>;\n\n constructor(runnerScript: string, processName: string, env: Record<string, string | undefined>) {\n super();\n this._runnerScript = runnerScript;\n this._processName = processName;\n this._extraEnv = env;\n }\n\n async startRunner(runnerParams: any, options: { onStdOut?: (chunk: Buffer | string) => void, onStdErr?: (chunk: Buffer | string) => void } = {}): Promise<ProcessExitData | undefined> {\n assert(!this.process, 'Internal error: starting the same process twice');\n this.process = child_process.fork(require.resolve('../common/process'), {\n detached: false,\n env: {\n ...process.env,\n ...this._extraEnv,\n },\n stdio: [\n 'ignore',\n options.onStdOut ? 'pipe' : 'inherit',\n (options.onStdErr && !process.env.PW_RUNNER_DEBUG) ? 'pipe' : 'inherit',\n 'ipc',\n ],\n });\n this.process.on('exit', async (code, signal) => {\n this._processDidExit = true;\n await this.onExit();\n this._didExitAndRanOnExit = true;\n this.emit('exit', { unexpectedly: !this._didSendStop, code, signal } as ProcessExitData);\n });\n this.process.on('error', e => {}); // do not yell at a send to dead process.\n this.process.on('message', (message: any) => {\n if (debug.enabled('pw:test:protocol'))\n debug('pw:test:protocol')('\u25C0 RECV ' + JSON.stringify(message));\n if (message.method === '__env_produced__') {\n const producedEnv: EnvProducedPayload = message.params;\n this._producedEnv = Object.fromEntries(producedEnv.map(e => [e[0], e[1] ?? undefined]));\n } else if (message.method === '__dispatch__') {\n const { id, error, method, params, result } = message.params as ProtocolResponse;\n if (id && this._callbacks.has(id)) {\n const { resolve, reject } = this._callbacks.get(id)!;\n this._callbacks.delete(id);\n if (error) {\n const errorObject = new Error(error.message);\n errorObject.stack = error.stack;\n reject(errorObject);\n } else {\n resolve(result);\n }\n } else {\n this.emit(method!, params);\n }\n } else {\n this.emit(message.method!, message.params);\n }\n });\n\n if (options.onStdOut)\n this.process.stdout?.on('data', options.onStdOut);\n if (options.onStdErr)\n this.process.stderr?.on('data', options.onStdErr);\n\n const error = await new Promise<ProcessExitData | undefined>(resolve => {\n this.process!.once('exit', (code, signal) => resolve({ unexpectedly: true, code, signal }));\n this.once('ready', () => resolve(undefined));\n });\n\n if (error)\n return error;\n\n const processParams: ProcessInitParams = {\n processName: this._processName,\n timeOrigin: timeOrigin(),\n };\n\n this.send({\n method: '__init__', params: {\n processParams,\n runnerScript: this._runnerScript,\n runnerParams\n }\n });\n }\n\n sendMessage(message: { method: string, params?: any }) {\n const id = ++this._lastMessageId;\n this.send({\n method: '__dispatch__',\n params: { id, ...message }\n });\n return new Promise((resolve, reject) => {\n this._callbacks.set(id, { resolve, reject });\n });\n }\n\n protected sendMessageNoReply(message: { method: string, params?: any }) {\n this.sendMessage(message).catch(() => {});\n }\n\n protected async onExit() {\n }\n\n async stop() {\n if (!this._processDidExit && !this._didSendStop) {\n this.send({ method: '__stop__' });\n this._didSendStop = true;\n }\n if (!this._didExitAndRanOnExit)\n await new Promise(f => this.once('exit', f));\n }\n\n didSendStop() {\n return this._didSendStop;\n }\n\n producedEnv() {\n return this._producedEnv;\n }\n\n private send(message: { method: string, params?: any }) {\n if (debug.enabled('pw:test:protocol'))\n debug('pw:test:protocol')('SEND \u25BA ' + JSON.stringify(message));\n this.process?.send(message);\n }\n}\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["child_process", "error"]
|
7
|
+
}
|
@@ -0,0 +1,241 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __create = Object.create;
|
3
|
+
var __defProp = Object.defineProperty;
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
8
|
+
var __export = (target, all) => {
|
9
|
+
for (var name in all)
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
11
|
+
};
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
14
|
+
for (let key of __getOwnPropNames(from))
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
17
|
+
}
|
18
|
+
return to;
|
19
|
+
};
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
26
|
+
mod
|
27
|
+
));
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
29
|
+
var projectUtils_exports = {};
|
30
|
+
__export(projectUtils_exports, {
|
31
|
+
buildDependentProjects: () => buildDependentProjects,
|
32
|
+
buildProjectsClosure: () => buildProjectsClosure,
|
33
|
+
buildTeardownToSetupsMap: () => buildTeardownToSetupsMap,
|
34
|
+
collectFilesForProject: () => collectFilesForProject,
|
35
|
+
filterProjects: () => filterProjects,
|
36
|
+
findTopLevelProjects: () => findTopLevelProjects
|
37
|
+
});
|
38
|
+
module.exports = __toCommonJS(projectUtils_exports);
|
39
|
+
var import_fs = __toESM(require("fs"));
|
40
|
+
var import_path = __toESM(require("path"));
|
41
|
+
var import_util = require("util");
|
42
|
+
var import_utils = require("playwright-core/lib/utils");
|
43
|
+
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
44
|
+
var import_util2 = require("../util");
|
45
|
+
const readFileAsync = (0, import_util.promisify)(import_fs.default.readFile);
|
46
|
+
const readDirAsync = (0, import_util.promisify)(import_fs.default.readdir);
|
47
|
+
function wildcardPatternToRegExp(pattern) {
|
48
|
+
return new RegExp("^" + pattern.split("*").map(import_utils.escapeRegExp).join(".*") + "$", "ig");
|
49
|
+
}
|
50
|
+
function filterProjects(projects, projectNames) {
|
51
|
+
if (!projectNames)
|
52
|
+
return [...projects];
|
53
|
+
const projectNamesToFind = /* @__PURE__ */ new Set();
|
54
|
+
const unmatchedProjectNames = /* @__PURE__ */ new Map();
|
55
|
+
const patterns = /* @__PURE__ */ new Set();
|
56
|
+
for (const name of projectNames) {
|
57
|
+
const lowerCaseName = name.toLocaleLowerCase();
|
58
|
+
if (lowerCaseName.includes("*")) {
|
59
|
+
patterns.add(wildcardPatternToRegExp(lowerCaseName));
|
60
|
+
} else {
|
61
|
+
projectNamesToFind.add(lowerCaseName);
|
62
|
+
unmatchedProjectNames.set(lowerCaseName, name);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
const result = projects.filter((project) => {
|
66
|
+
const lowerCaseName = project.project.name.toLocaleLowerCase();
|
67
|
+
if (projectNamesToFind.has(lowerCaseName)) {
|
68
|
+
unmatchedProjectNames.delete(lowerCaseName);
|
69
|
+
return true;
|
70
|
+
}
|
71
|
+
for (const regex of patterns) {
|
72
|
+
regex.lastIndex = 0;
|
73
|
+
if (regex.test(lowerCaseName))
|
74
|
+
return true;
|
75
|
+
}
|
76
|
+
return false;
|
77
|
+
});
|
78
|
+
if (unmatchedProjectNames.size) {
|
79
|
+
const unknownProjectNames = Array.from(unmatchedProjectNames.values()).map((n) => `"${n}"`).join(", ");
|
80
|
+
throw new Error(`Project(s) ${unknownProjectNames} not found. Available projects: ${projects.map((p) => `"${p.project.name}"`).join(", ")}`);
|
81
|
+
}
|
82
|
+
if (!result.length) {
|
83
|
+
const allProjects = projects.map((p) => `"${p.project.name}"`).join(", ");
|
84
|
+
throw new Error(`No projects matched. Available projects: ${allProjects}`);
|
85
|
+
}
|
86
|
+
return result;
|
87
|
+
}
|
88
|
+
function buildTeardownToSetupsMap(projects) {
|
89
|
+
const result = /* @__PURE__ */ new Map();
|
90
|
+
for (const project of projects) {
|
91
|
+
if (project.teardown) {
|
92
|
+
const setups = result.get(project.teardown) || [];
|
93
|
+
setups.push(project);
|
94
|
+
result.set(project.teardown, setups);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
return result;
|
98
|
+
}
|
99
|
+
function buildProjectsClosure(projects, hasTests) {
|
100
|
+
const result = /* @__PURE__ */ new Map();
|
101
|
+
const visit = (depth, project) => {
|
102
|
+
if (depth > 100) {
|
103
|
+
const error = new Error("Circular dependency detected between projects.");
|
104
|
+
error.stack = "";
|
105
|
+
throw error;
|
106
|
+
}
|
107
|
+
if (depth === 0 && hasTests && !hasTests(project))
|
108
|
+
return;
|
109
|
+
if (result.get(project) !== "dependency")
|
110
|
+
result.set(project, depth ? "dependency" : "top-level");
|
111
|
+
for (const dep of project.deps)
|
112
|
+
visit(depth + 1, dep);
|
113
|
+
if (project.teardown)
|
114
|
+
visit(depth + 1, project.teardown);
|
115
|
+
};
|
116
|
+
for (const p of projects)
|
117
|
+
visit(0, p);
|
118
|
+
return result;
|
119
|
+
}
|
120
|
+
function findTopLevelProjects(config) {
|
121
|
+
const closure = buildProjectsClosure(config.projects);
|
122
|
+
return [...closure].filter((entry) => entry[1] === "top-level").map((entry) => entry[0]);
|
123
|
+
}
|
124
|
+
function buildDependentProjects(forProjects, projects) {
|
125
|
+
const reverseDeps = new Map(projects.map((p) => [p, []]));
|
126
|
+
for (const project of projects) {
|
127
|
+
for (const dep of project.deps)
|
128
|
+
reverseDeps.get(dep).push(project);
|
129
|
+
}
|
130
|
+
const result = /* @__PURE__ */ new Set();
|
131
|
+
const visit = (depth, project) => {
|
132
|
+
if (depth > 100) {
|
133
|
+
const error = new Error("Circular dependency detected between projects.");
|
134
|
+
error.stack = "";
|
135
|
+
throw error;
|
136
|
+
}
|
137
|
+
result.add(project);
|
138
|
+
for (const reverseDep of reverseDeps.get(project))
|
139
|
+
visit(depth + 1, reverseDep);
|
140
|
+
if (project.teardown)
|
141
|
+
visit(depth + 1, project.teardown);
|
142
|
+
};
|
143
|
+
for (const forProject of forProjects)
|
144
|
+
visit(0, forProject);
|
145
|
+
return result;
|
146
|
+
}
|
147
|
+
async function collectFilesForProject(project, fsCache = /* @__PURE__ */ new Map()) {
|
148
|
+
const extensions = /* @__PURE__ */ new Set([".js", ".ts", ".mjs", ".mts", ".cjs", ".cts", ".jsx", ".tsx", ".mjsx", ".mtsx", ".cjsx", ".ctsx"]);
|
149
|
+
const testFileExtension = (file) => extensions.has(import_path.default.extname(file));
|
150
|
+
const allFiles = await cachedCollectFiles(project.project.testDir, project.respectGitIgnore, fsCache);
|
151
|
+
const testMatch = (0, import_util2.createFileMatcher)(project.project.testMatch);
|
152
|
+
const testIgnore = (0, import_util2.createFileMatcher)(project.project.testIgnore);
|
153
|
+
const testFiles = allFiles.filter((file) => {
|
154
|
+
if (!testFileExtension(file))
|
155
|
+
return false;
|
156
|
+
const isTest = !testIgnore(file) && testMatch(file);
|
157
|
+
if (!isTest)
|
158
|
+
return false;
|
159
|
+
return true;
|
160
|
+
});
|
161
|
+
return testFiles;
|
162
|
+
}
|
163
|
+
async function cachedCollectFiles(testDir, respectGitIgnore, fsCache) {
|
164
|
+
const key = testDir + ":" + respectGitIgnore;
|
165
|
+
let result = fsCache.get(key);
|
166
|
+
if (!result) {
|
167
|
+
result = await collectFiles(testDir, respectGitIgnore);
|
168
|
+
fsCache.set(key, result);
|
169
|
+
}
|
170
|
+
return result;
|
171
|
+
}
|
172
|
+
async function collectFiles(testDir, respectGitIgnore) {
|
173
|
+
if (!import_fs.default.existsSync(testDir))
|
174
|
+
return [];
|
175
|
+
if (!import_fs.default.statSync(testDir).isDirectory())
|
176
|
+
return [];
|
177
|
+
const checkIgnores = (entryPath, rules, isDirectory, parentStatus) => {
|
178
|
+
let status = parentStatus;
|
179
|
+
for (const rule of rules) {
|
180
|
+
const ruleIncludes = rule.negate;
|
181
|
+
if (status === "included" === ruleIncludes)
|
182
|
+
continue;
|
183
|
+
const relative = import_path.default.relative(rule.dir, entryPath);
|
184
|
+
if (rule.match("/" + relative) || rule.match(relative)) {
|
185
|
+
status = ruleIncludes ? "included" : "ignored";
|
186
|
+
} else if (isDirectory && (rule.match("/" + relative + "/") || rule.match(relative + "/"))) {
|
187
|
+
status = ruleIncludes ? "included" : "ignored";
|
188
|
+
} else if (isDirectory && ruleIncludes && (rule.match("/" + relative, true) || rule.match(relative, true))) {
|
189
|
+
status = "ignored-but-recurse";
|
190
|
+
}
|
191
|
+
}
|
192
|
+
return status;
|
193
|
+
};
|
194
|
+
const files = [];
|
195
|
+
const visit = async (dir, rules, status) => {
|
196
|
+
const entries = await readDirAsync(dir, { withFileTypes: true });
|
197
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
198
|
+
if (respectGitIgnore) {
|
199
|
+
const gitignore = entries.find((e) => e.isFile() && e.name === ".gitignore");
|
200
|
+
if (gitignore) {
|
201
|
+
const content = await readFileAsync(import_path.default.join(dir, gitignore.name), "utf8");
|
202
|
+
const newRules = content.split(/\r?\n/).map((s) => {
|
203
|
+
s = s.trim();
|
204
|
+
if (!s)
|
205
|
+
return;
|
206
|
+
const rule = new import_utilsBundle.minimatch.Minimatch(s, { matchBase: true, dot: true, flipNegate: true });
|
207
|
+
if (rule.comment)
|
208
|
+
return;
|
209
|
+
rule.dir = dir;
|
210
|
+
return rule;
|
211
|
+
}).filter((rule) => !!rule);
|
212
|
+
rules = [...rules, ...newRules];
|
213
|
+
}
|
214
|
+
}
|
215
|
+
for (const entry of entries) {
|
216
|
+
if (entry.name === "." || entry.name === "..")
|
217
|
+
continue;
|
218
|
+
if (entry.isFile() && entry.name === ".gitignore")
|
219
|
+
continue;
|
220
|
+
if (entry.isDirectory() && entry.name === "node_modules")
|
221
|
+
continue;
|
222
|
+
const entryPath = import_path.default.join(dir, entry.name);
|
223
|
+
const entryStatus = checkIgnores(entryPath, rules, entry.isDirectory(), status);
|
224
|
+
if (entry.isDirectory() && entryStatus !== "ignored")
|
225
|
+
await visit(entryPath, rules, entryStatus);
|
226
|
+
else if (entry.isFile() && entryStatus === "included")
|
227
|
+
files.push(entryPath);
|
228
|
+
}
|
229
|
+
};
|
230
|
+
await visit(testDir, [], "included");
|
231
|
+
return files;
|
232
|
+
}
|
233
|
+
// Annotate the CommonJS export names for ESM import in node:
|
234
|
+
0 && (module.exports = {
|
235
|
+
buildDependentProjects,
|
236
|
+
buildProjectsClosure,
|
237
|
+
buildTeardownToSetupsMap,
|
238
|
+
collectFilesForProject,
|
239
|
+
filterProjects,
|
240
|
+
findTopLevelProjects
|
241
|
+
});
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../src/runner/projectUtils.ts"],
|
4
|
+
"sourcesContent": ["/**\n * Copyright Microsoft Corporation. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { promisify } from 'util';\n\nimport { escapeRegExp } from 'playwright-core/lib/utils';\nimport { minimatch } from 'playwright-core/lib/utilsBundle';\n\nimport { createFileMatcher } from '../util';\n\nimport type { FullProjectInternal } from '../common/config';\n\n\nconst readFileAsync = promisify(fs.readFile);\nconst readDirAsync = promisify(fs.readdir);\n\nfunction wildcardPatternToRegExp(pattern: string): RegExp {\n return new RegExp('^' + pattern.split('*').map(escapeRegExp).join('.*') + '$', 'ig');\n}\n\nexport function filterProjects(projects: FullProjectInternal[], projectNames?: string[]): FullProjectInternal[] {\n if (!projectNames)\n return [...projects];\n\n const projectNamesToFind = new Set<string>();\n const unmatchedProjectNames = new Map<string, string>();\n const patterns = new Set<RegExp>();\n for (const name of projectNames!) {\n const lowerCaseName = name.toLocaleLowerCase();\n if (lowerCaseName.includes('*')) {\n patterns.add(wildcardPatternToRegExp(lowerCaseName));\n } else {\n projectNamesToFind.add(lowerCaseName);\n unmatchedProjectNames.set(lowerCaseName, name);\n }\n }\n\n const result = projects.filter(project => {\n const lowerCaseName = project.project.name.toLocaleLowerCase();\n if (projectNamesToFind.has(lowerCaseName)) {\n unmatchedProjectNames.delete(lowerCaseName);\n return true;\n }\n for (const regex of patterns) {\n regex.lastIndex = 0;\n if (regex.test(lowerCaseName))\n return true;\n }\n return false;\n });\n\n if (unmatchedProjectNames.size) {\n const unknownProjectNames = Array.from(unmatchedProjectNames.values()).map(n => `\"${n}\"`).join(', ');\n throw new Error(`Project(s) ${unknownProjectNames} not found. Available projects: ${projects.map(p => `\"${p.project.name}\"`).join(', ')}`);\n }\n\n if (!result.length) {\n const allProjects = projects.map(p => `\"${p.project.name}\"`).join(', ');\n throw new Error(`No projects matched. Available projects: ${allProjects}`);\n }\n\n\n return result;\n}\n\nexport function buildTeardownToSetupsMap(projects: FullProjectInternal[]): Map<FullProjectInternal, FullProjectInternal[]> {\n const result = new Map<FullProjectInternal, FullProjectInternal[]>();\n for (const project of projects) {\n if (project.teardown) {\n const setups = result.get(project.teardown) || [];\n setups.push(project);\n result.set(project.teardown, setups);\n }\n }\n return result;\n}\n\nexport function buildProjectsClosure(projects: FullProjectInternal[], hasTests?: (project: FullProjectInternal) => boolean): Map<FullProjectInternal, 'top-level' | 'dependency'> {\n const result = new Map<FullProjectInternal, 'top-level' | 'dependency'>();\n const visit = (depth: number, project: FullProjectInternal) => {\n if (depth > 100) {\n const error = new Error('Circular dependency detected between projects.');\n error.stack = '';\n throw error;\n }\n\n if (depth === 0 && hasTests && !hasTests(project))\n return;\n\n if (result.get(project) !== 'dependency')\n result.set(project, depth ? 'dependency' : 'top-level');\n\n for (const dep of project.deps)\n visit(depth + 1, dep);\n if (project.teardown)\n visit(depth + 1, project.teardown);\n };\n for (const p of projects)\n visit(0, p);\n return result;\n}\n\nexport function buildDependentProjects(forProjects: FullProjectInternal[], projects: FullProjectInternal[]): Set<FullProjectInternal> {\n const reverseDeps = new Map<FullProjectInternal, FullProjectInternal[]>(projects.map(p => ([p, []])));\n for (const project of projects) {\n for (const dep of project.deps)\n reverseDeps.get(dep)!.push(project);\n }\n const result = new Set<FullProjectInternal>();\n const visit = (depth: number, project: FullProjectInternal) => {\n if (depth > 100) {\n const error = new Error('Circular dependency detected between projects.');\n error.stack = '';\n throw error;\n }\n result.add(project);\n for (const reverseDep of reverseDeps.get(project)!)\n visit(depth + 1, reverseDep);\n if (project.teardown)\n visit(depth + 1, project.teardown);\n };\n for (const forProject of forProjects)\n visit(0, forProject);\n return result;\n}\n\nexport async function collectFilesForProject(project: FullProjectInternal, fsCache = new Map<string, string[]>()): Promise<string[]> {\n const extensions = new Set(['.js', '.ts', '.mjs', '.mts', '.cjs', '.cts', '.jsx', '.tsx', '.mjsx', '.mtsx', '.cjsx', '.ctsx']);\n const testFileExtension = (file: string) => extensions.has(path.extname(file));\n const allFiles = await cachedCollectFiles(project.project.testDir, project.respectGitIgnore, fsCache);\n const testMatch = createFileMatcher(project.project.testMatch);\n const testIgnore = createFileMatcher(project.project.testIgnore);\n const testFiles = allFiles.filter(file => {\n if (!testFileExtension(file))\n return false;\n const isTest = !testIgnore(file) && testMatch(file);\n if (!isTest)\n return false;\n return true;\n });\n return testFiles;\n}\n\nasync function cachedCollectFiles(testDir: string, respectGitIgnore: boolean, fsCache: Map<string, string[]>) {\n const key = testDir + ':' + respectGitIgnore;\n let result = fsCache.get(key);\n if (!result) {\n result = await collectFiles(testDir, respectGitIgnore);\n fsCache.set(key, result);\n }\n return result;\n}\n\nasync function collectFiles(testDir: string, respectGitIgnore: boolean): Promise<string[]> {\n if (!fs.existsSync(testDir))\n return [];\n if (!fs.statSync(testDir).isDirectory())\n return [];\n\n type Rule = {\n dir: string;\n negate: boolean;\n match: (s: string, partial?: boolean) => boolean\n };\n type IgnoreStatus = 'ignored' | 'included' | 'ignored-but-recurse';\n\n const checkIgnores = (entryPath: string, rules: Rule[], isDirectory: boolean, parentStatus: IgnoreStatus) => {\n let status = parentStatus;\n for (const rule of rules) {\n const ruleIncludes = rule.negate;\n if ((status === 'included') === ruleIncludes)\n continue;\n const relative = path.relative(rule.dir, entryPath);\n if (rule.match('/' + relative) || rule.match(relative)) {\n // Matches \"/dir/file\" or \"dir/file\"\n status = ruleIncludes ? 'included' : 'ignored';\n } else if (isDirectory && (rule.match('/' + relative + '/') || rule.match(relative + '/'))) {\n // Matches \"/dir/subdir/\" or \"dir/subdir/\" for directories.\n status = ruleIncludes ? 'included' : 'ignored';\n } else if (isDirectory && ruleIncludes && (rule.match('/' + relative, true) || rule.match(relative, true))) {\n // Matches \"/dir/donotskip/\" when \"/dir\" is excluded, but \"!/dir/donotskip/file\" is included.\n status = 'ignored-but-recurse';\n }\n }\n return status;\n };\n\n const files: string[] = [];\n\n const visit = async (dir: string, rules: Rule[], status: IgnoreStatus) => {\n const entries = await readDirAsync(dir, { withFileTypes: true });\n entries.sort((a, b) => a.name.localeCompare(b.name));\n\n if (respectGitIgnore) {\n const gitignore = entries.find(e => e.isFile() && e.name === '.gitignore');\n if (gitignore) {\n const content = await readFileAsync(path.join(dir, gitignore.name), 'utf8');\n const newRules: Rule[] = content.split(/\\r?\\n/).map(s => {\n s = s.trim();\n if (!s)\n return;\n // Use flipNegate, because we handle negation ourselves.\n const rule = new minimatch.Minimatch(s, { matchBase: true, dot: true, flipNegate: true }) as any;\n if (rule.comment)\n return;\n rule.dir = dir;\n return rule;\n }).filter(rule => !!rule);\n rules = [...rules, ...newRules];\n }\n }\n\n for (const entry of entries) {\n if (entry.name === '.' || entry.name === '..')\n continue;\n if (entry.isFile() && entry.name === '.gitignore')\n continue;\n if (entry.isDirectory() && entry.name === 'node_modules')\n continue;\n const entryPath = path.join(dir, entry.name);\n const entryStatus = checkIgnores(entryPath, rules, entry.isDirectory(), status);\n if (entry.isDirectory() && entryStatus !== 'ignored')\n await visit(entryPath, rules, entryStatus);\n else if (entry.isFile() && entryStatus === 'included')\n files.push(entryPath);\n }\n };\n await visit(testDir, [], 'included');\n return files;\n}\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["import_util", "fs", "path"]
|
7
|
+
}
|
@@ -0,0 +1,189 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __create = Object.create;
|
3
|
+
var __defProp = Object.defineProperty;
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
8
|
+
var __export = (target, all) => {
|
9
|
+
for (var name in all)
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
11
|
+
};
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
14
|
+
for (let key of __getOwnPropNames(from))
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
17
|
+
}
|
18
|
+
return to;
|
19
|
+
};
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
26
|
+
mod
|
27
|
+
));
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
29
|
+
var rebase_exports = {};
|
30
|
+
__export(rebase_exports, {
|
31
|
+
addSuggestedRebaseline: () => addSuggestedRebaseline,
|
32
|
+
applySuggestedRebaselines: () => applySuggestedRebaselines,
|
33
|
+
clearSuggestedRebaselines: () => clearSuggestedRebaselines
|
34
|
+
});
|
35
|
+
module.exports = __toCommonJS(rebase_exports);
|
36
|
+
var import_fs = __toESM(require("fs"));
|
37
|
+
var import_path = __toESM(require("path"));
|
38
|
+
var import_utils = require("playwright-core/lib/utils");
|
39
|
+
var import_utils2 = require("playwright-core/lib/utils");
|
40
|
+
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
41
|
+
var import_projectUtils = require("./projectUtils");
|
42
|
+
var import_babelBundle = require("../transform/babelBundle");
|
43
|
+
const t = import_babelBundle.types;
|
44
|
+
const suggestedRebaselines = new import_utils.MultiMap();
|
45
|
+
function addSuggestedRebaseline(location, suggestedRebaseline) {
|
46
|
+
suggestedRebaselines.set(location.file, { location, code: suggestedRebaseline });
|
47
|
+
}
|
48
|
+
function clearSuggestedRebaselines() {
|
49
|
+
suggestedRebaselines.clear();
|
50
|
+
}
|
51
|
+
async function applySuggestedRebaselines(config, reporter) {
|
52
|
+
if (config.config.updateSnapshots === "none")
|
53
|
+
return;
|
54
|
+
if (!suggestedRebaselines.size)
|
55
|
+
return;
|
56
|
+
const [project] = (0, import_projectUtils.filterProjects)(config.projects, config.cliProjectFilter);
|
57
|
+
if (!project)
|
58
|
+
return;
|
59
|
+
const patches = [];
|
60
|
+
const files = [];
|
61
|
+
const gitCache = /* @__PURE__ */ new Map();
|
62
|
+
const patchFile = import_path.default.join(project.project.outputDir, "rebaselines.patch");
|
63
|
+
for (const fileName of [...suggestedRebaselines.keys()].sort()) {
|
64
|
+
const source = await import_fs.default.promises.readFile(fileName, "utf8");
|
65
|
+
const lines = source.split("\n");
|
66
|
+
const replacements = suggestedRebaselines.get(fileName);
|
67
|
+
const fileNode = (0, import_babelBundle.babelParse)(source, fileName, true);
|
68
|
+
const ranges = [];
|
69
|
+
(0, import_babelBundle.traverse)(fileNode, {
|
70
|
+
CallExpression: (path2) => {
|
71
|
+
const node = path2.node;
|
72
|
+
if (node.arguments.length < 1)
|
73
|
+
return;
|
74
|
+
if (!t.isMemberExpression(node.callee))
|
75
|
+
return;
|
76
|
+
const argument = node.arguments[0];
|
77
|
+
if (!t.isStringLiteral(argument) && !t.isTemplateLiteral(argument))
|
78
|
+
return;
|
79
|
+
const prop = node.callee.property;
|
80
|
+
if (!prop.loc || !argument.start || !argument.end)
|
81
|
+
return;
|
82
|
+
for (const replacement of replacements) {
|
83
|
+
if (prop.loc.start.line !== replacement.location.line)
|
84
|
+
continue;
|
85
|
+
if (prop.loc.start.column + 1 !== replacement.location.column)
|
86
|
+
continue;
|
87
|
+
const indent = lines[prop.loc.start.line - 1].match(/^\s*/)[0];
|
88
|
+
const newText = replacement.code.replace(/\{indent\}/g, indent);
|
89
|
+
ranges.push({ start: argument.start, end: argument.end, oldText: source.substring(argument.start, argument.end), newText });
|
90
|
+
break;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
});
|
94
|
+
ranges.sort((a, b) => b.start - a.start);
|
95
|
+
let result = source;
|
96
|
+
for (const range of ranges)
|
97
|
+
result = result.substring(0, range.start) + range.newText + result.substring(range.end);
|
98
|
+
const relativeName = import_path.default.relative(process.cwd(), fileName);
|
99
|
+
files.push(relativeName);
|
100
|
+
if (config.config.updateSourceMethod === "overwrite") {
|
101
|
+
await import_fs.default.promises.writeFile(fileName, result);
|
102
|
+
} else if (config.config.updateSourceMethod === "3way") {
|
103
|
+
await import_fs.default.promises.writeFile(fileName, applyPatchWithConflictMarkers(source, result));
|
104
|
+
} else {
|
105
|
+
const gitFolder = findGitRoot(import_path.default.dirname(fileName), gitCache);
|
106
|
+
const relativeToGit = import_path.default.relative(gitFolder || process.cwd(), fileName);
|
107
|
+
patches.push(createPatch(relativeToGit, source, result));
|
108
|
+
}
|
109
|
+
}
|
110
|
+
const fileList = files.map((file) => " " + import_utils2.colors.dim(file)).join("\n");
|
111
|
+
reporter.onStdErr(`
|
112
|
+
New baselines created for:
|
113
|
+
|
114
|
+
${fileList}
|
115
|
+
`);
|
116
|
+
if (config.config.updateSourceMethod === "patch") {
|
117
|
+
await import_fs.default.promises.mkdir(import_path.default.dirname(patchFile), { recursive: true });
|
118
|
+
await import_fs.default.promises.writeFile(patchFile, patches.join("\n"));
|
119
|
+
reporter.onStdErr(`
|
120
|
+
` + import_utils2.colors.cyan("git apply " + import_path.default.relative(process.cwd(), patchFile)) + "\n");
|
121
|
+
}
|
122
|
+
}
|
123
|
+
function createPatch(fileName, before, after) {
|
124
|
+
const file = fileName.replace(/\\/g, "/");
|
125
|
+
const text = import_utilsBundle.diff.createPatch(file, before, after, void 0, void 0, { context: 3 });
|
126
|
+
return [
|
127
|
+
"diff --git a/" + file + " b/" + file,
|
128
|
+
"--- a/" + file,
|
129
|
+
"+++ b/" + file,
|
130
|
+
...text.split("\n").slice(4)
|
131
|
+
].join("\n");
|
132
|
+
}
|
133
|
+
function findGitRoot(dir, cache) {
|
134
|
+
const result = cache.get(dir);
|
135
|
+
if (result !== void 0)
|
136
|
+
return result;
|
137
|
+
const gitPath = import_path.default.join(dir, ".git");
|
138
|
+
if (import_fs.default.existsSync(gitPath) && import_fs.default.lstatSync(gitPath).isDirectory()) {
|
139
|
+
cache.set(dir, dir);
|
140
|
+
return dir;
|
141
|
+
}
|
142
|
+
const parentDir = import_path.default.dirname(dir);
|
143
|
+
if (dir === parentDir) {
|
144
|
+
cache.set(dir, null);
|
145
|
+
return null;
|
146
|
+
}
|
147
|
+
const parentResult = findGitRoot(parentDir, cache);
|
148
|
+
cache.set(dir, parentResult);
|
149
|
+
return parentResult;
|
150
|
+
}
|
151
|
+
function applyPatchWithConflictMarkers(oldText, newText) {
|
152
|
+
const diffResult = import_utilsBundle.diff.diffLines(oldText, newText);
|
153
|
+
let result = "";
|
154
|
+
let conflict = false;
|
155
|
+
diffResult.forEach((part) => {
|
156
|
+
if (part.added) {
|
157
|
+
if (conflict) {
|
158
|
+
result += part.value;
|
159
|
+
result += ">>>>>>> SNAPSHOT\n";
|
160
|
+
conflict = false;
|
161
|
+
} else {
|
162
|
+
result += "<<<<<<< HEAD\n";
|
163
|
+
result += part.value;
|
164
|
+
result += "=======\n";
|
165
|
+
conflict = true;
|
166
|
+
}
|
167
|
+
} else if (part.removed) {
|
168
|
+
result += "<<<<<<< HEAD\n";
|
169
|
+
result += part.value;
|
170
|
+
result += "=======\n";
|
171
|
+
conflict = true;
|
172
|
+
} else {
|
173
|
+
if (conflict) {
|
174
|
+
result += ">>>>>>> SNAPSHOT\n";
|
175
|
+
conflict = false;
|
176
|
+
}
|
177
|
+
result += part.value;
|
178
|
+
}
|
179
|
+
});
|
180
|
+
if (conflict)
|
181
|
+
result += ">>>>>>> SNAPSHOT\n";
|
182
|
+
return result;
|
183
|
+
}
|
184
|
+
// Annotate the CommonJS export names for ESM import in node:
|
185
|
+
0 && (module.exports = {
|
186
|
+
addSuggestedRebaseline,
|
187
|
+
applySuggestedRebaselines,
|
188
|
+
clearSuggestedRebaselines
|
189
|
+
});
|