playwright 1.56.0-alpha-2025-09-23 → 1.56.0-alpha-1758747822000

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.
Files changed (37) hide show
  1. package/lib/agents/generateAgents.js +25 -10
  2. package/lib/agents/generator.md +5 -5
  3. package/lib/agents/healer.md +4 -4
  4. package/lib/agents/planner.md +5 -5
  5. package/lib/index.js +3 -50
  6. package/lib/matchers/toBeTruthy.js +0 -2
  7. package/lib/matchers/toEqual.js +0 -2
  8. package/lib/matchers/toMatchText.js +0 -3
  9. package/lib/mcp/browser/browserContextFactory.js +20 -9
  10. package/lib/mcp/browser/browserServerBackend.js +2 -0
  11. package/lib/mcp/browser/config.js +55 -18
  12. package/lib/mcp/browser/context.js +17 -1
  13. package/lib/mcp/browser/response.js +27 -20
  14. package/lib/mcp/browser/sessionLog.js +1 -1
  15. package/lib/mcp/browser/tab.js +6 -32
  16. package/lib/mcp/browser/tools/dialogs.js +6 -1
  17. package/lib/mcp/browser/tools/files.js +6 -1
  18. package/lib/mcp/browser/tools/pdf.js +1 -1
  19. package/lib/mcp/browser/tools/screenshot.js +1 -1
  20. package/lib/mcp/browser/tools/snapshot.js +1 -1
  21. package/lib/mcp/browser/tools/tracing.js +1 -1
  22. package/lib/mcp/browser/tools/utils.js +2 -2
  23. package/lib/mcp/browser/tools.js +5 -0
  24. package/lib/mcp/log.js +2 -2
  25. package/lib/mcp/program.js +1 -1
  26. package/lib/mcp/sdk/http.js +17 -5
  27. package/lib/mcp/sdk/server.js +1 -1
  28. package/lib/mcp/test/browserBackend.js +29 -33
  29. package/lib/program.js +6 -4
  30. package/lib/runner/lastRun.js +6 -16
  31. package/lib/runner/loadUtils.js +35 -2
  32. package/lib/runner/tasks.js +9 -1
  33. package/lib/runner/testRunner.js +2 -1
  34. package/lib/util.js +12 -6
  35. package/lib/worker/testInfo.js +1 -0
  36. package/lib/worker/workerMain.js +4 -1
  37. package/package.json +2 -2
@@ -32,10 +32,13 @@ __export(loadUtils_exports, {
32
32
  createRootSuite: () => createRootSuite,
33
33
  loadFileSuites: () => loadFileSuites,
34
34
  loadGlobalHook: () => loadGlobalHook,
35
- loadReporter: () => loadReporter
35
+ loadReporter: () => loadReporter,
36
+ loadTestList: () => loadTestList
36
37
  });
37
38
  module.exports = __toCommonJS(loadUtils_exports);
38
39
  var import_path = __toESM(require("path"));
40
+ var import_fs = __toESM(require("fs"));
41
+ var import_utils = require("playwright-core/lib/utils");
39
42
  var import_loaderHost = require("./loaderHost");
40
43
  var import_util = require("../util");
41
44
  var import_projectUtils = require("./projectUtils");
@@ -290,11 +293,41 @@ function sourceMapSources(file, cache) {
290
293
  return sources;
291
294
  }
292
295
  }
