|
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 testServer_exports = {}; |
|
30
|
__export(testServer_exports, { |
|
31
|
TestServerDispatcher: () => TestServerDispatcher, |
|
32
|
runTestServer: () => runTestServer, |
|
33
|
runUIMode: () => runUIMode |
|
34
|
}); |
|
35
|
module.exports = __toCommonJS(testServer_exports); |
|
36
|
var import_util = __toESM(require("util")); |
|
37
|
var import_server = require("playwright-core/lib/server"); |
|
38
|
var import_utils = require("playwright-core/lib/utils"); |
|
39
|
var import_utilsBundle = require("playwright-core/lib/utilsBundle"); |
|
40
|
var import_configLoader = require("../common/configLoader"); |
|
41
|
var import_list = __toESM(require("../reporters/list")); |
|
42
|
var import_reporters = require("./reporters"); |
|
43
|
var import_sigIntWatcher = require("./sigIntWatcher"); |
|
44
|
var import_testRunner = require("./testRunner"); |
|
45
|
const originalDebugLog = import_utilsBundle.debug.log; |
|
46
|
const originalStdoutWrite = process.stdout.write; |
|
47
|
const originalStderrWrite = process.stderr.write; |
|
48
|
const originalStdinIsTTY = process.stdin.isTTY; |
|
49
|
class TestServer { |
|
50
|
constructor(configLocation, configCLIOverrides) { |
|
51
|
this._configLocation = configLocation; |
|
52
|
this._configCLIOverrides = configCLIOverrides; |
|
53
|
} |
|
54
|
async start(options) { |
|
55
|
this._dispatcher = new TestServerDispatcher(this._configLocation, this._configCLIOverrides); |
|
56
|
return await (0, import_server.startTraceViewerServer)({ ...options, transport: this._dispatcher.transport }); |
|
57
|
} |
|
58
|
async stop() { |
|
59
|
await this._dispatcher?.stop(); |
|
60
|
} |
|
61
|
} |
|
62
|
class TestServerDispatcher { |
|
63
|
constructor(configLocation, configCLIOverrides) { |
|
64
|
this._serializer = require.resolve("./uiModeReporter"); |
|
65
|
this._closeOnDisconnect = false; |
|
66
|
this._testRunner = new import_testRunner.TestRunner(configLocation, configCLIOverrides); |
|
67
|
this.transport = { |
|
68
|
onconnect: () => { |
|
69
|
}, |
|
70
|
dispatch: (method, params) => this[method](params), |
|
71
|
onclose: () => { |
|
72
|
if (this._closeOnDisconnect) |
|
73
|
(0, import_utils.gracefullyProcessExitDoNotHang)(0); |
|
74
|
} |
|
75
|
}; |
|
76
|
this._dispatchEvent = (method, params) => this.transport.sendEvent?.(method, params); |
|
77
|
this._testRunner.on(import_testRunner.TestRunnerEvent.TestFilesChanged, (testFiles) => this._dispatchEvent("testFilesChanged", { testFiles })); |
|
78
|
this._testRunner.on(import_testRunner.TestRunnerEvent.TestPaused, (params) => this._dispatchEvent("testPaused", { errors: params.errors })); |
|
79
|
} |
|
80
|
async _wireReporter(messageSink) { |
|
81
|
return await (0, import_reporters.createReporterForTestServer)(this._serializer, messageSink); |
|
82
|
} |
|
83
|
async _collectingReporter() { |
|
84
|
const report = []; |
|
85
|
return { |
|
86
|
reporter: await (0, import_reporters.createReporterForTestServer)(this._serializer, (e) => report.push(e)), |
|
87
|
report |
|
88
|
}; |
|
89
|
} |
|
90
|
async initialize(params) { |
|
91
|
this._serializer = params.serializer || require.resolve("./uiModeReporter"); |
|
92
|
this._closeOnDisconnect = !!params.closeOnDisconnect; |
|
93
|
await this._testRunner.initialize({ |
|
94
|
...params |
|
95
|
}); |
|
96
|
this._setInterceptStdio(!!params.interceptStdio); |
|
97
|
} |
|
98
|
async ping() { |
|
99
|
} |
|
100
|
async open(params) { |
|
101
|
if ((0, import_utils.isUnderTest)()) |
|
102
|
return; |
|
103
|
(0, import_utilsBundle.open)("vscode://file/" + params.location.file + ":" + params.location.line).catch((e) => console.error(e)); |
|
104
|
} |
|
105
|
async resizeTerminal(params) { |
|
106
|
this._testRunner.resizeTerminal(params); |
|
107
|
} |
|
108
|
async checkBrowsers() { |
|
109
|
return { hasBrowsers: this._testRunner.hasSomeBrowsers() }; |
|
110
|
} |
|
111
|
async installBrowsers() { |
|
112
|
await this._testRunner.installBrowsers(); |
|
113
|
} |
|
114
|
async runGlobalSetup(params) { |
|
115
|
const { reporter, report } = await this._collectingReporter(); |
|
116
|
this._globalSetupReport = report; |
|
117
|
const { status, env } = await this._testRunner.runGlobalSetup([reporter, new import_list.default()]); |
|
118
|
return { report, status, env }; |
|
119
|
} |
|
120
|
async runGlobalTeardown() { |
|
121
|
const { status } = await this._testRunner.runGlobalTeardown(); |
|
122
|
const report = this._globalSetupReport || []; |
|
123
|
this._globalSetupReport = void 0; |
|
124
|
return { status, report }; |
|
125
|
} |
|
126
|
async startDevServer(params) { |
|
127
|
await this.stopDevServer({}); |
|
128
|
const { reporter, report } = await this._collectingReporter(); |
|
129
|
const { status } = await this._testRunner.startDevServer(reporter, "out-of-process"); |
|
130
|
return { report, status }; |
|
131
|
} |
|
132
|
async stopDevServer(params) { |
|
133
|
const { status } = await this._testRunner.stopDevServer(); |
|
134
|
const report = this._devServerReport || []; |
|
135
|
this._devServerReport = void 0; |
|
136
|
return { status, report }; |
|
137
|
} |
|
138
|
async clearCache(params) { |
|
139
|
await this._testRunner.clearCache(); |
|
140
|
} |
|
141
|
async listFiles(params) { |
|
142
|
const { reporter, report } = await this._collectingReporter(); |
|
143
|
const { status } = await this._testRunner.listFiles(reporter, params.projects); |
|
144
|
return { report, status }; |
|
145
|
} |
|
146
|
async listTests(params) { |
|
147
|
const { reporter, report } = await this._collectingReporter(); |
|
148
|
const { status } = await this._testRunner.listTests(reporter, params); |
|
149
|
return { report, status }; |
|
150
|
} |
|
151
|
async runTests(params) { |
|
152
|
const wireReporter = await this._wireReporter((e) => this._dispatchEvent("report", e)); |
|
153
|
const { status } = await this._testRunner.runTests(wireReporter, { |
|
154
|
...params, |
|
155
|
doNotRunDepsOutsideProjectFilter: true, |
|
156
|
pauseAtEnd: params.pauseAtEnd, |
|
157
|
pauseOnError: params.pauseOnError |
|
158
|
}); |
|
159
|
return { status }; |
|
160
|
} |
|
161
|
async watch(params) { |
|
162
|
await this._testRunner.watch(params.fileNames); |
|
163
|
} |
|
164
|
async findRelatedTestFiles(params) { |
|
165
|
return this._testRunner.findRelatedTestFiles(params.files); |
|
166
|
} |
|
167
|
async stopTests() { |
|
168
|
await this._testRunner.stopTests(); |
|
169
|
} |
|
170
|
async stop() { |
|
171
|
this._setInterceptStdio(false); |
|
172
|
await this._testRunner.stop(); |
|
173
|
} |
|
174
|
async closeGracefully() { |
|
175
|
await this._testRunner.closeGracefully(); |
|
176
|
} |
|
177
|
_setInterceptStdio(interceptStdio) { |
|
178
|
if (process.env.PWTEST_DEBUG) |
|
179
|
return; |
|
180
|
if (interceptStdio) { |
|
181
|
if (import_utilsBundle.debug.log === originalDebugLog) { |
|
182
|
import_utilsBundle.debug.log = (...args) => { |
|
183
|
const string = import_util.default.format(...args) + "\n"; |
|
184
|
return originalStderrWrite.apply(process.stderr, [string]); |
|
185
|
}; |
|
186
|
} |
|
187
|
const stdoutWrite = (chunk) => { |
|
188
|
this._dispatchEvent("stdio", chunkToPayload("stdout", chunk)); |
|
189
|
return true; |
|
190
|
}; |
|
191
|
const stderrWrite = (chunk) => { |
|
192
|
this._dispatchEvent("stdio", chunkToPayload("stderr", chunk)); |
|
193
|
return true; |
|
194
|
}; |
|
195
|
process.stdout.write = stdoutWrite; |
|
196
|
process.stderr.write = stderrWrite; |
|
197
|
process.stdin.isTTY = void 0; |
|
198
|
} else { |
|
199
|
import_utilsBundle.debug.log = originalDebugLog; |
|
200
|
process.stdout.write = originalStdoutWrite; |
|
201
|
process.stderr.write = originalStderrWrite; |
|
202
|
process.stdin.isTTY = originalStdinIsTTY; |
|
203
|
} |
|
204
|
} |
|
205
|
} |
|
206
|
async function runUIMode(configFile, configCLIOverrides, options) { |
|
207
|
const configLocation = (0, import_configLoader.resolveConfigLocation)(configFile); |
|
208
|
return await innerRunTestServer(configLocation, configCLIOverrides, options, async (server, cancelPromise) => { |
|
209
|
await (0, import_server.installRootRedirect)(server, void 0, { ...options, webApp: "uiMode.html" }); |
|
210
|
if (options.host !== void 0 || options.port !== void 0) { |
|
211
|
await (0, import_server.openTraceInBrowser)(server.urlPrefix("human-readable")); |
|
212
|
} else { |
|
213
|
const channel = await installedChromiumChannelForUI(configLocation, configCLIOverrides); |
|
214
|
const page = await (0, import_server.openTraceViewerApp)(server.urlPrefix("precise"), "chromium", { |
|
215
|
headless: (0, import_utils.isUnderTest)() && process.env.PWTEST_HEADED_FOR_TEST !== "1", |
|
216
|
persistentContextOptions: { |
|
217
|
handleSIGINT: false, |
|
218
|
channel |
|
219
|
} |
|
220
|
}); |
|
221
|
page.on("close", () => cancelPromise.resolve()); |
|
222
|
} |
|
223
|
}); |
|
224
|
} |
|
225
|
async function installedChromiumChannelForUI(configLocation, configCLIOverrides) { |
|
226
|
const config = await (0, import_configLoader.loadConfig)(configLocation, configCLIOverrides).catch((e) => null); |
|
227
|
if (!config) |
|
228
|
return void 0; |
|
229
|
if (config.projects.some((p) => (!p.project.use.browserName || p.project.use.browserName === "chromium") && !p.project.use.channel)) |
|
230
|
return void 0; |
|
231
|
for (const channel of ["chromium", "chrome", "msedge"]) { |
|
232
|
if (config.projects.some((p) => p.project.use.channel === channel)) |
|
233
|
return channel; |
|
234
|
} |
|
235
|
return void 0; |
|
236
|
} |
|
237
|
async function runTestServer(configFile, configCLIOverrides, options) { |
|
238
|
const configLocation = (0, import_configLoader.resolveConfigLocation)(configFile); |
|
239
|
return await innerRunTestServer(configLocation, configCLIOverrides, options, async (server) => { |
|
240
|
console.log("Listening on " + server.urlPrefix("precise").replace("http:", "ws:") + "/" + server.wsGuid()); |
|
241
|
}); |
|
242
|
} |
|
243
|
async function innerRunTestServer(configLocation, configCLIOverrides, options, openUI) { |
|
244
|
const testServer = new TestServer(configLocation, configCLIOverrides); |
|
245
|
const cancelPromise = new import_utils.ManualPromise(); |
|
246
|
const sigintWatcher = new import_sigIntWatcher.SigIntWatcher(); |
|
247
|
process.stdin.on("close", () => (0, import_utils.gracefullyProcessExitDoNotHang)(0)); |
|
248
|
void sigintWatcher.promise().then(() => cancelPromise.resolve()); |
|
249
|
try { |
|
250
|
const server = await testServer.start(options); |
|
251
|
await openUI(server, cancelPromise); |
|
252
|
await cancelPromise; |
|
253
|
} finally { |
|
254
|
await testServer.stop(); |
|
255
|
sigintWatcher.disarm(); |
|
256
|
} |
|
257
|
return sigintWatcher.hadSignal() ? "interrupted" : "passed"; |
|
258
|
} |
|
259
|
function chunkToPayload(type, chunk) { |
|
260
|
if (chunk instanceof Uint8Array) |
|
261
|
return { type, buffer: chunk.toString("base64") }; |
|
262
|
return { type, text: chunk }; |
|
263
|
} |
|
264
|
// Annotate the CommonJS export names for ESM import in node: |
|
265
|
0 && (module.exports = { |
|
266
|
TestServerDispatcher, |
|
267
|
runTestServer, |
|
268
|
runUIMode |
|
269
|
}); |
|
270
|
|