@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,344 @@
|
|
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 testTracing_exports = {};
|
30
|
+
__export(testTracing_exports, {
|
31
|
+
TestTracing: () => TestTracing,
|
32
|
+
testTraceEntryName: () => testTraceEntryName
|
33
|
+
});
|
34
|
+
module.exports = __toCommonJS(testTracing_exports);
|
35
|
+
var import_fs = __toESM(require("fs"));
|
36
|
+
var import_path = __toESM(require("path"));
|
37
|
+
var import_utils = require("playwright-core/lib/utils");
|
38
|
+
var import_zipBundle = require("playwright-core/lib/zipBundle");
|
39
|
+
var import_util = require("../util");
|
40
|
+
const testTraceEntryName = "test.trace";
|
41
|
+
const version = 8;
|
42
|
+
let traceOrdinal = 0;
|
43
|
+
class TestTracing {
|
44
|
+
constructor(testInfo, artifactsDir) {
|
45
|
+
this._traceEvents = [];
|
46
|
+
this._temporaryTraceFiles = [];
|
47
|
+
this._didFinishTestFunctionAndAfterEachHooks = false;
|
48
|
+
this._testInfo = testInfo;
|
49
|
+
this._artifactsDir = artifactsDir;
|
50
|
+
this._tracesDir = import_path.default.join(this._artifactsDir, "traces");
|
51
|
+
this._contextCreatedEvent = {
|
52
|
+
version,
|
53
|
+
type: "context-options",
|
54
|
+
origin: "testRunner",
|
55
|
+
browserName: "",
|
56
|
+
options: {},
|
57
|
+
platform: process.platform,
|
58
|
+
wallTime: Date.now(),
|
59
|
+
monotonicTime: (0, import_utils.monotonicTime)(),
|
60
|
+
sdkLanguage: "javascript"
|
61
|
+
};
|
62
|
+
this._appendTraceEvent(this._contextCreatedEvent);
|
63
|
+
}
|
64
|
+
_shouldCaptureTrace() {
|
65
|
+
if (this._options?.mode === "on")
|
66
|
+
return true;
|
67
|
+
if (this._options?.mode === "retain-on-failure")
|
68
|
+
return true;
|
69
|
+
if (this._options?.mode === "on-first-retry" && this._testInfo.retry === 1)
|
70
|
+
return true;
|
71
|
+
if (this._options?.mode === "on-all-retries" && this._testInfo.retry > 0)
|
72
|
+
return true;
|
73
|
+
if (this._options?.mode === "retain-on-first-failure" && this._testInfo.retry === 0)
|
74
|
+
return true;
|
75
|
+
return false;
|
76
|
+
}
|
77
|
+
async startIfNeeded(value) {
|
78
|
+
const defaultTraceOptions = { screenshots: true, snapshots: true, sources: true, attachments: true, _live: false, mode: "off" };
|
79
|
+
if (!value) {
|
80
|
+
this._options = defaultTraceOptions;
|
81
|
+
} else if (typeof value === "string") {
|
82
|
+
this._options = { ...defaultTraceOptions, mode: value === "retry-with-trace" ? "on-first-retry" : value };
|
83
|
+
} else {
|
84
|
+
const mode = value.mode || "off";
|
85
|
+
this._options = { ...defaultTraceOptions, ...value, mode: mode === "retry-with-trace" ? "on-first-retry" : mode };
|
86
|
+
}
|
87
|
+
if (!this._shouldCaptureTrace()) {
|
88
|
+
this._options = void 0;
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
if (!this._liveTraceFile && this._options._live) {
|
92
|
+
this._liveTraceFile = { file: import_path.default.join(this._tracesDir, `${this._testInfo.testId}-test.trace`), fs: new import_utils.SerializedFS() };
|
93
|
+
this._liveTraceFile.fs.mkdir(import_path.default.dirname(this._liveTraceFile.file));
|
94
|
+
const data = this._traceEvents.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
95
|
+
this._liveTraceFile.fs.writeFile(this._liveTraceFile.file, data);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
didFinishTestFunctionAndAfterEachHooks() {
|
99
|
+
this._didFinishTestFunctionAndAfterEachHooks = true;
|
100
|
+
}
|
101
|
+
artifactsDir() {
|
102
|
+
return this._artifactsDir;
|
103
|
+
}
|
104
|
+
tracesDir() {
|
105
|
+
return this._tracesDir;
|
106
|
+
}
|
107
|
+
traceTitle() {
|
108
|
+
return [import_path.default.relative(this._testInfo.project.testDir, this._testInfo.file) + ":" + this._testInfo.line, ...this._testInfo.titlePath.slice(1)].join(" \u203A ");
|
109
|
+
}
|
110
|
+
generateNextTraceRecordingName() {
|
111
|
+
const ordinalSuffix = traceOrdinal ? `-recording${traceOrdinal}` : "";
|
112
|
+
++traceOrdinal;
|
113
|
+
const retrySuffix = this._testInfo.retry ? `-retry${this._testInfo.retry}` : "";
|
114
|
+
return `${this._testInfo.testId}${retrySuffix}${ordinalSuffix}`;
|
115
|
+
}
|
116
|
+
_generateNextTraceRecordingPath() {
|
117
|
+
const file = import_path.default.join(this._artifactsDir, (0, import_utils.createGuid)() + ".zip");
|
118
|
+
this._temporaryTraceFiles.push(file);
|
119
|
+
return file;
|
120
|
+
}
|
121
|
+
traceOptions() {
|
122
|
+
return this._options;
|
123
|
+
}
|
124
|
+
maybeGenerateNextTraceRecordingPath() {
|
125
|
+
if (this._didFinishTestFunctionAndAfterEachHooks && this._shouldAbandonTrace())
|
126
|
+
return;
|
127
|
+
return this._generateNextTraceRecordingPath();
|
128
|
+
}
|
129
|
+
_shouldAbandonTrace() {
|
130
|
+
if (!this._options)
|
131
|
+
return true;
|
132
|
+
const testFailed = this._testInfo.status !== this._testInfo.expectedStatus;
|
133
|
+
return !testFailed && (this._options.mode === "retain-on-failure" || this._options.mode === "retain-on-first-failure");
|
134
|
+
}
|
135
|
+
async stopIfNeeded() {
|
136
|
+
if (!this._options)
|
137
|
+
return;
|
138
|
+
const error = await this._liveTraceFile?.fs.syncAndGetError();
|
139
|
+
if (error)
|
140
|
+
throw error;
|
141
|
+
if (this._shouldAbandonTrace()) {
|
142
|
+
for (const file of this._temporaryTraceFiles)
|
143
|
+
await import_fs.default.promises.unlink(file).catch(() => {
|
144
|
+
});
|
145
|
+
return;
|
146
|
+
}
|
147
|
+
const zipFile = new import_zipBundle.yazl.ZipFile();
|
148
|
+
if (!this._options?.attachments) {
|
149
|
+
for (const event of this._traceEvents) {
|
150
|
+
if (event.type === "after")
|
151
|
+
delete event.attachments;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
if (this._options?.sources) {
|
155
|
+
const sourceFiles = /* @__PURE__ */ new Set();
|
156
|
+
for (const event of this._traceEvents) {
|
157
|
+
if (event.type === "before") {
|
158
|
+
for (const frame of event.stack || [])
|
159
|
+
sourceFiles.add(frame.file);
|
160
|
+
}
|
161
|
+
}
|
162
|
+
for (const sourceFile of sourceFiles) {
|
163
|
+
await import_fs.default.promises.readFile(sourceFile, "utf8").then((source) => {
|
164
|
+
zipFile.addBuffer(Buffer.from(source), "resources/src@" + (0, import_utils.calculateSha1)(sourceFile) + ".txt");
|
165
|
+
}).catch(() => {
|
166
|
+
});
|
167
|
+
}
|
168
|
+
}
|
169
|
+
const sha1s = /* @__PURE__ */ new Set();
|
170
|
+
for (const event of this._traceEvents.filter((e) => e.type === "after")) {
|
171
|
+
for (const attachment of event.attachments || []) {
|
172
|
+
let contentPromise;
|
173
|
+
if (attachment.path)
|
174
|
+
contentPromise = import_fs.default.promises.readFile(attachment.path).catch(() => void 0);
|
175
|
+
else if (attachment.base64)
|
176
|
+
contentPromise = Promise.resolve(Buffer.from(attachment.base64, "base64"));
|
177
|
+
const content = await contentPromise;
|
178
|
+
if (content === void 0)
|
179
|
+
continue;
|
180
|
+
const sha1 = (0, import_utils.calculateSha1)(content);
|
181
|
+
attachment.sha1 = sha1;
|
182
|
+
delete attachment.path;
|
183
|
+
delete attachment.base64;
|
184
|
+
if (sha1s.has(sha1))
|
185
|
+
continue;
|
186
|
+
sha1s.add(sha1);
|
187
|
+
zipFile.addBuffer(content, "resources/" + sha1);
|
188
|
+
}
|
189
|
+
}
|
190
|
+
const traceContent = Buffer.from(this._traceEvents.map((e) => JSON.stringify(e)).join("\n"));
|
191
|
+
zipFile.addBuffer(traceContent, testTraceEntryName);
|
192
|
+
await new Promise((f) => {
|
193
|
+
zipFile.end(void 0, () => {
|
194
|
+
zipFile.outputStream.pipe(import_fs.default.createWriteStream(this._generateNextTraceRecordingPath())).on("close", f);
|
195
|
+
});
|
196
|
+
});
|
197
|
+
const tracePath = this._testInfo.outputPath("trace.zip");
|
198
|
+
await mergeTraceFiles(tracePath, this._temporaryTraceFiles);
|
199
|
+
this._testInfo.attachments.push({ name: "trace", path: tracePath, contentType: "application/zip" });
|
200
|
+
}
|
201
|
+
appendForError(error) {
|
202
|
+
const rawStack = error.stack?.split("\n") || [];
|
203
|
+
const stack = rawStack ? (0, import_util.filteredStackTrace)(rawStack) : [];
|
204
|
+
this._appendTraceEvent({
|
205
|
+
type: "error",
|
206
|
+
message: this._formatError(error),
|
207
|
+
stack
|
208
|
+
});
|
209
|
+
}
|
210
|
+
_formatError(error) {
|
211
|
+
const parts = [error.message || String(error.value)];
|
212
|
+
if (error.cause)
|
213
|
+
parts.push("[cause]: " + this._formatError(error.cause));
|
214
|
+
return parts.join("\n");
|
215
|
+
}
|
216
|
+
appendStdioToTrace(type, chunk) {
|
217
|
+
this._appendTraceEvent({
|
218
|
+
type,
|
219
|
+
timestamp: (0, import_utils.monotonicTime)(),
|
220
|
+
text: typeof chunk === "string" ? chunk : void 0,
|
221
|
+
base64: typeof chunk === "string" ? void 0 : chunk.toString("base64")
|
222
|
+
});
|
223
|
+
}
|
224
|
+
appendBeforeActionForStep(options) {
|
225
|
+
this._appendTraceEvent({
|
226
|
+
type: "before",
|
227
|
+
callId: options.stepId,
|
228
|
+
stepId: options.stepId,
|
229
|
+
parentId: options.parentId,
|
230
|
+
startTime: (0, import_utils.monotonicTime)(),
|
231
|
+
class: "Test",
|
232
|
+
method: options.category,
|
233
|
+
title: options.title,
|
234
|
+
params: Object.fromEntries(Object.entries(options.params || {}).map(([name, value]) => [name, generatePreview(value)])),
|
235
|
+
stack: options.stack,
|
236
|
+
group: options.group
|
237
|
+
});
|
238
|
+
}
|
239
|
+
appendAfterActionForStep(callId, error, attachments = [], annotations) {
|
240
|
+
this._appendTraceEvent({
|
241
|
+
type: "after",
|
242
|
+
callId,
|
243
|
+
endTime: (0, import_utils.monotonicTime)(),
|
244
|
+
attachments: serializeAttachments(attachments),
|
245
|
+
annotations,
|
246
|
+
error
|
247
|
+
});
|
248
|
+
}
|
249
|
+
_appendTraceEvent(event) {
|
250
|
+
this._traceEvents.push(event);
|
251
|
+
if (this._liveTraceFile)
|
252
|
+
this._liveTraceFile.fs.appendFile(this._liveTraceFile.file, JSON.stringify(event) + "\n", true);
|
253
|
+
}
|
254
|
+
}
|
255
|
+
function serializeAttachments(attachments) {
|
256
|
+
if (attachments.length === 0)
|
257
|
+
return void 0;
|
258
|
+
return attachments.filter((a) => a.name !== "trace").map((a) => {
|
259
|
+
return {
|
260
|
+
name: a.name,
|
261
|
+
contentType: a.contentType,
|
262
|
+
path: a.path,
|
263
|
+
base64: a.body?.toString("base64")
|
264
|
+
};
|
265
|
+
});
|
266
|
+
}
|
267
|
+
function generatePreview(value, visited = /* @__PURE__ */ new Set()) {
|
268
|
+
if (visited.has(value))
|
269
|
+
return "";
|
270
|
+
visited.add(value);
|
271
|
+
if (typeof value === "string")
|
272
|
+
return value;
|
273
|
+
if (typeof value === "number")
|
274
|
+
return value.toString();
|
275
|
+
if (typeof value === "boolean")
|
276
|
+
return value.toString();
|
277
|
+
if (value === null)
|
278
|
+
return "null";
|
279
|
+
if (value === void 0)
|
280
|
+
return "undefined";
|
281
|
+
if (Array.isArray(value))
|
282
|
+
return "[" + value.map((v) => generatePreview(v, visited)).join(", ") + "]";
|
283
|
+
if (typeof value === "object")
|
284
|
+
return "Object";
|
285
|
+
return String(value);
|
286
|
+
}
|
287
|
+
async function mergeTraceFiles(fileName, temporaryTraceFiles) {
|
288
|
+
temporaryTraceFiles = temporaryTraceFiles.filter((file) => import_fs.default.existsSync(file));
|
289
|
+
if (temporaryTraceFiles.length === 1) {
|
290
|
+
await import_fs.default.promises.rename(temporaryTraceFiles[0], fileName);
|
291
|
+
return;
|
292
|
+
}
|
293
|
+
const mergePromise = new import_utils.ManualPromise();
|
294
|
+
const zipFile = new import_zipBundle.yazl.ZipFile();
|
295
|
+
const entryNames = /* @__PURE__ */ new Set();
|
296
|
+
zipFile.on("error", (error) => mergePromise.reject(error));
|
297
|
+
for (let i = temporaryTraceFiles.length - 1; i >= 0; --i) {
|
298
|
+
const tempFile = temporaryTraceFiles[i];
|
299
|
+
const promise = new import_utils.ManualPromise();
|
300
|
+
import_zipBundle.yauzl.open(tempFile, (err, inZipFile) => {
|
301
|
+
if (err) {
|
302
|
+
promise.reject(err);
|
303
|
+
return;
|
304
|
+
}
|
305
|
+
let pendingEntries = inZipFile.entryCount;
|
306
|
+
inZipFile.on("entry", (entry) => {
|
307
|
+
let entryName = entry.fileName;
|
308
|
+
if (entry.fileName === testTraceEntryName) {
|
309
|
+
} else if (entry.fileName.match(/trace\.[a-z]*$/)) {
|
310
|
+
entryName = i + "-" + entry.fileName;
|
311
|
+
}
|
312
|
+
if (entryNames.has(entryName)) {
|
313
|
+
if (--pendingEntries === 0)
|
314
|
+
promise.resolve();
|
315
|
+
return;
|
316
|
+
}
|
317
|
+
entryNames.add(entryName);
|
318
|
+
inZipFile.openReadStream(entry, (err2, readStream) => {
|
319
|
+
if (err2) {
|
320
|
+
promise.reject(err2);
|
321
|
+
return;
|
322
|
+
}
|
323
|
+
zipFile.addReadStream(readStream, entryName);
|
324
|
+
if (--pendingEntries === 0)
|
325
|
+
promise.resolve();
|
326
|
+
});
|
327
|
+
});
|
328
|
+
});
|
329
|
+
await promise;
|
330
|
+
}
|
331
|
+
zipFile.end(void 0, () => {
|
332
|
+
zipFile.outputStream.pipe(import_fs.default.createWriteStream(fileName)).on("close", () => {
|
333
|
+
void Promise.all(temporaryTraceFiles.map((tempFile) => import_fs.default.promises.unlink(tempFile))).then(() => {
|
334
|
+
mergePromise.resolve();
|
335
|
+
}).catch((error) => mergePromise.reject(error));
|
336
|
+
}).on("error", (error) => mergePromise.reject(error));
|
337
|
+
});
|
338
|
+
await mergePromise;
|
339
|
+
}
|
340
|
+
// Annotate the CommonJS export names for ESM import in node:
|
341
|
+
0 && (module.exports = {
|
342
|
+
TestTracing,
|
343
|
+
testTraceEntryName
|
344
|
+
});
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../src/worker/testTracing.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';\n\nimport { ManualPromise, SerializedFS, calculateSha1, createGuid, monotonicTime } from 'playwright-core/lib/utils';\nimport { yauzl, yazl } from 'playwright-core/lib/zipBundle';\n\nimport { filteredStackTrace } from '../util';\n\nimport type { TestStepCategory, TestInfoImpl } from './testInfo';\nimport type { PlaywrightWorkerOptions, TestInfo, TraceMode } from '../../types/test';\nimport type { TestInfoErrorImpl } from '../common/ipc';\nimport type { SerializedError, StackFrame } from '@protocol/channels';\nimport type * as trace from '@trace/trace';\nimport type EventEmitter from 'events';\n\nexport type Attachment = TestInfo['attachments'][0];\nexport const testTraceEntryName = 'test.trace';\nconst version: trace.VERSION = 8;\nlet traceOrdinal = 0;\n\ntype TraceFixtureValue = PlaywrightWorkerOptions['trace'] | undefined;\ntype TraceOptions = { screenshots: boolean, snapshots: boolean, sources: boolean, attachments: boolean, _live: boolean, mode: TraceMode };\n\nexport class TestTracing {\n private _testInfo: TestInfoImpl;\n private _options: TraceOptions | undefined;\n private _liveTraceFile: { file: string, fs: SerializedFS } | undefined;\n private _traceEvents: trace.TraceEvent[] = [];\n private _temporaryTraceFiles: string[] = [];\n private _artifactsDir: string;\n private _tracesDir: string;\n private _contextCreatedEvent: trace.ContextCreatedTraceEvent;\n private _didFinishTestFunctionAndAfterEachHooks = false;\n\n constructor(testInfo: TestInfoImpl, artifactsDir: string) {\n this._testInfo = testInfo;\n this._artifactsDir = artifactsDir;\n this._tracesDir = path.join(this._artifactsDir, 'traces');\n this._contextCreatedEvent = {\n version,\n type: 'context-options',\n origin: 'testRunner',\n browserName: '',\n options: {},\n platform: process.platform,\n wallTime: Date.now(),\n monotonicTime: monotonicTime(),\n sdkLanguage: 'javascript',\n };\n this._appendTraceEvent(this._contextCreatedEvent);\n }\n\n private _shouldCaptureTrace() {\n if (this._options?.mode === 'on')\n return true;\n\n if (this._options?.mode === 'retain-on-failure')\n return true;\n\n if (this._options?.mode === 'on-first-retry' && this._testInfo.retry === 1)\n return true;\n\n if (this._options?.mode === 'on-all-retries' && this._testInfo.retry > 0)\n return true;\n\n if (this._options?.mode === 'retain-on-first-failure' && this._testInfo.retry === 0)\n return true;\n\n return false;\n }\n\n async startIfNeeded(value: TraceFixtureValue) {\n const defaultTraceOptions: TraceOptions = { screenshots: true, snapshots: true, sources: true, attachments: true, _live: false, mode: 'off' };\n\n if (!value) {\n this._options = defaultTraceOptions;\n } else if (typeof value === 'string') {\n this._options = { ...defaultTraceOptions, mode: value === 'retry-with-trace' ? 'on-first-retry' : value as TraceMode };\n } else {\n const mode = value.mode || 'off';\n this._options = { ...defaultTraceOptions, ...value, mode: (mode as string) === 'retry-with-trace' ? 'on-first-retry' : mode };\n }\n\n if (!this._shouldCaptureTrace()) {\n this._options = undefined;\n return;\n }\n\n if (!this._liveTraceFile && this._options._live) {\n // Note that trace name must start with testId for live tracing to work.\n this._liveTraceFile = { file: path.join(this._tracesDir, `${this._testInfo.testId}-test.trace`), fs: new SerializedFS() };\n this._liveTraceFile.fs.mkdir(path.dirname(this._liveTraceFile.file));\n const data = this._traceEvents.map(e => JSON.stringify(e)).join('\\n') + '\\n';\n this._liveTraceFile.fs.writeFile(this._liveTraceFile.file, data);\n }\n }\n\n didFinishTestFunctionAndAfterEachHooks() {\n this._didFinishTestFunctionAndAfterEachHooks = true;\n }\n\n artifactsDir() {\n return this._artifactsDir;\n }\n\n tracesDir() {\n return this._tracesDir;\n }\n\n traceTitle() {\n return [path.relative(this._testInfo.project.testDir, this._testInfo.file) + ':' + this._testInfo.line, ...this._testInfo.titlePath.slice(1)].join(' \u203A ');\n }\n\n generateNextTraceRecordingName() {\n const ordinalSuffix = traceOrdinal ? `-recording${traceOrdinal}` : '';\n ++traceOrdinal;\n const retrySuffix = this._testInfo.retry ? `-retry${this._testInfo.retry}` : '';\n // Note that trace name must start with testId for live tracing to work.\n return `${this._testInfo.testId}${retrySuffix}${ordinalSuffix}`;\n }\n\n private _generateNextTraceRecordingPath() {\n const file = path.join(this._artifactsDir, createGuid() + '.zip');\n this._temporaryTraceFiles.push(file);\n return file;\n }\n\n traceOptions() {\n return this._options;\n }\n\n maybeGenerateNextTraceRecordingPath() {\n // Forget about traces that should be saved on failure, when no failure happened\n // during the test and beforeEach/afterEach hooks.\n // This avoids downloading traces over the wire when not really needed.\n if (this._didFinishTestFunctionAndAfterEachHooks && this._shouldAbandonTrace())\n return;\n return this._generateNextTraceRecordingPath();\n }\n\n private _shouldAbandonTrace() {\n if (!this._options)\n return true;\n const testFailed = this._testInfo.status !== this._testInfo.expectedStatus;\n return !testFailed && (this._options.mode === 'retain-on-failure' || this._options.mode === 'retain-on-first-failure');\n }\n\n async stopIfNeeded() {\n if (!this._options)\n return;\n\n const error = await this._liveTraceFile?.fs.syncAndGetError();\n if (error)\n throw error;\n\n if (this._shouldAbandonTrace()) {\n for (const file of this._temporaryTraceFiles)\n await fs.promises.unlink(file).catch(() => {});\n return;\n }\n\n const zipFile = new yazl.ZipFile();\n\n if (!this._options?.attachments) {\n for (const event of this._traceEvents) {\n if (event.type === 'after')\n delete event.attachments;\n }\n }\n\n if (this._options?.sources) {\n const sourceFiles = new Set<string>();\n for (const event of this._traceEvents) {\n if (event.type === 'before') {\n for (const frame of event.stack || [])\n sourceFiles.add(frame.file);\n }\n }\n for (const sourceFile of sourceFiles) {\n await fs.promises.readFile(sourceFile, 'utf8').then(source => {\n zipFile.addBuffer(Buffer.from(source), 'resources/src@' + calculateSha1(sourceFile) + '.txt');\n }).catch(() => {});\n }\n }\n\n const sha1s = new Set<string>();\n for (const event of this._traceEvents.filter(e => e.type === 'after') as trace.AfterActionTraceEvent[]) {\n for (const attachment of (event.attachments || [])) {\n let contentPromise: Promise<Buffer | undefined> | undefined;\n if (attachment.path)\n contentPromise = fs.promises.readFile(attachment.path).catch(() => undefined);\n else if (attachment.base64)\n contentPromise = Promise.resolve(Buffer.from(attachment.base64, 'base64'));\n\n const content = await contentPromise;\n if (content === undefined)\n continue;\n\n const sha1 = calculateSha1(content);\n attachment.sha1 = sha1;\n delete attachment.path;\n delete attachment.base64;\n if (sha1s.has(sha1))\n continue;\n sha1s.add(sha1);\n zipFile.addBuffer(content, 'resources/' + sha1);\n }\n }\n\n const traceContent = Buffer.from(this._traceEvents.map(e => JSON.stringify(e)).join('\\n'));\n zipFile.addBuffer(traceContent, testTraceEntryName);\n\n await new Promise(f => {\n zipFile.end(undefined, () => {\n zipFile.outputStream.pipe(fs.createWriteStream(this._generateNextTraceRecordingPath())).on('close', f);\n });\n });\n\n const tracePath = this._testInfo.outputPath('trace.zip');\n await mergeTraceFiles(tracePath, this._temporaryTraceFiles);\n this._testInfo.attachments.push({ name: 'trace', path: tracePath, contentType: 'application/zip' });\n }\n\n appendForError(error: TestInfoErrorImpl) {\n const rawStack = error.stack?.split('\\n') || [];\n const stack = rawStack ? filteredStackTrace(rawStack) : [];\n this._appendTraceEvent({\n type: 'error',\n message: this._formatError(error),\n stack,\n });\n }\n\n _formatError(error: TestInfoErrorImpl) {\n const parts: string[] = [error.message || String(error.value)];\n if (error.cause)\n parts.push('[cause]: ' + this._formatError(error.cause));\n return parts.join('\\n');\n }\n\n appendStdioToTrace(type: 'stdout' | 'stderr', chunk: string | Buffer) {\n this._appendTraceEvent({\n type,\n timestamp: monotonicTime(),\n text: typeof chunk === 'string' ? chunk : undefined,\n base64: typeof chunk === 'string' ? undefined : chunk.toString('base64'),\n });\n }\n\n appendBeforeActionForStep(options: { stepId: string, parentId?: string, title: string, category: TestStepCategory, params?: Record<string, any>, stack: StackFrame[], group?: string }) {\n this._appendTraceEvent({\n type: 'before',\n callId: options.stepId,\n stepId: options.stepId,\n parentId: options.parentId,\n startTime: monotonicTime(),\n class: 'Test',\n method: options.category,\n title: options.title,\n params: Object.fromEntries(Object.entries(options.params || {}).map(([name, value]) => [name, generatePreview(value)])),\n stack: options.stack,\n group: options.group,\n });\n }\n\n appendAfterActionForStep(callId: string, error?: SerializedError['error'], attachments: Attachment[] = [], annotations?: trace.AfterActionTraceEventAnnotation[]) {\n this._appendTraceEvent({\n type: 'after',\n callId,\n endTime: monotonicTime(),\n attachments: serializeAttachments(attachments),\n annotations,\n error,\n });\n }\n\n private _appendTraceEvent(event: trace.TraceEvent) {\n this._traceEvents.push(event);\n if (this._liveTraceFile)\n this._liveTraceFile.fs.appendFile(this._liveTraceFile.file, JSON.stringify(event) + '\\n', true);\n }\n}\n\nfunction serializeAttachments(attachments: Attachment[]): trace.AfterActionTraceEvent['attachments'] {\n if (attachments.length === 0)\n return undefined;\n return attachments.filter(a => a.name !== 'trace').map(a => {\n return {\n name: a.name,\n contentType: a.contentType,\n path: a.path,\n base64: a.body?.toString('base64'),\n };\n });\n}\n\nfunction generatePreview(value: any, visited = new Set<any>()): string {\n if (visited.has(value))\n return '';\n visited.add(value);\n if (typeof value === 'string')\n return value;\n if (typeof value === 'number')\n return value.toString();\n if (typeof value === 'boolean')\n return value.toString();\n if (value === null)\n return 'null';\n if (value === undefined)\n return 'undefined';\n if (Array.isArray(value))\n return '[' + value.map(v => generatePreview(v, visited)).join(', ') + ']';\n if (typeof value === 'object')\n return 'Object';\n return String(value);\n}\n\nasync function mergeTraceFiles(fileName: string, temporaryTraceFiles: string[]) {\n temporaryTraceFiles = temporaryTraceFiles.filter(file => fs.existsSync(file));\n if (temporaryTraceFiles.length === 1) {\n await fs.promises.rename(temporaryTraceFiles[0], fileName);\n return;\n }\n\n const mergePromise = new ManualPromise();\n const zipFile = new yazl.ZipFile();\n const entryNames = new Set<string>();\n (zipFile as any as EventEmitter).on('error', error => mergePromise.reject(error));\n\n for (let i = temporaryTraceFiles.length - 1; i >= 0; --i) {\n const tempFile = temporaryTraceFiles[i];\n const promise = new ManualPromise<void>();\n yauzl.open(tempFile, (err, inZipFile) => {\n if (err) {\n promise.reject(err);\n return;\n }\n let pendingEntries = inZipFile.entryCount;\n inZipFile.on('entry', entry => {\n let entryName = entry.fileName;\n if (entry.fileName === testTraceEntryName) {\n // Keep the name for test traces so that the last test trace\n // that contains most of the information is kept in the trace.\n // Note the reverse order of the iteration (from new traces to old).\n } else if (entry.fileName.match(/trace\\.[a-z]*$/)) {\n entryName = i + '-' + entry.fileName;\n }\n if (entryNames.has(entryName)) {\n if (--pendingEntries === 0)\n promise.resolve();\n return;\n }\n entryNames.add(entryName);\n inZipFile.openReadStream(entry, (err, readStream) => {\n if (err) {\n promise.reject(err);\n return;\n }\n zipFile.addReadStream(readStream!, entryName);\n if (--pendingEntries === 0)\n promise.resolve();\n });\n });\n });\n await promise;\n }\n\n zipFile.end(undefined, () => {\n zipFile.outputStream.pipe(fs.createWriteStream(fileName)).on('close', () => {\n void Promise.all(temporaryTraceFiles.map(tempFile => fs.promises.unlink(tempFile))).then(() => {\n mergePromise.resolve();\n }).catch(error => mergePromise.reject(error));\n }).on('error', error => mergePromise.reject(error));\n });\n await mergePromise;\n}\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["path", "fs", "err"]
|
7
|
+
}
|
@@ -0,0 +1,174 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __defProp = Object.defineProperty;
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
6
|
+
var __export = (target, all) => {
|
7
|
+
for (var name in all)
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
9
|
+
};
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
12
|
+
for (let key of __getOwnPropNames(from))
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
15
|
+
}
|
16
|
+
return to;
|
17
|
+
};
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
19
|
+
var timeoutManager_exports = {};
|
20
|
+
__export(timeoutManager_exports, {
|
21
|
+
TimeoutManager: () => TimeoutManager,
|
22
|
+
TimeoutManagerError: () => TimeoutManagerError,
|
23
|
+
kMaxDeadline: () => kMaxDeadline
|
24
|
+
});
|
25
|
+
module.exports = __toCommonJS(timeoutManager_exports);
|
26
|
+
var import_utils = require("playwright-core/lib/utils");
|
27
|
+
var import_utils2 = require("playwright-core/lib/utils");
|
28
|
+
var import_util = require("../util");
|
29
|
+
const kMaxDeadline = 2147483647;
|
30
|
+
class TimeoutManager {
|
31
|
+
constructor(timeout) {
|
32
|
+
this._ignoreTimeouts = false;
|
33
|
+
this._defaultSlot = { timeout, elapsed: 0 };
|
34
|
+
}
|
35
|
+
setIgnoreTimeouts() {
|
36
|
+
this._ignoreTimeouts = true;
|
37
|
+
if (this._running)
|
38
|
+
this._updateTimeout(this._running);
|
39
|
+
}
|
40
|
+
interrupt() {
|
41
|
+
if (this._running)
|
42
|
+
this._running.timeoutPromise.reject(this._createTimeoutError(this._running));
|
43
|
+
}
|
44
|
+
isTimeExhaustedFor(runnable) {
|
45
|
+
const slot = runnable.fixture?.slot || runnable.slot || this._defaultSlot;
|
46
|
+
return slot.timeout > 0 && slot.elapsed >= slot.timeout - 1;
|
47
|
+
}
|
48
|
+
async withRunnable(runnable, cb) {
|
49
|
+
if (this._running)
|
50
|
+
throw new Error(`Internal error: duplicate runnable`);
|
51
|
+
const running = this._running = {
|
52
|
+
runnable,
|
53
|
+
slot: runnable.fixture?.slot || runnable.slot || this._defaultSlot,
|
54
|
+
start: (0, import_utils.monotonicTime)(),
|
55
|
+
deadline: kMaxDeadline,
|
56
|
+
timer: void 0,
|
57
|
+
timeoutPromise: new import_utils.ManualPromise()
|
58
|
+
};
|
59
|
+
let debugTitle = "";
|
60
|
+
try {
|
61
|
+
if (import_util.debugTest.enabled) {
|
62
|
+
debugTitle = runnable.fixture ? `${runnable.fixture.phase} "${runnable.fixture.title}"` : runnable.type;
|
63
|
+
const location = runnable.location ? ` at "${(0, import_util.formatLocation)(runnable.location)}"` : ``;
|
64
|
+
(0, import_util.debugTest)(`started ${debugTitle}${location}`);
|
65
|
+
}
|
66
|
+
this._updateTimeout(running);
|
67
|
+
return await Promise.race([
|
68
|
+
cb(),
|
69
|
+
running.timeoutPromise
|
70
|
+
]);
|
71
|
+
} finally {
|
72
|
+
if (running.timer)
|
73
|
+
clearTimeout(running.timer);
|
74
|
+
running.timer = void 0;
|
75
|
+
running.slot.elapsed += (0, import_utils.monotonicTime)() - running.start;
|
76
|
+
this._running = void 0;
|
77
|
+
if (import_util.debugTest.enabled)
|
78
|
+
(0, import_util.debugTest)(`finished ${debugTitle}`);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
_updateTimeout(running) {
|
82
|
+
if (running.timer)
|
83
|
+
clearTimeout(running.timer);
|
84
|
+
running.timer = void 0;
|
85
|
+
if (this._ignoreTimeouts || !running.slot.timeout) {
|
86
|
+
running.deadline = kMaxDeadline;
|
87
|
+
return;
|
88
|
+
}
|
89
|
+
running.deadline = running.start + (running.slot.timeout - running.slot.elapsed);
|
90
|
+
const timeout = running.deadline - (0, import_utils.monotonicTime)() + 1;
|
91
|
+
if (timeout <= 0)
|
92
|
+
running.timeoutPromise.reject(this._createTimeoutError(running));
|
93
|
+
else
|
94
|
+
running.timer = setTimeout(() => running.timeoutPromise.reject(this._createTimeoutError(running)), timeout);
|
95
|
+
}
|
96
|
+
defaultSlot() {
|
97
|
+
return this._defaultSlot;
|
98
|
+
}
|
99
|
+
slow() {
|
100
|
+
const slot = this._running ? this._running.slot : this._defaultSlot;
|
101
|
+
slot.timeout = slot.timeout * 3;
|
102
|
+
if (this._running)
|
103
|
+
this._updateTimeout(this._running);
|
104
|
+
}
|
105
|
+
setTimeout(timeout) {
|
106
|
+
const slot = this._running ? this._running.slot : this._defaultSlot;
|
107
|
+
slot.timeout = timeout;
|
108
|
+
if (this._running)
|
109
|
+
this._updateTimeout(this._running);
|
110
|
+
}
|
111
|
+
currentSlotDeadline() {
|
112
|
+
return this._running ? this._running.deadline : kMaxDeadline;
|
113
|
+
}
|
114
|
+
currentSlotType() {
|
115
|
+
return this._running ? this._running.runnable.type : "test";
|
116
|
+
}
|
117
|
+
_createTimeoutError(running) {
|
118
|
+
let message = "";
|
119
|
+
const timeout = running.slot.timeout;
|
120
|
+
const runnable = running.runnable;
|
121
|
+
switch (runnable.type) {
|
122
|
+
case "test": {
|
123
|
+
if (runnable.fixture) {
|
124
|
+
if (runnable.fixture.phase === "setup")
|
125
|
+
message = `Test timeout of ${timeout}ms exceeded while setting up "${runnable.fixture.title}".`;
|
126
|
+
else
|
127
|
+
message = `Tearing down "${runnable.fixture.title}" exceeded the test timeout of ${timeout}ms.`;
|
128
|
+
} else {
|
129
|
+
message = `Test timeout of ${timeout}ms exceeded.`;
|
130
|
+
}
|
131
|
+
break;
|
132
|
+
}
|
133
|
+
case "afterEach":
|
134
|
+
case "beforeEach":
|
135
|
+
message = `Test timeout of ${timeout}ms exceeded while running "${runnable.type}" hook.`;
|
136
|
+
break;
|
137
|
+
case "beforeAll":
|
138
|
+
case "afterAll":
|
139
|
+
message = `"${runnable.type}" hook timeout of ${timeout}ms exceeded.`;
|
140
|
+
break;
|
141
|
+
case "teardown": {
|
142
|
+
if (runnable.fixture)
|
143
|
+
message = `Worker teardown timeout of ${timeout}ms exceeded while ${runnable.fixture.phase === "setup" ? "setting up" : "tearing down"} "${runnable.fixture.title}".`;
|
144
|
+
else
|
145
|
+
message = `Worker teardown timeout of ${timeout}ms exceeded.`;
|
146
|
+
break;
|
147
|
+
}
|
148
|
+
case "skip":
|
149
|
+
case "slow":
|
150
|
+
case "fixme":
|
151
|
+
case "fail":
|
152
|
+
message = `"${runnable.type}" modifier timeout of ${timeout}ms exceeded.`;
|
153
|
+
break;
|
154
|
+
}
|
155
|
+
const fixtureWithSlot = runnable.fixture?.slot ? runnable.fixture : void 0;
|
156
|
+
if (fixtureWithSlot)
|
157
|
+
message = `Fixture "${fixtureWithSlot.title}" timeout of ${timeout}ms exceeded during ${fixtureWithSlot.phase}.`;
|
158
|
+
message = import_utils2.colors.red(message);
|
159
|
+
const location = (fixtureWithSlot || runnable).location;
|
160
|
+
const error = new TimeoutManagerError(message);
|
161
|
+
error.name = "";
|
162
|
+
error.stack = message + (location ? `
|
163
|
+
at ${location.file}:${location.line}:${location.column}` : "");
|
164
|
+
return error;
|
165
|
+
}
|
166
|
+
}
|
167
|
+
class TimeoutManagerError extends Error {
|
168
|
+
}
|
169
|
+
// Annotate the CommonJS export names for ESM import in node:
|
170
|
+
0 && (module.exports = {
|
171
|
+
TimeoutManager,
|
172
|
+
TimeoutManagerError,
|
173
|
+
kMaxDeadline
|
174
|
+
});
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../src/worker/timeoutManager.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 { ManualPromise, monotonicTime } from 'playwright-core/lib/utils';\nimport { colors } from 'playwright-core/lib/utils';\n\nimport { debugTest, formatLocation } from '../util';\n\nimport type { Location } from '../../types/testReporter';\n\nexport type TimeSlot = {\n timeout: number;\n elapsed: number;\n};\n\ntype RunnableType = 'test' | 'beforeAll' | 'afterAll' | 'beforeEach' | 'afterEach' | 'slow' | 'skip' | 'fail' | 'fixme' | 'teardown';\n\nexport type RunnableDescription = {\n type: RunnableType;\n location?: Location;\n slot?: TimeSlot; // Falls back to test slot.\n fixture?: FixtureDescription;\n};\n\nexport type FixtureDescription = {\n title: string;\n phase: 'setup' | 'teardown';\n location?: Location;\n slot?: TimeSlot; // Falls back to the runnable slot.\n};\n\ntype Running = {\n runnable: RunnableDescription;\n slot: TimeSlot;\n start: number;\n deadline: number;\n timer: NodeJS.Timeout | undefined;\n timeoutPromise: ManualPromise<any>;\n};\nexport const kMaxDeadline = 2147483647; // 2^31-1\n\nexport class TimeoutManager {\n private _defaultSlot: TimeSlot;\n private _running?: Running;\n private _ignoreTimeouts = false;\n\n constructor(timeout: number) {\n this._defaultSlot = { timeout, elapsed: 0 };\n }\n\n setIgnoreTimeouts() {\n this._ignoreTimeouts = true;\n if (this._running)\n this._updateTimeout(this._running);\n }\n\n interrupt() {\n if (this._running)\n this._running.timeoutPromise.reject(this._createTimeoutError(this._running));\n }\n\n isTimeExhaustedFor(runnable: RunnableDescription) {\n const slot = runnable.fixture?.slot || runnable.slot || this._defaultSlot;\n // Note: the \"-1\" here matches the +1 in _updateTimeout.\n return slot.timeout > 0 && (slot.elapsed >= slot.timeout - 1);\n }\n\n async withRunnable<T>(runnable: RunnableDescription, cb: () => Promise<T>): Promise<T> {\n if (this._running)\n throw new Error(`Internal error: duplicate runnable`);\n const running = this._running = {\n runnable,\n slot: runnable.fixture?.slot || runnable.slot || this._defaultSlot,\n start: monotonicTime(),\n deadline: kMaxDeadline,\n timer: undefined,\n timeoutPromise: new ManualPromise(),\n };\n let debugTitle = '';\n try {\n if (debugTest.enabled) {\n debugTitle = runnable.fixture ? `${runnable.fixture.phase} \"${runnable.fixture.title}\"` : runnable.type;\n const location = runnable.location ? ` at \"${formatLocation(runnable.location)}\"` : ``;\n debugTest(`started ${debugTitle}${location}`);\n }\n this._updateTimeout(running);\n return await Promise.race([\n cb(),\n running.timeoutPromise,\n ]);\n } finally {\n if (running.timer)\n clearTimeout(running.timer);\n running.timer = undefined;\n running.slot.elapsed += monotonicTime() - running.start;\n this._running = undefined;\n if (debugTest.enabled)\n debugTest(`finished ${debugTitle}`);\n }\n }\n\n private _updateTimeout(running: Running) {\n if (running.timer)\n clearTimeout(running.timer);\n running.timer = undefined;\n if (this._ignoreTimeouts || !running.slot.timeout) {\n running.deadline = kMaxDeadline;\n return;\n }\n running.deadline = running.start + (running.slot.timeout - running.slot.elapsed);\n // Compensate for Node.js troubles with timeouts that can fire too early.\n // We add an extra millisecond which seems to be enough.\n // See https://github.com/nodejs/node/issues/26578.\n const timeout = running.deadline - monotonicTime() + 1;\n if (timeout <= 0)\n running.timeoutPromise.reject(this._createTimeoutError(running));\n else\n running.timer = setTimeout(() => running.timeoutPromise.reject(this._createTimeoutError(running)), timeout);\n }\n\n defaultSlot() {\n return this._defaultSlot;\n }\n\n slow() {\n const slot = this._running ? this._running.slot : this._defaultSlot;\n slot.timeout = slot.timeout * 3;\n if (this._running)\n this._updateTimeout(this._running);\n }\n\n setTimeout(timeout: number) {\n const slot = this._running ? this._running.slot : this._defaultSlot;\n slot.timeout = timeout;\n if (this._running)\n this._updateTimeout(this._running);\n }\n\n currentSlotDeadline() {\n return this._running ? this._running.deadline : kMaxDeadline;\n }\n\n currentSlotType() {\n return this._running ? this._running.runnable.type : 'test';\n }\n\n private _createTimeoutError(running: Running): Error {\n let message = '';\n const timeout = running.slot.timeout;\n const runnable = running.runnable;\n switch (runnable.type) {\n case 'test': {\n if (runnable.fixture) {\n if (runnable.fixture.phase === 'setup')\n message = `Test timeout of ${timeout}ms exceeded while setting up \"${runnable.fixture.title}\".`;\n else\n message = `Tearing down \"${runnable.fixture.title}\" exceeded the test timeout of ${timeout}ms.`;\n } else {\n message = `Test timeout of ${timeout}ms exceeded.`;\n }\n break;\n }\n case 'afterEach':\n case 'beforeEach':\n message = `Test timeout of ${timeout}ms exceeded while running \"${runnable.type}\" hook.`;\n break;\n case 'beforeAll':\n case 'afterAll':\n message = `\"${runnable.type}\" hook timeout of ${timeout}ms exceeded.`;\n break;\n case 'teardown': {\n if (runnable.fixture)\n message = `Worker teardown timeout of ${timeout}ms exceeded while ${runnable.fixture.phase === 'setup' ? 'setting up' : 'tearing down'} \"${runnable.fixture.title}\".`;\n else\n message = `Worker teardown timeout of ${timeout}ms exceeded.`;\n break;\n }\n case 'skip':\n case 'slow':\n case 'fixme':\n case 'fail':\n message = `\"${runnable.type}\" modifier timeout of ${timeout}ms exceeded.`;\n break;\n }\n const fixtureWithSlot = runnable.fixture?.slot ? runnable.fixture : undefined;\n if (fixtureWithSlot)\n message = `Fixture \"${fixtureWithSlot.title}\" timeout of ${timeout}ms exceeded during ${fixtureWithSlot.phase}.`;\n message = colors.red(message);\n const location = (fixtureWithSlot || runnable).location;\n const error = new TimeoutManagerError(message);\n error.name = '';\n // Include location for hooks, modifiers and fixtures to distinguish between them.\n error.stack = message + (location ? `\\n at ${location.file}:${location.line}:${location.column}` : '');\n return error;\n }\n}\n\nexport class TimeoutManagerError extends Error {}\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["import_utils"]
|
7
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __defProp = Object.defineProperty;
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
6
|
+
var __export = (target, all) => {
|
7
|
+
for (var name in all)
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
9
|
+
};
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
12
|
+
for (let key of __getOwnPropNames(from))
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
15
|
+
}
|
16
|
+
return to;
|
17
|
+
};
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
19
|
+
var util_exports = {};
|
20
|
+
__export(util_exports, {
|
21
|
+
testInfoError: () => testInfoError
|
22
|
+
});
|
23
|
+
module.exports = __toCommonJS(util_exports);
|
24
|
+
var import_util = require("../util");
|
25
|
+
function testInfoError(error) {
|
26
|
+
return (0, import_util.serializeError)(error);
|
27
|
+
}
|
28
|
+
// Annotate the CommonJS export names for ESM import in node:
|
29
|
+
0 && (module.exports = {
|
30
|
+
testInfoError
|
31
|
+
});
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../src/worker/util.ts"],
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\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 { serializeError } from '../util';\n\nimport type { TestInfoErrorImpl } from '../common/ipc';\n\nexport function testInfoError(error: Error | any): TestInfoErrorImpl {\n return serializeError(error);\n}\n"],
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,kBAA+B;AAIxB,SAAS,cAAc,OAAuC;AACnE,aAAO,4BAAe,KAAK;AAC7B;",
|
6
|
+
"names": []
|
7
|
+
}
|