playwright 1.56.0-alpha-2025-08-29 → 1.56.0-alpha-1756505518000
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/config.js +1 -1
- package/lib/mcp/sdk/bundle.js +3 -0
- package/lib/mcp/test/backend.js +1 -5
- package/lib/mcp/test/context.js +1 -18
- package/lib/mcpBundleImpl.js +14 -71
- package/lib/program.js +2 -0
- package/lib/runner/lastRun.js +16 -6
- package/lib/runner/testRunner.js +4 -48
- package/lib/runner/testServer.js +33 -4
- package/package.json +3 -2
package/lib/program.js
CHANGED
|
@@ -172,6 +172,7 @@ async function runTests(args, opts) {
|
|
|
172
172
|
config.cliProjectFilter = opts.project || void 0;
|
|
173
173
|
config.cliPassWithNoTests = !!opts.passWithNoTests;
|
|
174
174
|
config.cliLastFailed = !!opts.lastFailed;
|
|
175
|
+
config.cliLastRunFile = opts.lastRunFile ? import_path.default.resolve(process.cwd(), opts.lastRunFile) : void 0;
|
|
175
176
|
(0, import_projectUtils.filterProjects)(config.projects, config.cliProjectFilter);
|
|
176
177
|
if (opts.ui || opts.uiHost || opts.uiPort) {
|
|
177
178
|
if (opts.onlyChanged)
|
|
@@ -330,6 +331,7 @@ const testOptions = [
|
|
|
330
331
|
["--headed", { description: `Run tests in headed browsers (default: headless)` }],
|
|
331
332
|
["--ignore-snapshots", { description: `Ignore screenshot and snapshot expectations` }],
|
|
332
333
|
["--last-failed", { description: `Only re-run the failures` }],
|
|
334
|
+
["--last-run-file <file>", { description: `Path to the last-run file (default: "test-results/.last-run.json")` }],
|
|
333
335
|
["--list", { description: `Collect all the tests and report them, but do not run` }],
|
|
334
336
|
["--max-failures <N>", { description: `Stop after the first N failures` }],
|
|
335
337
|
["--no-deps", { description: `Do not run project dependencies` }],
|
package/lib/runner/lastRun.js
CHANGED
|
@@ -37,17 +37,27 @@ var import_projectUtils = require("./projectUtils");
|
|
|
37
37
|
class LastRunReporter {
|
|
38
38
|
constructor(config) {
|
|
39
39
|
this._config = config;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
if (config.cliLastRunFile) {
|
|
41
|
+
this._lastRunFile = config.cliLastRunFile;
|
|
42
|
+
} else {
|
|
43
|
+
const [project] = (0, import_projectUtils.filterProjects)(config.projects, config.cliProjectFilter);
|
|
44
|
+
if (project)
|
|
45
|
+
this._lastRunFile = import_path.default.join(project.project.outputDir, ".last-run.json");
|
|
46
|
+
}
|
|
43
47
|
}
|
|
44
|
-
async
|
|
48
|
+
async applyFilter() {
|
|
45
49
|
if (!this._lastRunFile)
|
|
46
50
|
return;
|
|
47
51
|
try {
|
|
48
52
|
const lastRunInfo = JSON.parse(await import_fs.default.promises.readFile(this._lastRunFile, "utf8"));
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
if (lastRunInfo.filterTests) {
|
|
54
|
+
const filterTestIds = new Set(lastRunInfo.filterTests);
|
|
55
|
+
this._config.preOnlyTestFilters.push((test) => filterTestIds.has(test.id));
|
|
56
|
+
}
|
|
57
|
+
if (this._config.cliLastFailed) {
|
|
58
|
+
const failedTestIds = new Set(lastRunInfo.failedTests ?? []);
|
|
59
|
+
this._config.postShardTestFilters.push((test) => failedTestIds.has(test.id));
|
|
60
|
+
}
|
|
51
61
|
} catch {
|
|
52
62
|
}
|
|
53
63
|
}
|
package/lib/runner/testRunner.js
CHANGED
|
@@ -36,8 +36,6 @@ module.exports = __toCommonJS(testRunner_exports);
|
|
|
36
36
|
var import_events = __toESM(require("events"));
|
|
37
37
|
var import_fs = __toESM(require("fs"));
|
|
38
38
|
var import_path = __toESM(require("path"));
|
|
39
|
-
var import_util = __toESM(require("util"));
|
|
40
|
-
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
|
41
39
|
var import_server = require("playwright-core/lib/server");
|
|
42
40
|
var import_utils = require("playwright-core/lib/utils");
|
|
43
41
|
var import_configLoader = require("../common/configLoader");
|
|
@@ -48,17 +46,13 @@ var import_webServerPlugin = require("../plugins/webServerPlugin");
|
|
|
48
46
|
var import_base = require("../reporters/base");
|
|
49
47
|
var import_internalReporter = require("../reporters/internalReporter");
|
|
50
48
|
var import_compilationCache = require("../transform/compilationCache");
|
|
51
|
-
var
|
|
49
|
+
var import_util = require("../util");
|
|
52
50
|
var import_reporters = require("./reporters");
|
|
53
51
|
var import_tasks = require("./tasks");
|
|
54
52
|
var import_lastRun = require("./lastRun");
|
|
55
53
|
const TestRunnerEvent = {
|
|
56
|
-
TestFilesChanged: "testFilesChanged"
|
|
57
|
-
StdioChunk: "stdioChunk"
|
|
54
|
+
TestFilesChanged: "testFilesChanged"
|
|
58
55
|
};
|
|
59
|
-
const originalDebugLog = import_utilsBundle.debug.log;
|
|
60
|
-
const originalStdoutWrite = process.stdout.write;
|
|
61
|
-
const originalStderrWrite = process.stderr.write;
|
|
62
56
|
class TestRunner extends import_events.default {
|
|
63
57
|
constructor(configLocation, configCLIOverrides) {
|
|
64
58
|
super();
|
|
@@ -79,10 +73,6 @@ class TestRunner extends import_events.default {
|
|
|
79
73
|
async initialize(params) {
|
|
80
74
|
this._watchTestDirs = !!params.watchTestDirs;
|
|
81
75
|
this._populateDependenciesOnList = !!params.populateDependenciesOnList;
|
|
82
|
-
this._setInterceptStdio({
|
|
83
|
-
sendStdioEvents: !!params.sendStdioEvents,
|
|
84
|
-
muteConsole: !!params.muteConsole
|
|
85
|
-
});
|
|
86
76
|
}
|
|
87
77
|
resizeTerminal(params) {
|
|
88
78
|
process.stdout.columns = params.cols;
|
|
@@ -318,7 +308,6 @@ class TestRunner extends import_events.default {
|
|
|
318
308
|
(0, import_utils.gracefullyProcessExitDoNotHang)(0);
|
|
319
309
|
}
|
|
320
310
|
async stop() {
|
|
321
|
-
this._setInterceptStdio({ sendStdioEvents: false, muteConsole: false });
|
|
322
311
|
await this.runGlobalTeardown();
|
|
323
312
|
}
|
|
324
313
|
async _loadConfig(overrides) {
|
|
@@ -333,7 +322,7 @@ class TestRunner extends import_events.default {
|
|
|
333
322
|
}
|
|
334
323
|
return { config };
|
|
335
324
|
} catch (e) {
|
|
336
|
-
return { config: null, error: (0,
|
|
325
|
+
return { config: null, error: (0, import_util.serializeError)(e) };
|
|
337
326
|
}
|
|
338
327
|
}
|
|
339
328
|
async _loadConfigOrReportError(reporter, overrides) {
|
|
@@ -346,38 +335,6 @@ class TestRunner extends import_events.default {
|
|
|
346
335
|
await reporter.onExit();
|
|
347
336
|
return null;
|
|
348
337
|
}
|
|
349
|
-
_setInterceptStdio(options) {
|
|
350
|
-
if (process.env.PWTEST_DEBUG)
|
|
351
|
-
return;
|
|
352
|
-
if (options.sendStdioEvents || options.muteConsole) {
|
|
353
|
-
if (import_utilsBundle.debug.log === originalDebugLog) {
|
|
354
|
-
import_utilsBundle.debug.log = (...args) => {
|
|
355
|
-
const string = import_util.default.format(...args) + "\n";
|
|
356
|
-
return originalStderrWrite.apply(process.stderr, [string]);
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
const stdoutWrite = (chunk) => {
|
|
360
|
-
if (options.sendStdioEvents)
|
|
361
|
-
this.emit(TestRunnerEvent.StdioChunk, chunk, "stdout");
|
|
362
|
-
if (!options.muteConsole)
|
|
363
|
-
originalStdoutWrite.apply(process.stdout, [chunk]);
|
|
364
|
-
return true;
|
|
365
|
-
};
|
|
366
|
-
const stderrWrite = (chunk) => {
|
|
367
|
-
if (options.sendStdioEvents)
|
|
368
|
-
this.emit(TestRunnerEvent.StdioChunk, chunk, "stderr");
|
|
369
|
-
if (!options.muteConsole)
|
|
370
|
-
originalStderrWrite.apply(process.stderr, [chunk]);
|
|
371
|
-
return true;
|
|
372
|
-
};
|
|
373
|
-
process.stdout.write = stdoutWrite;
|
|
374
|
-
process.stderr.write = stderrWrite;
|
|
375
|
-
} else {
|
|
376
|
-
import_utilsBundle.debug.log = originalDebugLog;
|
|
377
|
-
process.stdout.write = originalStdoutWrite;
|
|
378
|
-
process.stderr.write = originalStderrWrite;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
338
|
}
|
|
382
339
|
function printInternalError(e) {
|
|
383
340
|
console.error("Internal error:", e);
|
|
@@ -400,8 +357,7 @@ async function runAllTestsWithConfig(config) {
|
|
|
400
357
|
(0, import_webServerPlugin.webServerPluginsForConfig)(config).forEach((p) => config.plugins.push({ factory: p }));
|
|
401
358
|
const reporters = await (0, import_reporters.createReporters)(config, listOnly ? "list" : "test", false);
|
|
402
359
|
const lastRun = new import_lastRun.LastRunReporter(config);
|
|
403
|
-
|
|
404
|
-
await lastRun.filterLastFailed();
|
|
360
|
+
await lastRun.applyFilter();
|
|
405
361
|
const reporter = new import_internalReporter.InternalReporter([...reporters, lastRun]);
|
|
406
362
|
const tasks = listOnly ? [
|
|
407
363
|
(0, import_tasks.createLoadTask)("in-process", { failOnLoadErrors: true, filterOnly: false }),
|
package/lib/runner/testServer.js
CHANGED
|
@@ -33,6 +33,7 @@ __export(testServer_exports, {
|
|
|
33
33
|
runUIMode: () => runUIMode
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(testServer_exports);
|
|
36
|
+
var import_util = __toESM(require("util"));
|
|
36
37
|
var import_server = require("playwright-core/lib/server");
|
|
37
38
|
var import_utils = require("playwright-core/lib/utils");
|
|
38
39
|
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
|
@@ -41,6 +42,9 @@ var import_list = __toESM(require("../reporters/list"));
|
|
|
41
42
|
var import_reporters = require("./reporters");
|
|
42
43
|
var import_sigIntWatcher = require("./sigIntWatcher");
|
|
43
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;
|
|
44
48
|
class TestServer {
|
|
45
49
|
constructor(configLocation, configCLIOverrides) {
|
|
46
50
|
this._configLocation = configLocation;
|
|
@@ -70,7 +74,6 @@ class TestServerDispatcher {
|
|
|
70
74
|
};
|
|
71
75
|
this._dispatchEvent = (method, params) => this.transport.sendEvent?.(method, params);
|
|
72
76
|
this._testRunner.on(import_testRunner.TestRunnerEvent.TestFilesChanged, (testFiles) => this._dispatchEvent("testFilesChanged", { testFiles }));
|
|
73
|
-
this._testRunner.on(import_testRunner.TestRunnerEvent.StdioChunk, (chunk, stdio) => this._dispatchEvent("stdio", chunkToPayload(stdio, chunk)));
|
|
74
77
|
}
|
|
75
78
|
async _wireReporter(messageSink) {
|
|
76
79
|
return await (0, import_reporters.createReporterForTestServer)(this._serializer, messageSink);
|
|
@@ -86,10 +89,9 @@ class TestServerDispatcher {
|
|
|
86
89
|
this._serializer = params.serializer || require.resolve("./uiModeReporter");
|
|
87
90
|
this._closeOnDisconnect = !!params.closeOnDisconnect;
|
|
88
91
|
await this._testRunner.initialize({
|
|
89
|
-
...params
|
|
90
|
-
sendStdioEvents: !!params.interceptStdio,
|
|
91
|
-
muteConsole: !!params.interceptStdio
|
|
92
|
+
...params
|
|
92
93
|
});
|
|
94
|
+
this._setInterceptStdio(!!params.interceptStdio);
|
|
93
95
|
}
|
|
94
96
|
async ping() {
|
|
95
97
|
}
|
|
@@ -160,11 +162,38 @@ class TestServerDispatcher {
|
|
|
160
162
|
await this._testRunner.stopTests();
|
|
161
163
|
}
|
|
162
164
|
async stop() {
|
|
165
|
+
this._setInterceptStdio(false);
|
|
163
166
|
await this._testRunner.stop();
|
|
164
167
|
}
|
|
165
168
|
async closeGracefully() {
|
|
166
169
|
await this._testRunner.closeGracefully();
|
|
167
170
|
}
|
|
171
|
+
_setInterceptStdio(interceptStdio) {
|
|
172
|
+
if (process.env.PWTEST_DEBUG)
|
|
173
|
+
return;
|
|
174
|
+
if (interceptStdio) {
|
|
175
|
+
if (import_utilsBundle.debug.log === originalDebugLog) {
|
|
176
|
+
import_utilsBundle.debug.log = (...args) => {
|
|
177
|
+
const string = import_util.default.format(...args) + "\n";
|
|
178
|
+
return originalStderrWrite.apply(process.stderr, [string]);
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const stdoutWrite = (chunk) => {
|
|
182
|
+
this._dispatchEvent("stdio", chunkToPayload("stdout", chunk));
|
|
183
|
+
return true;
|
|
184
|
+
};
|
|
185
|
+
const stderrWrite = (chunk) => {
|
|
186
|
+
this._dispatchEvent("stdio", chunkToPayload("stderr", chunk));
|
|
187
|
+
return true;
|
|
188
|
+
};
|
|
189
|
+
process.stdout.write = stdoutWrite;
|
|
190
|
+
process.stderr.write = stderrWrite;
|
|
191
|
+
} else {
|
|
192
|
+
import_utilsBundle.debug.log = originalDebugLog;
|
|
193
|
+
process.stdout.write = originalStdoutWrite;
|
|
194
|
+
process.stderr.write = originalStderrWrite;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
168
197
|
}
|
|
169
198
|
async function runUIMode(configFile, configCLIOverrides, options) {
|
|
170
199
|
const configLocation = (0, import_configLoader.resolveConfigLocation)(configFile);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playwright",
|
|
3
|
-
"version": "1.56.0-alpha-
|
|
3
|
+
"version": "1.56.0-alpha-1756505518000",
|
|
4
4
|
"description": "A high-level API to automate web browsers",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"./package.json": "./package.json",
|
|
22
22
|
"./lib/common/configLoader": "./lib/common/configLoader.js",
|
|
23
23
|
"./lib/fsWatcher": "./lib/fsWatcher.js",
|
|
24
|
+
"./lib/mcpBundleImpl": "./lib/mcpBundleImpl.js",
|
|
24
25
|
"./lib/mcp/sdk/exports": "./lib/mcp/sdk/exports.js",
|
|
25
26
|
"./lib/program": "./lib/program.js",
|
|
26
27
|
"./lib/reporters/base": "./lib/reporters/base.js",
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
},
|
|
61
62
|
"license": "Apache-2.0",
|
|
62
63
|
"dependencies": {
|
|
63
|
-
"playwright-core": "1.56.0-alpha-
|
|
64
|
+
"playwright-core": "1.56.0-alpha-1756505518000"
|
|
64
65
|
},
|
|
65
66
|
"optionalDependencies": {
|
|
66
67
|
"fsevents": "2.3.2"
|