296
+ async function loadTestList(config, filePath) {
297
+ try {
298
+ const content = await import_fs.default.promises.readFile(filePath, "utf-8");
299
+ const lines = content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
300
+ const descriptions = lines.map((line) => {
301
+ const delimiter = line.includes("\u203A") ? "\u203A" : ">";
302
+ const tokens = line.split(delimiter).map((token) => token.trim());
303
+ let project;
304
+ if (tokens[0].startsWith("[")) {
305
+ if (!tokens[0].endsWith("]"))
306
+ throw new Error(`Malformed test description: ${line}`);
307
+ project = tokens[0].substring(1, tokens[0].length - 1);
308
+ tokens.shift();
309
+ }
310
+ return { project, file: (0, import_utils.toPosixPath)((0, import_util.parseLocationArg)(tokens[0]).file), titlePath: tokens.slice(1) };
311
+ });
312
+ return (test) => descriptions.some((d) => {
313
+ const [projectName, , ...titles] = test.titlePath();
314
+ if (d.project !== void 0 && d.project !== projectName)
315
+ return false;
316
+ const relativeFile = (0, import_utils.toPosixPath)(import_path.default.relative(config.config.rootDir, test.location.file));
317
+ if (relativeFile !== d.file)
318
+ return false;
319
+ return d.titlePath.length === titles.length && d.titlePath.every((_, index) => titles[index] === d.titlePath[index]);
320
+ });
321
+ } catch (e) {
322
+ throw (0, import_util.errorWithFile)(filePath, "Cannot read test list file: " + e.message);
323
+ }
324
+ }
293
325
  // Annotate the CommonJS export names for ESM import in node:
294
326
  0 && (module.exports = {
295
327
  collectProjectsAndTestFiles,
296
328
  createRootSuite,
297
329
  loadFileSuites,
298
330
  loadGlobalHook,
299
- loadReporter
331
+ loadReporter,
332
+ loadTestList
300
333
  });
@@ -249,10 +249,18 @@ function createLoadTask(mode, options) {
249
249
  const changedFiles = await (0, import_vcs.detectChangedTestFiles)(testRun.config.cliOnlyChanged, testRun.config.configDir);
250
250
  testRun.config.preOnlyTestFilters.push((test) => changedFiles.has(test.location.file));
251
251
  }
252
+ if (testRun.config.cliTestList) {
253
+ const testListFilter = await (0, import_loadUtils.loadTestList)(testRun.config, testRun.config.cliTestList);
254
+ testRun.config.preOnlyTestFilters.push(testListFilter);
255
+ }
256
+ if (testRun.config.cliTestListInvert) {
257
+ const testListInvertFilter = await (0, import_loadUtils.loadTestList)(testRun.config, testRun.config.cliTestListInvert);
258
+ testRun.config.preOnlyTestFilters.push((test) => !testListInvertFilter(test));
259
+ }
252
260
  const { rootSuite, topLevelProjects } = await (0, import_loadUtils.createRootSuite)(testRun, options.failOnLoadErrors ? errors : softErrors, !!options.filterOnly);
253
261
  testRun.rootSuite = rootSuite;
254
262
  testRun.failureTracker.onRootSuite(rootSuite, topLevelProjects);
255
- if (options.failOnLoadErrors && !testRun.rootSuite.allTests().length && !testRun.config.cliPassWithNoTests && !testRun.config.config.shard && !testRun.config.cliOnlyChanged) {
263
+ if (options.failOnLoadErrors && !testRun.rootSuite.allTests().length && !testRun.config.cliPassWithNoTests && !testRun.config.config.shard && !testRun.config.cliOnlyChanged && !testRun.config.cliTestList && !testRun.config.cliTestListInvert) {
256
264
  if (testRun.config.cliArgs.length) {
257
265
  throw new Error([
258
266
  `No tests found.`,
@@ -365,7 +365,8 @@ async function runAllTestsWithConfig(config) {
365
365
  (0, import_webServerPlugin.webServerPluginsForConfig)(config).forEach((p) => config.plugins.push({ factory: p }));
366
366
  const reporters = await (0, import_reporters.createReporters)(config, listOnly ? "list" : "test", false);
367
367
  const lastRun = new import_lastRun.LastRunReporter(config);
368
- await lastRun.applyFilter();
368
+ if (config.cliLastFailed)
369
+ await lastRun.filterLastFailed();
369
370
  const reporter = new import_internalReporter.InternalReporter([...reporters, lastRun]);
370
371
  const tasks = listOnly ? [
371
372
  (0, import_tasks.createLoadTask)("in-process", { failOnLoadErrors: true, filterOnly: false }),
package/lib/util.js CHANGED
@@ -48,6 +48,7 @@ __export(util_exports, {
48
48
  getPackageJsonPath: () => getPackageJsonPath,
49
49
  mergeObjects: () => mergeObjects,
50
50
  normalizeAndSaveAttachment: () => normalizeAndSaveAttachment,
51
+ parseLocationArg: () => parseLocationArg,
51
52
  relativeFilePath: () => relativeFilePath,
52
53
  removeDirAndLogToConsole: () => removeDirAndLogToConsole,
53
54
  resolveImportSpecifierAfterMapping: () => resolveImportSpecifierAfterMapping,
@@ -105,14 +106,18 @@ function serializeError(error) {
105
106
  value: import_util.default.inspect(error)
106
107
  };
107
108
  }
109
+ function parseLocationArg(arg) {
110
+ const match = /^(.*?):(\d+):?(\d+)?$/.exec(arg);
111
+ return {
112
+ file: match ? match[1] : arg,
113
+ line: match ? parseInt(match[2], 10) : null,
114
+ column: match?.[3] ? parseInt(match[3], 10) : null
115
+ };
116
+ }
108
117
  function createFileFiltersFromArguments(args) {
109
118
  return args.map((arg) => {
110
- const match = /^(.*?):(\d+):?(\d+)?$/.exec(arg);
111
- return {
112
- re: forceRegExp(match ? match[1] : arg),
113
- line: match ? parseInt(match[2], 10) : null,
114
- column: match?.[3] ? parseInt(match[3], 10) : null
115
- };
119
+ const parsed = parseLocationArg(arg);
120
+ return { re: forceRegExp(parsed.file), line: parsed.line, column: parsed.column };
116
121
  });
117
122
  }
118
123
  function createFileMatcherFromArguments(args) {
@@ -385,6 +390,7 @@ function stripAnsiEscapes(str) {
385
390
  getPackageJsonPath,
386
391
  mergeObjects,
387
392
  normalizeAndSaveAttachment,
393
+ parseLocationArg,
388
394
  relativeFilePath,
389
395
  removeDirAndLogToConsole,
390
396
  resolveImportSpecifierAfterMapping,
@@ -50,6 +50,7 @@ class TestInfoImpl {
50
50
  this._lastStepId = 0;
51
51
  this._steps = [];
52
52
  this._stepMap = /* @__PURE__ */ new Map();
53
+ this._onDidFinishTestFunctions = [];
53
54
  this._hasNonRetriableError = false;
54
55
  this._hasUnhandledError = false;
55
56
  this._allowSkips = false;
@@ -318,7 +318,10 @@ class WorkerMain extends import_process.ProcessRunner {
318
318
  await testInfo._runAsStep({ title: "After Hooks", category: "hook" }, async () => {
319
319
  let firstAfterHooksError;
320
320
  try {
321
- await testInfo._runWithTimeout({ type: "test", slot: afterHooksSlot }, async () => testInfo._onDidFinishTestFunction?.());
321
+ await testInfo._runWithTimeout({ type: "test", slot: afterHooksSlot }, async () => {
322
+ for (const fn of testInfo._onDidFinishTestFunctions)
323
+ await fn();
324
+ });
322
325
  } catch (error) {
323
326
  firstAfterHooksError = firstAfterHooksError ?? error;
324
327
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright",
3
- "version": "1.56.0-alpha-2025-09-23",
3
+ "version": "1.56.0-alpha-1758747822000",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -64,7 +64,7 @@
64
64
  },
65
65
  "license": "Apache-2.0",
66
66
  "dependencies": {
67
- "playwright-core": "1.56.0-alpha-2025-09-23"
67
+ "playwright-core": "1.56.0-alpha-1758747822000"
68
68
  },
69
69
  "optionalDependencies": {
70
70
  "fsevents": "2.3.2"