@smoothdeploy/playwright 1.62.1 → 1.63.0-beta-1793966341000

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.

Potentially problematic release.


This version of @smoothdeploy/playwright might be problematic. Click here for more details.

@@ -53,9 +53,7 @@ __export(testRunner_exports, {
53
53
  runAllTestsWithConfig: () => runAllTestsWithConfig
54
54
  });
55
55
  var import_events2 = __toESM(require("events"));
56
- var import_fs13 = __toESM(require("fs"));
57
- var import_path17 = __toESM(require("path"));
58
- var import_coreBundle2 = require("playwright-core/lib/coreBundle");
56
+ var import_coreBundle3 = require("playwright-core/lib/coreBundle");
59
57
  var import_common10 = require("../common");
60
58
 
61
59
  // packages/playwright/src/runner/fsWatcher.ts
@@ -81,14 +79,21 @@ var FSWatcher = class {
81
79
  this._throttleTimer = void 0;
82
80
  if (!this._watchedPaths.length)
83
81
  return;
84
- const ignored = [...this._ignoredFolders, "**/node_modules/**"];
82
+ const ignoredPrefixes = this._ignoredFolders.map((folder) => folder.replace(/\\/g, "/") + "/");
83
+ const ignored = (file) => {
84
+ if (file.split("/").includes("node_modules"))
85
+ return true;
86
+ return ignoredPrefixes.some((prefix) => (file + "/").startsWith(prefix));
87
+ };
85
88
  this._fsWatcher = chokidar.watch(watchedPaths, { ignoreInitial: true, ignored }).on("all", async (event, file) => {
89
+ if (event !== "add" && event !== "addDir" && event !== "change" && event !== "unlink" && event !== "unlinkDir")
90
+ return;
86
91
  if (this._throttleTimer)
87
92
  clearTimeout(this._throttleTimer);
88
93
  this._collector.push({ event, file });
89
94
  this._throttleTimer = setTimeout(() => this._reportEventsIfAny(), 250);
90
95
  });
91
- await new Promise((resolve, reject) => this._fsWatcher.once("ready", resolve).once("error", reject));
96
+ await new Promise((resolve, reject) => this._fsWatcher.once("ready", () => resolve()).once("error", reject));
92
97
  }
93
98
  async close() {
94
99
  await this._fsWatcher?.close();
@@ -498,7 +503,9 @@ var TeleTestStep = class {
498
503
  this.steps = [];
499
504
  this._startTime = 0;
500
505
  this.title = payload.title;
506
+ this.subtitle = payload.subtitle;
501
507
  this.category = payload.category;
508
+ this.params = payload.params;
502
509
  this.location = location;
503
510
  this.parent = parentStep;
504
511
  this._startTime = payload.startTime;
@@ -597,7 +604,7 @@ function parseRegexPatterns(patterns) {
597
604
  }
598
605
  function computeTestCaseOutcome(test) {
599
606
  let skipped = 0;
600
- let didNotRun = 0;
607
+ let didNotRun2 = 0;
601
608
  let expected = 0;
602
609
  let interrupted = 0;
603
610
  let unexpected = 0;
@@ -607,7 +614,7 @@ function computeTestCaseOutcome(test) {
607
614
  } else if (result.status === "skipped" && test.expectedStatus === "skipped") {
608
615
  ++skipped;
609
616
  } else if (result.status === "skipped") {
610
- ++didNotRun;
617
+ ++didNotRun2;
611
618
  } else if (result.status === test.expectedStatus) {
612
619
  ++expected;
613
620
  } else {
@@ -759,7 +766,14 @@ async function gitCommitInfo(gitDir) {
759
766
  async function gitDiff(gitDir, ci) {
760
767
  const diffLimit = 1e5;
761
768
  if (ci?.prBaseHash) {
762
- await runGit(["fetch", "origin", ci.prBaseHash, "--depth=1", "--no-auto-maintenance", "--no-auto-gc", "--no-tags", "--no-recurse-submodules"], gitDir);
769
+ const hasBaseCommit = await runGit(["cat-file", "-e", `${ci.prBaseHash}^{commit}`], gitDir) !== void 0;
770
+ if (!hasBaseCommit) {
771
+ const isShallow = await runGit(["rev-parse", "--is-shallow-repository"], gitDir) === "true";
772
+ const fetchArgs = ["fetch", "origin", ci.prBaseHash, "--no-auto-maintenance", "--no-auto-gc", "--no-tags", "--no-recurse-submodules"];
773
+ if (isShallow)
774
+ fetchArgs.push("--depth=1");
775
+ await runGit(fetchArgs, gitDir);
776
+ }
763
777
  const diff3 = await runGit(["diff", ci.prBaseHash, "HEAD"], gitDir);
764
778
  if (diff3)
765
779
  return diff3.substring(0, diffLimit);
@@ -1180,7 +1194,7 @@ var TerminalReporter = class {
1180
1194
  const threshold = this.config.reportSlowTests.threshold;
1181
1195
  return fileDurations.filter(([, duration]) => duration > threshold).slice(0, count);
1182
1196
  }
1183
- generateSummaryMessage({ didNotRun, skipped, expected, interrupted, unexpected, flaky, fatalErrors }) {
1197
+ generateSummaryMessage({ didNotRun: didNotRun2, skipped, expected, interrupted, unexpected, flaky, fatalErrors }) {
1184
1198
  const tokens = [];
1185
1199
  if (unexpected.length) {
1186
1200
  tokens.push(this.screen.colors.red(` ${unexpected.length} failed`));
@@ -1199,8 +1213,8 @@ var TerminalReporter = class {
1199
1213
  }
1200
1214
  if (skipped)
1201
1215
  tokens.push(this.screen.colors.yellow(` ${skipped} skipped`));
1202
- if (didNotRun)
1203
- tokens.push(this.screen.colors.yellow(` ${didNotRun} did not run`));
1216
+ if (didNotRun2)
1217
+ tokens.push(this.screen.colors.yellow(` ${didNotRun2} did not run`));
1204
1218
  if (expected)
1205
1219
  tokens.push(this.screen.colors.green(` ${expected} passed`) + this.screen.colors.dim(` (${msToString(this.result.duration)})`));
1206
1220
  if (fatalErrors.length && expected + unexpected.length + interrupted.length + flaky.length > 0)
@@ -1208,7 +1222,7 @@ var TerminalReporter = class {
1208
1222
  return tokens.join("\n");
1209
1223
  }
1210
1224
  generateSummary() {
1211
- let didNotRun = 0;
1225
+ let didNotRun2 = 0;
1212
1226
  let skipped = 0;
1213
1227
  let expected = 0;
1214
1228
  const interrupted = [];
@@ -1223,7 +1237,7 @@ var TerminalReporter = class {
1223
1237
  interruptedToPrint.push(test);
1224
1238
  interrupted.push(test);
1225
1239
  } else if (!test.results.length || test.expectedStatus !== "skipped") {
1226
- ++didNotRun;
1240
+ ++didNotRun2;
1227
1241
  } else {
1228
1242
  ++skipped;
1229
1243
  }
@@ -1242,7 +1256,7 @@ var TerminalReporter = class {
1242
1256
  });
1243
1257
  const failuresToPrint = [...unexpected, ...flaky, ...interruptedToPrint];
1244
1258
  return {
1245
- didNotRun,
1259
+ didNotRun: didNotRun2,
1246
1260
  skipped,
1247
1261
  expected,
1248
1262
  interrupted,
@@ -1285,7 +1299,7 @@ var TerminalReporter = class {
1285
1299
  return formatTestTitle(this.screen, this.config, test, step, this._options);
1286
1300
  }
1287
1301
  formatTestHeader(test, options = {}) {
1288
- return formatTestHeader(this.screen, this.config, test, { ...options, includeTestId: this._options.includeTestId });
1302
+ return formatTestHeader(this.screen, this.config, test, { ...options, includeTestId: this._options.includeTestId, omitTags: this._options.omitTags });
1289
1303
  }
1290
1304
  formatFailure(test, index) {
1291
1305
  return formatFailure(this.screen, this.config, test, index, this._options);
@@ -1320,7 +1334,7 @@ function formatFailure(screen, config2, test, index, options) {
1320
1334
  if (!errors.length)
1321
1335
  continue;
1322
1336
  if (!printedHeader) {
1323
- const header = formatTestHeader(screen, config2, test, { indent: " ", index, mode: "error", includeTestId: options?.includeTestId });
1337
+ const header = formatTestHeader(screen, config2, test, { indent: " ", index, mode: "error", includeTestId: options?.includeTestId, omitTags: options?.omitTags });
1324
1338
  lines.push(screen.colors.red(header));
1325
1339
  printedHeader = true;
1326
1340
  }
@@ -1433,7 +1447,9 @@ function relativeTestPath(screen, config2, test) {
1433
1447
  return relativeFilePath(screen, config2, test.location.file);
1434
1448
  }
1435
1449
  function stepSuffix(step) {
1436
- const stepTitles = step ? step.titlePath() : [];
1450
+ const stepTitles = [];
1451
+ for (let current = step; current; current = current.parent)
1452
+ stepTitles.unshift(current.subtitle ? `${current.title} ${current.subtitle}` : current.title);
1437
1453
  return stepTitles.map((t2) => t2.split("\n")[0]).map((t2) => " \u203A " + t2).join("");
1438
1454
  }
1439
1455
  function formatTestTitle(screen, config2, test, step, options = {}) {
@@ -1443,7 +1459,7 @@ function formatTestTitle(screen, config2, test, step, options = {}) {
1443
1459
  const projectLabel = options.includeTestId ? `project=` : "";
1444
1460
  const projectTitle = projectName ? `[${projectLabel}${projectName}] \u203A ` : "";
1445
1461
  const testTitle = `${testId}${projectTitle}${location} \u203A ${titles.join(" \u203A ")}`;
1446
- const extraTags = test.tags.filter((t2) => !testTitle.includes(t2) && !config2.tags.includes(t2));
1462
+ const extraTags = options.omitTags ? [] : test.tags.filter((t2) => !testTitle.includes(t2) && !config2.tags.includes(t2));
1447
1463
  return `${testTitle}${stepSuffix(step)}${extraTags.length ? " " + extraTags.join(" ") : ""}`;
1448
1464
  }
1449
1465
  function formatTestHeader(screen, config2, test, options = {}) {
@@ -1859,7 +1875,7 @@ function addLocationAndSnippetToError(config2, error, file) {
1859
1875
  }
1860
1876
 
1861
1877
  // packages/playwright/src/runner/testRunner.ts
1862
- var import_util15 = require("../util");
1878
+ var import_util16 = require("../util");
1863
1879
 
1864
1880
  // packages/playwright/src/runner/reporters.ts
1865
1881
  var reporters_exports = {};
@@ -1867,7 +1883,7 @@ __export(reporters_exports, {
1867
1883
  createErrorCollectingReporter: () => createErrorCollectingReporter,
1868
1884
  createReporters: () => createReporters
1869
1885
  });
1870
- var import_fs8 = __toESM(require("fs"));
1886
+ var import_fs9 = __toESM(require("fs"));
1871
1887
 
1872
1888
  // packages/playwright/src/runner/loadUtils.ts
1873
1889
  var import_path4 = __toESM(require("path"));
@@ -2007,11 +2023,23 @@ var ProcessHost = class extends import_events.EventEmitter {
2007
2023
  return;
2008
2024
  const exitPromise = new Promise((f) => this.once("exit", () => f()));
2009
2025
  const timeout = +(process.env.PWTEST_CHILD_PROCESS_TIMEOUT || 5 * 60 * 1e3);
2010
- const result = await raceAgainstDeadline2(() => exitPromise, monotonicTime4() + timeout);
2011
- if (result.timedOut) {
2012
- this.emit("processError", { message: `Error: ${this._processName} process did not exit within ${timeout}ms after stop, force-killed it` });
2013
- this._forceKill();
2014
- await exitPromise;
2026
+ let lastHeartbeat = monotonicTime4();
2027
+ const onHeartbeat = () => lastHeartbeat = monotonicTime4();
2028
+ this.on("__heartbeat__", onHeartbeat);
2029
+ try {
2030
+ while (true) {
2031
+ const result = await raceAgainstDeadline2(() => exitPromise, lastHeartbeat + timeout);
2032
+ if (!result.timedOut)
2033
+ return;
2034
+ if (monotonicTime4() < lastHeartbeat + timeout)
2035
+ continue;
2036
+ this.emit("processError", { message: `Error: ${this._processName} process did not exit within ${timeout}ms after stop, force-killed it` });
2037
+ this._forceKill();
2038
+ await exitPromise;
2039
+ return;
2040
+ }
2041
+ } finally {
2042
+ this.off("__heartbeat__", onHeartbeat);
2015
2043
  }
2016
2044
  }
2017
2045
  _forceKill() {
@@ -2361,7 +2389,8 @@ function createTestGroups(projectSuite, expectedParallelism) {
2361
2389
  requireFile: test._requireFile,
2362
2390
  repeatEachIndex: test.repeatEachIndex,
2363
2391
  projectId: test._projectId,
2364
- tests: []
2392
+ tests: [],
2393
+ locks: []
2365
2394
  };
2366
2395
  };
2367
2396
  for (const test of projectSuite.allTests()) {
@@ -2421,6 +2450,14 @@ function createTestGroups(projectSuite, expectedParallelism) {
2421
2450
  }
2422
2451
  }
2423
2452
  }
2453
+ for (const group of result) {
2454
+ const locks = /* @__PURE__ */ new Set();
2455
+ for (const test of group.tests) {
2456
+ for (const lock of test._locks)
2457
+ locks.add(lock);
2458
+ }
2459
+ group.locks = [...locks];
2460
+ }
2424
2461
  return result;
2425
2462
  }
2426
2463
  function filterForShard(shard, weights, testGroups) {
@@ -3003,7 +3040,9 @@ var TeleReporterEmitter = class {
3003
3040
  id: step[this._idSymbol],
3004
3041
  parentStepId: step.parent?.[this._idSymbol],
3005
3042
  title: step.title,
3043
+ subtitle: step.subtitle,
3006
3044
  category: step.category,
3045
+ params: step.params,
3007
3046
  startTime: +step.startTime,
3008
3047
  location: this._relativeLocation(step.location)
3009
3048
  };
@@ -3136,9 +3175,10 @@ var BlobReporter = class extends TeleReporterEmitter {
3136
3175
  };
3137
3176
 
3138
3177
  // packages/playwright/src/reporters/dot.ts
3178
+ var { getAsBooleanFromENV } = require("playwright-core/lib/coreBundle").utils;
3139
3179
  var DotReporter = class extends TerminalReporter {
3140
- constructor() {
3141
- super(...arguments);
3180
+ constructor(options) {
3181
+ super({ ...options, omitTags: getAsBooleanFromENV("PLAYWRIGHT_DOT_OMIT_TAGS", options?.omitTags) });
3142
3182
  this._counter = 0;
3143
3183
  }
3144
3184
  onBegin(suite) {
@@ -3228,6 +3268,7 @@ var import_path7 = __toESM(require("path"));
3228
3268
  var import_util7 = require("../util");
3229
3269
  var { noColors: noColors2 } = require("playwright-core/lib/coreBundle").iso;
3230
3270
  var { msToString: msToString2 } = require("playwright-core/lib/coreBundle").iso;
3271
+ var { getAsBooleanFromENV: getAsBooleanFromENV2 } = require("playwright-core/lib/coreBundle").utils;
3231
3272
  var GitHubLogger = class {
3232
3273
  newLine() {
3233
3274
  process.stdout.write("\n");
@@ -3253,7 +3294,7 @@ var GitHubLogger = class {
3253
3294
  };
3254
3295
  var GitHubReporter = class extends TerminalReporter {
3255
3296
  constructor(options = {}) {
3256
- super(options);
3297
+ super({ ...options, omitTags: getAsBooleanFromENV2("PLAYWRIGHT_GITHUB_OMIT_TAGS", options.omitTags) });
3257
3298
  this.githubLogger = new GitHubLogger();
3258
3299
  this._failedTestCount = 0;
3259
3300
  this.screen = { ...this.screen, colors: noColors2 };
@@ -3845,6 +3886,7 @@ var HtmlBuilder = class {
3845
3886
  title = `${title} (skipped${skipped.description ? ": " + skipped.description : ""})`;
3846
3887
  const testStep = {
3847
3888
  title,
3889
+ subtitle: step.subtitle,
3848
3890
  startTime: step.startTime.toISOString(),
3849
3891
  duration,
3850
3892
  steps: dedupeSteps(step.steps).map((s) => this._createTestStep(s, result)),
@@ -3930,7 +3972,7 @@ function dedupeSteps(steps) {
3930
3972
  for (const step of steps) {
3931
3973
  const canDedupe = !step.error && step.duration >= 0 && step.location?.file && !step.steps.length;
3932
3974
  const lastStep = lastResult?.step;
3933
- if (canDedupe && lastResult && lastStep && step.category === lastStep.category && step.title === lastStep.title && step.location?.file === lastStep.location?.file && step.location?.line === lastStep.location?.line && step.location?.column === lastStep.location?.column) {
3975
+ if (canDedupe && lastResult && lastStep && step.category === lastStep.category && step.title === lastStep.title && step.subtitle === lastStep.subtitle && step.location?.file === lastStep.location?.file && step.location?.line === lastStep.location?.line && step.location?.column === lastStep.location?.column) {
3934
3976
  ++lastResult.count;
3935
3977
  lastResult.duration += step.duration;
3936
3978
  continue;
@@ -4181,6 +4223,7 @@ var JSONReporter = class {
4181
4223
  const steps = step.steps.filter((s) => s.category === "test.step");
4182
4224
  return {
4183
4225
  title: step.title,
4226
+ subtitle: step.subtitle,
4184
4227
  duration: step.duration,
4185
4228
  error: step.error,
4186
4229
  steps: steps.length ? steps.map((s) => this._serializeTestStep(s)) : void 0
@@ -4215,7 +4258,7 @@ var json_default = JSONReporter;
4215
4258
  var import_fs7 = __toESM(require("fs"));
4216
4259
  var import_path10 = __toESM(require("path"));
4217
4260
  var import_util9 = require("../util");
4218
- var { getAsBooleanFromENV } = require("playwright-core/lib/coreBundle").utils;
4261
+ var { getAsBooleanFromENV: getAsBooleanFromENV3 } = require("playwright-core/lib/coreBundle").utils;
4219
4262
  var JUnitReporter = class {
4220
4263
  constructor(options) {
4221
4264
  this.totalTests = 0;
@@ -4225,9 +4268,11 @@ var JUnitReporter = class {
4225
4268
  this.stripANSIControlSequences = false;
4226
4269
  this.includeProjectInTestName = false;
4227
4270
  this.includeRetries = false;
4228
- this.stripANSIControlSequences = getAsBooleanFromENV("PLAYWRIGHT_JUNIT_STRIP_ANSI", !!options.stripANSIControlSequences);
4229
- this.includeProjectInTestName = getAsBooleanFromENV("PLAYWRIGHT_JUNIT_INCLUDE_PROJECT_IN_TEST_NAME", !!options.includeProjectInTestName);
4230
- this.includeRetries = getAsBooleanFromENV("PLAYWRIGHT_JUNIT_INCLUDE_RETRIES", !!options.includeRetries);
4271
+ this.omitTags = false;
4272
+ this.stripANSIControlSequences = getAsBooleanFromENV3("PLAYWRIGHT_JUNIT_STRIP_ANSI", !!options.stripANSIControlSequences);
4273
+ this.includeProjectInTestName = getAsBooleanFromENV3("PLAYWRIGHT_JUNIT_INCLUDE_PROJECT_IN_TEST_NAME", !!options.includeProjectInTestName);
4274
+ this.includeRetries = getAsBooleanFromENV3("PLAYWRIGHT_JUNIT_INCLUDE_RETRIES", !!options.includeRetries);
4275
+ this.omitTags = getAsBooleanFromENV3("PLAYWRIGHT_JUNIT_OMIT_TAGS", !!options.omitTags);
4231
4276
  this.configDir = options.configDir;
4232
4277
  this.resolvedOutputFile = resolveOutputFile("JUNIT", options)?.outputFile;
4233
4278
  }
@@ -4380,7 +4425,7 @@ var JUnitReporter = class {
4380
4425
  entry.children.push({
4381
4426
  name: errorInfo.elementName,
4382
4427
  attributes: { message: errorInfo.message, type: errorInfo.type },
4383
- text: (0, import_util9.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test))
4428
+ text: (0, import_util9.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test, void 0, { omitTags: this.omitTags }))
4384
4429
  });
4385
4430
  return errorInfo.elementName;
4386
4431
  }
@@ -4390,7 +4435,7 @@ var JUnitReporter = class {
4390
4435
  message: `${import_path10.default.basename(test.location.file)}:${test.location.line}:${test.location.column} ${test.title}`,
4391
4436
  type: "FAILURE"
4392
4437
  },
4393
- text: (0, import_util9.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test))
4438
+ text: (0, import_util9.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test, void 0, { omitTags: this.omitTags }))
4394
4439
  });
4395
4440
  return "failure";
4396
4441
  }
@@ -4501,9 +4546,10 @@ function escape(text, stripANSIControlSequences, isCharacterData) {
4501
4546
  var junit_default = JUnitReporter;
4502
4547
 
4503
4548
  // packages/playwright/src/reporters/line.ts
4549
+ var { getAsBooleanFromENV: getAsBooleanFromENV4 } = require("playwright-core/lib/coreBundle").utils;
4504
4550
  var LineReporter = class extends TerminalReporter {
4505
- constructor() {
4506
- super(...arguments);
4551
+ constructor(options) {
4552
+ super({ ...options, omitTags: getAsBooleanFromENV4("PLAYWRIGHT_LINE_OMIT_TAGS", options?.omitTags) });
4507
4553
  this._current = 0;
4508
4554
  this._failures = 0;
4509
4555
  this._didBegin = false;
@@ -4612,13 +4658,13 @@ var line_default = LineReporter;
4612
4658
  // packages/playwright/src/reporters/list.ts
4613
4659
  var import_util10 = require("../util");
4614
4660
  var { msToString: msToString3 } = require("playwright-core/lib/coreBundle").iso;
4615
- var { getAsBooleanFromENV: getAsBooleanFromENV2 } = require("playwright-core/lib/coreBundle").utils;
4661
+ var { getAsBooleanFromENV: getAsBooleanFromENV5 } = require("playwright-core/lib/coreBundle").utils;
4616
4662
  var DOES_NOT_SUPPORT_UTF8_IN_TERMINAL = process.platform === "win32" && process.env.TERM_PROGRAM !== "vscode" && !process.env.WT_SESSION;
4617
4663
  var POSITIVE_STATUS_MARK = DOES_NOT_SUPPORT_UTF8_IN_TERMINAL ? "ok" : "\u2713";
4618
4664
  var NEGATIVE_STATUS_MARK = DOES_NOT_SUPPORT_UTF8_IN_TERMINAL ? "x" : "\u2718";
4619
4665
  var ListReporter = class extends TerminalReporter {
4620
4666
  constructor(options) {
4621
- super(options);
4667
+ super({ ...options, omitTags: getAsBooleanFromENV5("PLAYWRIGHT_LIST_OMIT_TAGS", options?.omitTags) });
4622
4668
  this._lastRow = 0;
4623
4669
  this._lastColumn = 0;
4624
4670
  this._testRows = /* @__PURE__ */ new Map();
@@ -4628,8 +4674,8 @@ var ListReporter = class extends TerminalReporter {
4628
4674
  this._needNewLine = false;
4629
4675
  this._failureIndex = 0;
4630
4676
  this._paused = /* @__PURE__ */ new Set();
4631
- this._printSteps = getAsBooleanFromENV2("PLAYWRIGHT_LIST_PRINT_STEPS", options?.printSteps);
4632
- this._printFailuresInline = getAsBooleanFromENV2("PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE", options?.printFailuresInline);
4677
+ this._printSteps = getAsBooleanFromENV5("PLAYWRIGHT_LIST_PRINT_STEPS", options?.printSteps);
4678
+ this._printFailuresInline = getAsBooleanFromENV5("PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE", options?.printFailuresInline);
4633
4679
  }
4634
4680
  onBegin(suite) {
4635
4681
  super.onBegin(suite);
@@ -4888,29 +4934,383 @@ var ListModeReporter = class {
4888
4934
  };
4889
4935
  var listModeReporter_default = ListModeReporter;
4890
4936
 
4937
+ // packages/playwright/src/reporters/perfetto.ts
4938
+ var import_fs8 = __toESM(require("fs"));
4939
+ var import_path12 = __toESM(require("path"));
4940
+ var import_zlib = __toESM(require("zlib"));
4941
+ var import_coreBundle2 = require("playwright-core/lib/coreBundle");
4942
+ var import_util11 = require("../util");
4943
+ var { toPosixPath: toPosixPath4 } = require("playwright-core/lib/coreBundle").utils;
4944
+ var kStatusColors = {
4945
+ passed: "good",
4946
+ failed: "bad",
4947
+ timedOut: "terrible",
4948
+ interrupted: "yellow",
4949
+ skipped: "grey"
4950
+ };
4951
+ var kProcessId = 1;
4952
+ var kRunThreadId = 0;
4953
+ var PerfettoReporter = class {
4954
+ constructor(options) {
4955
+ this._events = [];
4956
+ this._laneEndTime = /* @__PURE__ */ new Map();
4957
+ this._globalErrors = [];
4958
+ this._resolvedOutputFile = resolveOutputFile("PERFETTO", {
4959
+ ...options,
4960
+ default: {
4961
+ fileName: "perfetto.json",
4962
+ outputDir: "test-results"
4963
+ }
4964
+ }).outputFile;
4965
+ }
4966
+ version() {
4967
+ return "v2";
4968
+ }
4969
+ printsToStdio() {
4970
+ return false;
4971
+ }
4972
+ onConfigure(config2) {
4973
+ this._config = config2;
4974
+ }
4975
+ onBegin(suite) {
4976
+ this._suite = suite;
4977
+ }
4978
+ onError(error) {
4979
+ this._globalErrors.push({ error, timestamp: Date.now() });
4980
+ }
4981
+ async onEnd(result) {
4982
+ const entries = [];
4983
+ for (const test of this._suite?.allTests() ?? []) {
4984
+ for (const testResult of test.results)
4985
+ entries.push({ test, result: testResult });
4986
+ }
4987
+ entries.sort((a, b) => a.result.startTime.getTime() - b.result.startTime.getTime());
4988
+ for (const entry of entries)
4989
+ this._appendTestResult(entry.test, entry.result);
4990
+ for (const { error, timestamp } of this._globalErrors) {
4991
+ this._events.push({
4992
+ name: "error",
4993
+ cat: "error",
4994
+ ph: "i",
4995
+ s: "g",
4996
+ ts: timestamp,
4997
+ pid: kProcessId,
4998
+ tid: kRunThreadId,
4999
+ cname: "bad",
5000
+ args: { error: this._formatError(error) }
5001
+ });
5002
+ }
5003
+ await this._writeReport(result);
5004
+ }
5005
+ _appendTestResult(test, result) {
5006
+ const startMs = result.startTime.getTime();
5007
+ let endMs = startMs + Math.max(0, result.duration);
5008
+ for (const step of result.steps)
5009
+ endMs = Math.max(endMs, stepEndTime(step));
5010
+ const lane = this._allocateLane(result.parallelIndex, startMs);
5011
+ this._laneEndTime.set(lane, endMs);
5012
+ const tid = lane + 1;
5013
+ this._events.push({
5014
+ name: test.title,
5015
+ cat: "test",
5016
+ ph: "X",
5017
+ ts: startMs,
5018
+ dur: endMs - startMs,
5019
+ pid: kProcessId,
5020
+ tid,
5021
+ cname: kStatusColors[result.status],
5022
+ args: this._testArgs(test, result)
5023
+ });
5024
+ for (const step of result.steps)
5025
+ this._appendStep(step, tid, startMs, endMs);
5026
+ }
5027
+ _allocateLane(preferredLane, startMs) {
5028
+ const preferred = Math.max(0, preferredLane);
5029
+ if (!(this._laneEndTime.get(preferred) > startMs))
5030
+ return preferred;
5031
+ for (let lane = 0; ; ++lane) {
5032
+ if (!(this._laneEndTime.get(lane) > startMs))
5033
+ return lane;
5034
+ }
5035
+ }
5036
+ _appendStep(step, tid, parentStart, parentEnd) {
5037
+ const stepStart = step.startTime.getTime();
5038
+ const startMs = clamp(stepStart, parentStart, parentEnd);
5039
+ const endMs = clamp(step.duration >= 0 ? stepStart + step.duration : parentEnd, startMs, parentEnd);
5040
+ this._events.push({
5041
+ name: step.subtitle ? `${step.title} ${step.subtitle}` : step.title,
5042
+ cat: step.category,
5043
+ ph: "X",
5044
+ ts: startMs,
5045
+ dur: endMs - startMs,
5046
+ pid: kProcessId,
5047
+ tid,
5048
+ cname: step.error ? "bad" : void 0,
5049
+ args: this._stepArgs(step)
5050
+ });
5051
+ for (const child of step.steps)
5052
+ this._appendStep(child, tid, startMs, endMs);
5053
+ }
5054
+ _testArgs(test, result) {
5055
+ const [, projectName, , ...titles] = test.titlePath();
5056
+ const args = {
5057
+ status: result.status,
5058
+ expectedStatus: test.expectedStatus,
5059
+ testId: test.id,
5060
+ workerIndex: result.workerIndex,
5061
+ parallelIndex: result.parallelIndex,
5062
+ timeout: test.timeout,
5063
+ location: this._formatLocation(test.location)
5064
+ };
5065
+ if (titles.length > 1)
5066
+ args.title = titles.join(" \u203A ");
5067
+ if (projectName)
5068
+ args.project = projectName;
5069
+ if (result.retry)
5070
+ args.retry = result.retry;
5071
+ if (test.tags.length)
5072
+ args.tags = test.tags.join(" ");
5073
+ if (result.annotations.length)
5074
+ args.annotations = result.annotations.map((annotation) => formatAnnotation(annotation));
5075
+ if (result.attachments.length)
5076
+ args.attachments = result.attachments.map((attachment) => this._formatAttachment(attachment));
5077
+ if (result.errors.length)
5078
+ args.errors = result.errors.map((error) => this._formatError(error));
5079
+ const stdout = concatChunks(result.stdout);
5080
+ if (stdout)
5081
+ args.stdout = stdout;
5082
+ const stderr = concatChunks(result.stderr);
5083
+ if (stderr)
5084
+ args.stderr = stderr;
5085
+ return args;
5086
+ }
5087
+ _stepArgs(step) {
5088
+ const args = {};
5089
+ if (step.params)
5090
+ args.params = step.params;
5091
+ if (step.location)
5092
+ args.location = this._formatLocation(step.location);
5093
+ if (step.annotations.length)
5094
+ args.annotations = step.annotations.map((annotation) => formatAnnotation(annotation));
5095
+ if (step.attachments.length)
5096
+ args.attachments = step.attachments.map((attachment) => this._formatAttachment(attachment));
5097
+ if (step.error)
5098
+ args.error = this._formatError(step.error);
5099
+ return Object.keys(args).length ? args : void 0;
5100
+ }
5101
+ _formatAttachment(attachment) {
5102
+ return attachment.path ? this._relativePath(attachment.path) : attachment.name;
5103
+ }
5104
+ _formatLocation(location) {
5105
+ if (!location)
5106
+ return void 0;
5107
+ return `${this._relativePath(location.file)}:${location.line}:${location.column}`;
5108
+ }
5109
+ _formatError(error) {
5110
+ return (0, import_util11.stripAnsiEscapes)(formatError(nonTerminalScreen, error).message);
5111
+ }
5112
+ _relativePath(file) {
5113
+ return toPosixPath4(import_path12.default.relative(this._config.rootDir, file));
5114
+ }
5115
+ async _writeReport(result) {
5116
+ let timeOrigin2 = result.startTime.getTime();
5117
+ for (const event of this._events)
5118
+ timeOrigin2 = Math.min(timeOrigin2, event.ts);
5119
+ const metadataEvents = [
5120
+ { name: "process_name", cat: "__metadata", ph: "M", ts: 0, pid: kProcessId, tid: kRunThreadId, args: { name: "Playwright Test" } },
5121
+ { name: "process_sort_index", cat: "__metadata", ph: "M", ts: 0, pid: kProcessId, tid: kRunThreadId, args: { sort_index: 0 } }
5122
+ ];
5123
+ for (const lane of [...this._laneEndTime.keys()].sort((a, b) => a - b)) {
5124
+ metadataEvents.push({ name: "thread_name", cat: "__metadata", ph: "M", ts: 0, pid: kProcessId, tid: lane + 1, args: { name: `Worker ${lane}` } });
5125
+ metadataEvents.push({ name: "thread_sort_index", cat: "__metadata", ph: "M", ts: 0, pid: kProcessId, tid: lane + 1, args: { sort_index: lane + 1 } });
5126
+ }
5127
+ this._events.sort((a, b) => a.ts - b.ts);
5128
+ for (const event of this._events) {
5129
+ event.ts = Math.round((event.ts - timeOrigin2) * 1e3);
5130
+ if (event.dur !== void 0)
5131
+ event.dur = Math.round(event.dur * 1e3);
5132
+ }
5133
+ const metadata = {
5134
+ "playwright-version": (0, import_coreBundle2.getPlaywrightVersion)(),
5135
+ "start-time": result.startTime.toISOString(),
5136
+ "duration": result.duration,
5137
+ "status": result.status
5138
+ };
5139
+ await import_fs8.default.promises.mkdir(import_path12.default.dirname(this._resolvedOutputFile), { recursive: true });
5140
+ const writer = new ChunkWriter(this._resolvedOutputFile);
5141
+ await writer.write('{"traceEvents":[');
5142
+ let separator2 = "";
5143
+ for (const events of [metadataEvents, this._events]) {
5144
+ for (const event of events) {
5145
+ await writer.write(separator2 + JSON.stringify(event));
5146
+ separator2 = ",";
5147
+ }
5148
+ }
5149
+ await writer.write(`],"displayTimeUnit":"ms","metadata":${JSON.stringify(metadata)}}`);
5150
+ await writer.close();
5151
+ }
5152
+ };
5153
+ var ChunkWriter = class {
5154
+ constructor(file) {
5155
+ const fileStream = import_fs8.default.createWriteStream(file);
5156
+ const gzip = file.endsWith(".gz") ? import_zlib.default.createGzip() : void 0;
5157
+ gzip?.pipe(fileStream);
5158
+ this._stream = gzip ?? fileStream;
5159
+ this._closed = new Promise((resolve) => fileStream.on("close", resolve));
5160
+ for (const stream of /* @__PURE__ */ new Set([this._stream, fileStream]))
5161
+ stream.on("error", (error) => this._error ??= error);
5162
+ }
5163
+ async write(chunk) {
5164
+ if (this._error)
5165
+ throw this._error;
5166
+ if (!this._stream.write(chunk))
5167
+ await new Promise((resolve) => this._stream.once("drain", () => resolve()));
5168
+ }
5169
+ async close() {
5170
+ this._stream.end();
5171
+ await this._closed;
5172
+ if (this._error)
5173
+ throw this._error;
5174
+ }
5175
+ };
5176
+ function stepEndTime(step) {
5177
+ let end = step.startTime.getTime() + Math.max(0, step.duration);
5178
+ for (const child of step.steps)
5179
+ end = Math.max(end, stepEndTime(child));
5180
+ return end;
5181
+ }
5182
+ function formatAnnotation(annotation) {
5183
+ return annotation.description ? `${annotation.type}: ${annotation.description}` : annotation.type;
5184
+ }
5185
+ function clamp(value, min, max) {
5186
+ return Math.min(Math.max(value, min), max);
5187
+ }
5188
+ function concatChunks(chunks) {
5189
+ return chunks.map((chunk) => typeof chunk === "string" ? chunk : chunk.toString("utf8")).join("");
5190
+ }
5191
+ var perfetto_default = PerfettoReporter;
5192
+
4891
5193
  // packages/playwright/src/reporters/smoothdeploy.ts
4892
- var fs9 = __toESM(require("fs"));
4893
- var path12 = __toESM(require("path"));
5194
+ var fs10 = __toESM(require("fs"));
5195
+ var path13 = __toESM(require("path"));
5196
+
5197
+ // packages/playwright/src/reporters/smoothdeployMatch.ts
5198
+ var ACTION_API = {
5199
+ navigate: ["Frame.goto"],
5200
+ click: ["Frame.click", "Frame.dblclick", "Frame.dispatchEvent"],
5201
+ fill: ["Frame.fill"],
5202
+ press: ["Frame.press"],
5203
+ hover: ["Frame.hover"],
5204
+ check: ["Frame.check"],
5205
+ uncheck: ["Frame.uncheck"],
5206
+ select: ["Frame.selectOption"],
5207
+ setInputFiles: ["Frame.setInputFiles", "ElementHandle.setInputFiles"],
5208
+ openPage: ["BrowserContext.newPage"],
5209
+ closePage: ["Page.close"],
5210
+ assertVisible: ["toBeVisible"],
5211
+ assertText: ["toContainText", "toHaveText"],
5212
+ assertValue: ["toHaveValue", "toBeEmpty"],
5213
+ assertChecked: ["toBeChecked", "not.toBeChecked"],
5214
+ assertSnapshot: ["toHaveScreenshot", "toMatchAriaSnapshot"]
5215
+ };
5216
+ var FILLER_API_NEVER_SKIPS_AHEAD = /* @__PURE__ */ new Set(["Frame.dispatchEvent"]);
5217
+ function stepApi(step) {
5218
+ if (step.category === "pw:api")
5219
+ return step.channelMethod ?? null;
5220
+ return normalizeApiName(step.apiName);
5221
+ }
5222
+ function shortApi(step) {
5223
+ const api = stepApi(step);
5224
+ if (!api)
5225
+ return null;
5226
+ const idx = api.lastIndexOf(".");
5227
+ return step.category === "pw:api" && idx >= 0 ? api.slice(idx + 1) : api;
5228
+ }
5229
+ function normalizeApiName(apiName) {
5230
+ if (!apiName)
5231
+ return null;
5232
+ if (apiName.startsWith("expect")) {
5233
+ if (apiName.includes(".poll") || apiName.includes(".soft"))
5234
+ return null;
5235
+ const matcher = apiName.slice("expect".length).replace(/^\./, "");
5236
+ return matcher || null;
5237
+ }
5238
+ const idx = apiName.lastIndexOf(".");
5239
+ return idx >= 0 ? apiName.slice(idx + 1) : apiName;
5240
+ }
5241
+ function apiMatches(step, expected) {
5242
+ const api = stepApi(step);
5243
+ if (!api)
5244
+ return false;
5245
+ const allowed = ACTION_API[expected.action];
5246
+ return !!allowed && allowed.includes(api);
5247
+ }
5248
+ function groupMatches(step, expected) {
5249
+ if (expected.title !== void 0)
5250
+ return step.title === expected.title;
5251
+ return expected.action === "group";
5252
+ }
5253
+ function stepMatches(step, expected) {
5254
+ if (step.category === "test.step")
5255
+ return groupMatches(step, expected);
5256
+ if (step.category === "pw:api" || step.category === "expect")
5257
+ return apiMatches(step, expected);
5258
+ return false;
5259
+ }
5260
+ function matchStep(step, siblings, cursor) {
5261
+ if (cursor < siblings.length && stepMatches(step, siblings[cursor]))
5262
+ return cursor;
5263
+ const api = stepApi(step);
5264
+ const canLookAhead = step.category === "test.step" ? siblings.some((s) => s.title !== void 0) : !!api && !FILLER_API_NEVER_SKIPS_AHEAD.has(api);
5265
+ if (!canLookAhead)
5266
+ return -1;
5267
+ for (let j = cursor + 1; j < siblings.length; j++) {
5268
+ if (stepMatches(step, siblings[j]))
5269
+ return j;
5270
+ }
5271
+ return -1;
5272
+ }
5273
+ var INTERNAL_STEP_TITLES = /* @__PURE__ */ new Set([
5274
+ "Before Hooks",
5275
+ "After Hooks",
5276
+ "Worker Cleanup",
5277
+ "Launch browser",
5278
+ "Launch persistent context",
5279
+ "Connect over CDP",
5280
+ "Close browser",
5281
+ "Create context",
5282
+ "Close context",
5283
+ "Create page",
5284
+ "Close page",
5285
+ "Create CDP session"
5286
+ ]);
5287
+ function isToPassWrapper(step) {
5288
+ return normalizeApiName(step.apiName) === "toPass";
5289
+ }
5290
+ function isUserStep(step) {
5291
+ if (step.category === "hook" || step.category === "fixture" || step.category === "test.attach")
5292
+ return false;
5293
+ if (step.title.startsWith('Fixture "'))
5294
+ return false;
5295
+ return !INTERNAL_STEP_TITLES.has(step.title);
5296
+ }
5297
+
5298
+ // packages/playwright/src/reporters/smoothdeploy.ts
5299
+ var NO_SCREENSHOT_PREFIXES = ["Navigate", "Go back", "Go forward", "Reload", "Screenshot", "Wait for", "Pause", "Evaluate"];
5300
+ var safeId = (id) => id.replace(/[^a-zA-Z0-9_-]/g, "-");
4894
5301
  var SmoothDeployReporter = class {
4895
5302
  constructor() {
4896
5303
  this._configDir = "";
4897
5304
  this._manifest = null;
4898
- // Resolved manifest test + paramIndex for each active pw test
4899
5305
  this._resolvedTests = /* @__PURE__ */ new Map();
4900
- // Map pw TestStep → matched manifest step
4901
- this._stepToManifest = /* @__PURE__ */ new WeakMap();
4902
- // Child counter per parent (TestStep for nested, test.id string for root-level)
4903
- this._childCounters = /* @__PURE__ */ new Map();
4904
- // Accumulate nested step data per test for output manifest
5306
+ this._matched = /* @__PURE__ */ new WeakMap();
5307
+ this._opaqueFiller = /* @__PURE__ */ new WeakSet();
5308
+ this._retries = /* @__PURE__ */ new WeakMap();
5309
+ this._rootCursors = /* @__PURE__ */ new Map();
4905
5310
  this._testSteps = /* @__PURE__ */ new Map();
4906
- // Track parent step → output StepData for nesting output
4907
- this._stepToOutput = /* @__PURE__ */ new WeakMap();
4908
- // ID remap: pw IDs → manifest IDs (sanitized). Built during execution, applied in onEnd.
4909
5311
  this._testIdMap = /* @__PURE__ */ new Map();
4910
- // safePwTestId → safeManifestTestId
4911
5312
  this._stepIdMap = /* @__PURE__ */ new Map();
4912
5313
  }
4913
- // safePwStepId → safeManifestStepId
4914
5314
  version() {
4915
5315
  return "v2";
4916
5316
  }
@@ -4918,55 +5318,47 @@ var SmoothDeployReporter = class {
4918
5318
  return false;
4919
5319
  }
4920
5320
  onConfigure(config2) {
4921
- this._configDir = config2.configFile ? path12.dirname(config2.configFile) : config2.rootDir;
4922
- this._loadManifest();
4923
- }
4924
- _loadManifest() {
4925
- const manifestPath = path12.join(this._configDir, ".smoothdeploy-manifest.json");
4926
- if (!fs9.existsSync(manifestPath))
4927
- throw new Error(`SmoothDeploy reporter requires .smoothdeploy-manifest.json in ${this._configDir}`);
4928
- const raw = fs9.readFileSync(manifestPath, "utf-8");
4929
- this._manifest = JSON.parse(raw);
4930
- }
4931
- _emit(event) {
4932
- process.stdout.write(`[SMOOTHDEPLOY_EVENT]${JSON.stringify(event)}
5321
+ this._configDir = config2.configFile ? path13.dirname(config2.configFile) : config2.rootDir;
5322
+ const manifestPath = path13.join(this._configDir, ".smoothdeploy-manifest.json");
5323
+ if (fs10.existsSync(manifestPath))
5324
+ this._manifest = JSON.parse(fs10.readFileSync(manifestPath, "utf-8"));
5325
+ }
5326
+ _emit(event, step) {
5327
+ const retry = step && this._nearestRetry(step);
5328
+ if (retry)
5329
+ retry.events.push(event);
5330
+ else
5331
+ process.stdout.write(`[SMOOTHDEPLOY_EVENT]${JSON.stringify(event)}
4933
5332
  `);
4934
5333
  }
4935
- _isUserStep(step) {
4936
- const title = step.title;
4937
- if (title === "Before Hooks" || title === "After Hooks" || title === "Worker Cleanup")
4938
- return false;
4939
- if (title.startsWith('Fixture "'))
4940
- return false;
4941
- const internalSteps = [
4942
- "Launch browser",
4943
- "Launch persistent context",
4944
- "Connect over CDP",
4945
- "Close browser",
4946
- "Create context",
4947
- "Close context",
4948
- "Create page",
4949
- "Close page",
4950
- "Create CDP session"
4951
- ];
4952
- if (internalSteps.includes(title))
4953
- return false;
4954
- return true;
5334
+ _nearestRetry(step) {
5335
+ for (let p = step.parent; p; p = p.parent) {
5336
+ const retry = this._retries.get(p);
5337
+ if (retry)
5338
+ return retry;
5339
+ }
5340
+ return void 0;
4955
5341
  }
4956
- // Resolve a pw TestCase to its manifest test entry + param index.
4957
- // For parameterized tests: manifest title "Foo" with params=3 matches pw titles "Foo0", "Foo1", "Foo2".
4958
- // For non-parameterized tests: exact match, paramIndex=0.
4959
5342
  _resolveManifestTest(test) {
5343
+ const projectName = test.parent.project()?.name ?? "";
5344
+ const manifestTest = this._findManifestTest(test);
5345
+ if (!manifestTest)
5346
+ return { manifestTest: { id: test.id, title: test.title, steps: [] }, projectName, passthrough: true };
5347
+ const single = manifestTest.steps.length === 1 ? manifestTest.steps[0] : void 0;
5348
+ if (single && single.action === "script")
5349
+ return { manifestTest, projectName, passthrough: true, passthroughRootId: single.id };
5350
+ return { manifestTest, projectName, passthrough: false };
5351
+ }
5352
+ _findManifestTest(test) {
4960
5353
  if (!this._manifest)
4961
5354
  return null;
4962
5355
  const titlePath = test.titlePath();
4963
- const relFile = path12.relative(this._configDir, test.location.file);
5356
+ const relFile = path13.relative(this._configDir, test.location.file);
4964
5357
  const fileManifest = this._manifest.files[relFile];
4965
5358
  if (!fileManifest)
4966
5359
  return null;
4967
5360
  const fileIdx = titlePath.indexOf(relFile);
4968
5361
  const describeTitles = fileIdx >= 0 ? titlePath.slice(fileIdx + 1, -1) : [];
4969
- const testTitle = test.title;
4970
5362
  let currentSuites = fileManifest.suites;
4971
5363
  let currentTests = fileManifest.tests;
4972
5364
  for (const desc of describeTitles) {
@@ -4976,75 +5368,131 @@ var SmoothDeployReporter = class {
4976
5368
  currentSuites = suite.suites;
4977
5369
  currentTests = suite.tests;
4978
5370
  }
4979
- const exactMatch = currentTests.find((t2) => t2.title === testTitle);
4980
- if (exactMatch)
4981
- return { manifestTest: exactMatch, paramIndex: 0 };
4982
- for (const mt of currentTests) {
4983
- if (!mt.params || mt.params < 1)
4984
- continue;
4985
- if (!testTitle.startsWith(mt.title))
4986
- continue;
4987
- const suffix = testTitle.slice(mt.title.length);
4988
- const idx = parseInt(suffix, 10);
4989
- if (String(idx) === suffix && idx >= 0 && idx < mt.params)
4990
- return { manifestTest: mt, paramIndex: idx };
4991
- }
4992
- return null;
5371
+ return currentTests.find((t2) => t2.title === test.title) ?? null;
4993
5372
  }
4994
5373
  onTestBegin(test, result) {
4995
5374
  const resolved = this._resolveManifestTest(test);
4996
- if (!resolved)
4997
- return;
4998
5375
  this._resolvedTests.set(test.id, resolved);
4999
- const safePw = test.id.replace(/[^a-zA-Z0-9_-]/g, "-");
5000
- const safeManifest = resolved.manifestTest.id.replace(/[^a-zA-Z0-9_-]/g, "-");
5001
- this._testIdMap.set(safePw, safeManifest);
5002
- this._childCounters.set(test.id, 0);
5376
+ this._testIdMap.set(safeId(test.id), safeId(resolved.manifestTest.id));
5377
+ this._rootCursors.set(test.id, 0);
5003
5378
  this._testSteps.set(test.id, []);
5004
5379
  this._emit({
5005
5380
  event: "testBegin",
5006
5381
  testId: resolved.manifestTest.id,
5007
- paramIndex: resolved.paramIndex,
5382
+ projectName: resolved.projectName,
5008
5383
  testTitle: test.title,
5009
5384
  timestamp: Date.now()
5010
5385
  });
5386
+ if (resolved.passthroughRootId) {
5387
+ this._emit({
5388
+ event: "stepBegin",
5389
+ testId: resolved.manifestTest.id,
5390
+ projectName: resolved.projectName,
5391
+ id: resolved.passthroughRootId,
5392
+ action: "script",
5393
+ title: test.title,
5394
+ category: "test.step",
5395
+ timestamp: Date.now()
5396
+ });
5397
+ }
5011
5398
  }
5012
5399
  onTestEnd(test, result) {
5013
5400
  const resolved = this._resolvedTests.get(test.id);
5014
5401
  if (!resolved)
5015
5402
  return;
5403
+ if (resolved.passthroughRootId) {
5404
+ this._emit({
5405
+ event: "stepEnd",
5406
+ testId: resolved.manifestTest.id,
5407
+ projectName: resolved.projectName,
5408
+ id: resolved.passthroughRootId,
5409
+ action: "script",
5410
+ title: test.title,
5411
+ duration: result.duration,
5412
+ error: result.error ? { message: result.error.message } : null,
5413
+ timestamp: Date.now()
5414
+ });
5415
+ }
5016
5416
  this._emit({
5017
5417
  event: "testEnd",
5018
5418
  testId: resolved.manifestTest.id,
5019
- paramIndex: resolved.paramIndex,
5419
+ projectName: resolved.projectName,
5020
5420
  testTitle: test.title,
5021
5421
  status: result.status,
5022
5422
  duration: result.duration,
5023
5423
  timestamp: Date.now()
5024
5424
  });
5025
- this._childCounters.delete(test.id);
5425
+ this._rootCursors.delete(test.id);
5426
+ }
5427
+ _nearestMatchedAncestor(step) {
5428
+ for (let p = step.parent; p; p = p.parent) {
5429
+ const matched = this._matched.get(p);
5430
+ if (matched)
5431
+ return { matched, blocked: false };
5432
+ if (this._opaqueFiller.has(p))
5433
+ return { blocked: true };
5434
+ }
5435
+ return { blocked: false };
5436
+ }
5437
+ _resolveStep(test, resolved, step, parent) {
5438
+ const stepLike = { title: step.title, category: step.category, apiName: step._apiName, channelMethod: step._channelMethod };
5439
+ if (resolved.passthrough) {
5440
+ const index2 = parent ? parent.cursor : this._rootCursors.get(test.id) ?? 0;
5441
+ const prefix = parent ? `${parent.manifest.id}:` : resolved.passthroughRootId ? `${resolved.passthroughRootId}:` : "";
5442
+ if (parent)
5443
+ parent.cursor = index2 + 1;
5444
+ else
5445
+ this._rootCursors.set(test.id, index2 + 1);
5446
+ const action = step.category === "test.step" ? "group" : shortApi(stepLike) ?? step.category;
5447
+ return { id: `${prefix}${index2}`, action, title: step.title, children: [] };
5448
+ }
5449
+ if (parent && parent.manifest.children.length === 0)
5450
+ return null;
5451
+ const siblings = parent ? parent.manifest.children : resolved.manifestTest.steps;
5452
+ const cursor = parent ? parent.cursor : this._rootCursors.get(test.id) ?? 0;
5453
+ let index = matchStep(stepLike, siblings, cursor);
5454
+ const retry = this._nearestRetry(step);
5455
+ if (index < 0 && retry && retry.parent === parent && cursor > retry.startCursor) {
5456
+ index = matchStep(stepLike, siblings.slice(0, cursor), retry.startCursor);
5457
+ if (index >= 0)
5458
+ this._discardAttempt(test, retry);
5459
+ }
5460
+ if (index < 0)
5461
+ return null;
5462
+ if (parent)
5463
+ parent.cursor = index + 1;
5464
+ else
5465
+ this._rootCursors.set(test.id, index + 1);
5466
+ return siblings[index];
5467
+ }
5468
+ _discardAttempt(test, retry) {
5469
+ const list = retry.parent ? retry.parent.output.children : this._testSteps.get(test.id);
5470
+ for (const output of retry.outputs) {
5471
+ const i = list ? list.indexOf(output) : -1;
5472
+ if (i >= 0)
5473
+ list.splice(i, 1);
5474
+ }
5475
+ retry.outputs = [];
5476
+ retry.events = [];
5026
5477
  }
5027
5478
  onStepBegin(test, result, step) {
5028
- if (!this._isUserStep(step))
5479
+ if (!isUserStep(step))
5029
5480
  return;
5030
5481
  const resolved = this._resolvedTests.get(test.id);
5031
5482
  if (!resolved)
5032
5483
  return;
5033
- let parentStep = step.parent;
5034
- while (parentStep && !this._stepToOutput.has(parentStep))
5035
- parentStep = parentStep.parent;
5036
- const parentKey = parentStep ?? test.id;
5037
- const parentManifest = parentStep ? this._stepToManifest.get(parentStep) : void 0;
5038
- const parentSteps = parentManifest ? parentManifest.children : resolved.manifestTest.steps;
5039
- const idx = this._childCounters.get(parentKey) ?? 0;
5040
- this._childCounters.set(parentKey, idx + 1);
5041
- const manifestStep = parentSteps?.[idx] ?? null;
5042
- if (manifestStep)
5043
- this._stepToManifest.set(step, manifestStep);
5044
- this._childCounters.set(step, 0);
5045
- const outputStep = {
5046
- id: manifestStep?.id,
5047
- action: manifestStep?.action,
5484
+ const { matched: parent, blocked } = this._nearestMatchedAncestor(step);
5485
+ const manifestStep = blocked ? null : this._resolveStep(test, resolved, step, parent);
5486
+ if (!manifestStep) {
5487
+ if (blocked || !isToPassWrapper({ title: step.title, category: step.category, apiName: step._apiName }))
5488
+ this._opaqueFiller.add(step);
5489
+ else
5490
+ this._retries.set(step, { parent, startCursor: parent ? parent.cursor : this._rootCursors.get(test.id) ?? 0, events: [], outputs: [] });
5491
+ return;
5492
+ }
5493
+ const output = {
5494
+ id: manifestStep.id,
5495
+ action: manifestStep.action,
5048
5496
  title: step.title,
5049
5497
  category: step.category,
5050
5498
  duration: 0,
@@ -5052,97 +5500,106 @@ var SmoothDeployReporter = class {
5052
5500
  screenshots: null,
5053
5501
  children: []
5054
5502
  };
5055
- this._stepToOutput.set(step, outputStep);
5056
- const parentOutput = parentStep ? this._stepToOutput.get(parentStep) : void 0;
5057
- if (parentOutput)
5058
- parentOutput.children.push(outputStep);
5503
+ this._matched.set(step, { manifest: manifestStep, output, cursor: 0 });
5504
+ const retry = this._nearestRetry(step);
5505
+ if (retry && retry.parent === parent)
5506
+ retry.outputs.push(output);
5507
+ if (parent)
5508
+ parent.output.children.push(output);
5059
5509
  else
5060
- this._testSteps.get(test.id)?.push(outputStep);
5510
+ this._testSteps.get(test.id)?.push(output);
5061
5511
  this._emit({
5062
5512
  event: "stepBegin",
5063
5513
  testId: resolved.manifestTest.id,
5064
- paramIndex: resolved.paramIndex,
5065
- id: manifestStep?.id,
5066
- action: manifestStep?.action,
5514
+ projectName: resolved.projectName,
5515
+ id: manifestStep.id,
5516
+ action: manifestStep.action,
5067
5517
  title: step.title,
5068
5518
  category: step.category,
5069
5519
  timestamp: Date.now()
5070
- });
5520
+ }, step);
5521
+ }
5522
+ _screenshotsFor(test, step) {
5523
+ const hasScreenshot = step.category === "pw:api" && !NO_SCREENSHOT_PREFIXES.some((prefix) => step.title.startsWith(prefix));
5524
+ if (!hasScreenshot)
5525
+ return null;
5526
+ const safeStepId = safeId(step._stepId ?? step.title);
5527
+ return {
5528
+ safeStepId,
5529
+ paths: {
5530
+ page: `.smoothdeploy-output/screenshots/${safeId(test.id)}/${safeStepId}-page.png`,
5531
+ element: `.smoothdeploy-output/screenshots/${safeId(test.id)}/${safeStepId}-element.png`
5532
+ }
5533
+ };
5071
5534
  }
5072
5535
  onStepEnd(test, result, step) {
5073
- if (!this._isUserStep(step))
5536
+ if (!isUserStep(step))
5074
5537
  return;
5075
5538
  const resolved = this._resolvedTests.get(test.id);
5076
5539
  if (!resolved)
5077
5540
  return;
5078
- const manifestStep = this._stepToManifest.get(step) ?? null;
5079
- const outputStep = this._stepToOutput.get(step);
5080
- const safeTestId = test.id.replace(/[^a-zA-Z0-9_-]/g, "-");
5081
- const noScreenshotPrefixes = [
5082
- "Navigate",
5083
- "Go back",
5084
- "Go forward",
5085
- "Reload",
5086
- "Screenshot",
5087
- "Wait for",
5088
- "Pause",
5089
- "Evaluate"
5090
- ];
5091
- const hasScreenshot = step.category === "pw:api" && !noScreenshotPrefixes.some((prefix) => step.title.startsWith(prefix));
5092
- const internalStepId = step._stepId ?? step.title;
5093
- const safeStepId = internalStepId.replace(/[^a-zA-Z0-9_-]/g, "-");
5094
- const screenshots = hasScreenshot ? {
5095
- page: `.smoothdeploy-output/screenshots/${safeTestId}/${safeStepId}-page.png`,
5096
- element: `.smoothdeploy-output/screenshots/${safeTestId}/${safeStepId}-element.png`
5097
- } : null;
5098
- if (manifestStep) {
5099
- const safeManifestStepId = manifestStep.id.replace(/[^a-zA-Z0-9_-]/g, "-");
5100
- this._stepIdMap.set(safeStepId, safeManifestStepId);
5101
- }
5102
- if (outputStep) {
5103
- outputStep.duration = step.duration;
5104
- const hasDescendantError = (steps) => steps.some((c) => c.error !== null || hasDescendantError(c.children));
5105
- outputStep.error = step.error && !hasDescendantError(outputStep.children) ? { message: step.error.message ?? "" } : null;
5106
- outputStep.screenshots = screenshots;
5107
- }
5108
- this._childCounters.delete(step);
5541
+ const retry = this._retries.get(step);
5542
+ if (retry) {
5543
+ this._retries.delete(step);
5544
+ for (const event of retry.events)
5545
+ this._emit(event, step);
5546
+ return;
5547
+ }
5548
+ const matched = this._matched.get(step);
5549
+ const screenshots = this._screenshotsFor(test, step);
5550
+ if (!matched) {
5551
+ const leaf = this._nearestMatchedAncestor(step).matched;
5552
+ if (screenshots && leaf && leaf.manifest.children.length === 0 && !leaf.output.screenshots) {
5553
+ this._stepIdMap.set(screenshots.safeStepId, safeId(leaf.manifest.id));
5554
+ leaf.output.screenshots = screenshots.paths;
5555
+ }
5556
+ return;
5557
+ }
5558
+ if (screenshots) {
5559
+ this._stepIdMap.set(screenshots.safeStepId, safeId(matched.manifest.id));
5560
+ matched.output.screenshots = screenshots.paths;
5561
+ }
5562
+ matched.output.duration = step.duration;
5563
+ const skipped = step.annotations.some((a) => a.type === "skip");
5564
+ if (skipped)
5565
+ matched.output.skipped = true;
5566
+ const hasDescendantError = (steps) => steps.some((c) => c.error !== null || hasDescendantError(c.children));
5567
+ matched.output.error = step.error && !hasDescendantError(matched.output.children) ? { message: step.error.message ?? "" } : null;
5109
5568
  this._emit({
5110
5569
  event: "stepEnd",
5111
5570
  testId: resolved.manifestTest.id,
5112
- paramIndex: resolved.paramIndex,
5113
- id: manifestStep?.id,
5114
- action: manifestStep?.action,
5571
+ projectName: resolved.projectName,
5572
+ id: matched.manifest.id,
5573
+ action: matched.manifest.action,
5115
5574
  title: step.title,
5116
5575
  duration: step.duration,
5117
5576
  error: step.error ? { message: step.error.message } : null,
5577
+ skipped,
5118
5578
  timestamp: Date.now()
5119
- });
5579
+ }, step);
5120
5580
  }
5121
5581
  onEnd(result) {
5122
- const outputDir = path12.join(process.cwd(), ".smoothdeploy-output");
5123
- const screenshotsDir = path12.join(outputDir, "screenshots");
5124
- if (this._manifest) {
5125
- for (const [safePwTestId] of this._testIdMap) {
5126
- const testDir = path12.join(screenshotsDir, safePwTestId);
5127
- if (!fs9.existsSync(testDir))
5128
- continue;
5129
- for (const [safePwStepId, safeManifestStepId] of this._stepIdMap) {
5130
- for (const suffix of ["-page.png", "-element.png"]) {
5131
- const src = path12.join(testDir, `${safePwStepId}${suffix}`);
5132
- const dst = path12.join(testDir, `${safeManifestStepId}${suffix}`);
5133
- if (fs9.existsSync(src))
5134
- fs9.renameSync(src, dst);
5135
- }
5582
+ const outputDir = path13.join(process.cwd(), ".smoothdeploy-output");
5583
+ const screenshotsDir = path13.join(outputDir, "screenshots");
5584
+ for (const [safePwTestId] of this._testIdMap) {
5585
+ const testDir = path13.join(screenshotsDir, safePwTestId);
5586
+ if (!fs10.existsSync(testDir))
5587
+ continue;
5588
+ for (const [safePwStepId, safeManifestStepId] of this._stepIdMap) {
5589
+ for (const suffix of ["-page.png", "-element.png"]) {
5590
+ const src = path13.join(testDir, `${safePwStepId}${suffix}`);
5591
+ if (fs10.existsSync(src))
5592
+ fs10.renameSync(src, path13.join(testDir, `${safeManifestStepId}${suffix}`));
5136
5593
  }
5137
5594
  }
5138
- for (const [safePwTestId, safeManifestTestId] of this._testIdMap) {
5139
- const src = path12.join(screenshotsDir, safePwTestId);
5140
- const dst = path12.join(screenshotsDir, safeManifestTestId);
5141
- if (fs9.existsSync(src)) {
5142
- if (fs9.existsSync(dst))
5143
- fs9.rmSync(dst, { recursive: true });
5144
- fs9.renameSync(src, dst);
5145
- }
5595
+ }
5596
+ for (const [safePwTestId, safeManifestTestId] of this._testIdMap) {
5597
+ const src = path13.join(screenshotsDir, safePwTestId);
5598
+ const dst = path13.join(screenshotsDir, safeManifestTestId);
5599
+ if (src !== dst && fs10.existsSync(src)) {
5600
+ if (fs10.existsSync(dst))
5601
+ fs10.rmSync(dst, { recursive: true });
5602
+ fs10.renameSync(src, dst);
5146
5603
  }
5147
5604
  }
5148
5605
  const remapScreenshotPaths = (steps) => {
@@ -5160,24 +5617,17 @@ var SmoothDeployReporter = class {
5160
5617
  if (!resolved)
5161
5618
  continue;
5162
5619
  remapScreenshotPaths(steps);
5163
- const safeManifestTestId = resolved.manifestTest.id.replace(/[^a-zA-Z0-9_-]/g, "-");
5164
- const failurePath = path12.join(screenshotsDir, safeManifestTestId, "failure.png");
5165
- const failureScreenshot = fs9.existsSync(failurePath) ? `.smoothdeploy-output/screenshots/${safeManifestTestId}/failure.png` : null;
5620
+ const safeManifestTestId = safeId(resolved.manifestTest.id);
5621
+ const failurePath = path13.join(screenshotsDir, safeManifestTestId, "failure.png");
5622
+ const failureScreenshot = fs10.existsSync(failurePath) ? `.smoothdeploy-output/screenshots/${safeManifestTestId}/failure.png` : null;
5166
5623
  const key = resolved.manifestTest.id;
5167
5624
  if (!manifest[key])
5168
5625
  manifest[key] = [];
5169
- manifest[key].push({ paramIndex: resolved.paramIndex, steps, failureScreenshot });
5626
+ manifest[key].push({ projectName: resolved.projectName, steps, failureScreenshot });
5170
5627
  }
5171
- fs9.mkdirSync(outputDir, { recursive: true });
5172
- fs9.writeFileSync(
5173
- path12.join(outputDir, "manifest.json"),
5174
- JSON.stringify(manifest, null, 2)
5175
- );
5176
- this._emit({
5177
- event: "runEnd",
5178
- status: result.status,
5179
- timestamp: Date.now()
5180
- });
5628
+ fs10.mkdirSync(outputDir, { recursive: true });
5629
+ fs10.writeFileSync(path13.join(outputDir, "manifest.json"), JSON.stringify(manifest, null, 2));
5630
+ this._emit({ event: "runEnd", status: result.status, timestamp: Date.now() });
5181
5631
  }
5182
5632
  _remapPath(screenshotPath) {
5183
5633
  let result = screenshotPath;
@@ -5194,21 +5644,20 @@ var smoothdeploy_default = SmoothDeployReporter;
5194
5644
  var { calculateSha1: calculateSha13 } = require("playwright-core/lib/coreBundle").utils;
5195
5645
  async function createReporters(config2, mode, descriptions, runOptions) {
5196
5646
  const defaultReporters = {
5197
- blob: BlobReporter,
5198
- dot: mode === "list" ? listModeReporter_default : dot_default,
5199
- line: mode === "list" ? listModeReporter_default : line_default,
5200
- list: mode === "list" ? listModeReporter_default : list_default,
5201
- github: github_default,
5202
- json: json_default,
5203
- junit: junit_default,
5204
- null: empty_default,
5205
- html: html_default,
5206
- smoothdeploy: smoothdeploy_default
5647
+ "blob": BlobReporter,
5648
+ "perfetto": perfetto_default,
5649
+ "dot": mode === "list" ? listModeReporter_default : dot_default,
5650
+ "line": mode === "list" ? listModeReporter_default : line_default,
5651
+ "list": mode === "list" ? listModeReporter_default : list_default,
5652
+ "github": github_default,
5653
+ "json": json_default,
5654
+ "junit": junit_default,
5655
+ "null": empty_default,
5656
+ "html": html_default,
5657
+ "smoothdeploy": smoothdeploy_default
5207
5658
  };
5208
5659
  const reporters = [];
5209
5660
  descriptions ??= config2.config.reporter;
5210
- if (runOptions?.additionalReporters)
5211
- descriptions = [...descriptions, ...runOptions.additionalReporters];
5212
5661
  const reportOptions = reporterCommandOptions(config2, mode, runOptions);
5213
5662
  for (const r of descriptions) {
5214
5663
  const [name, arg] = r;
@@ -5272,22 +5721,22 @@ function computeCommandHash(config2, runOptions) {
5272
5721
  if (config2.config.tags.length)
5273
5722
  command.tags = config2.config.tags.join(" ");
5274
5723
  if (runOptions?.testList)
5275
- command.testList = calculateSha13(import_fs8.default.readFileSync(runOptions.testList));
5724
+ command.testList = calculateSha13(import_fs9.default.readFileSync(runOptions.testList));
5276
5725
  if (runOptions?.testListInvert)
5277
- command.testListInvert = calculateSha13(import_fs8.default.readFileSync(runOptions.testListInvert));
5726
+ command.testListInvert = calculateSha13(import_fs9.default.readFileSync(runOptions.testListInvert));
5278
5727
  if (Object.keys(command).length)
5279
5728
  parts.push(calculateSha13(JSON.stringify(command)).substring(0, 7));
5280
5729
  return parts.join("-");
5281
5730
  }
5282
5731
 
5283
5732
  // packages/playwright/src/runner/tasks.ts
5284
- var import_fs11 = __toESM(require("fs"));
5285
- var import_path15 = __toESM(require("path"));
5286
- var import_util13 = require("util");
5733
+ var import_fs12 = __toESM(require("fs"));
5734
+ var import_path16 = __toESM(require("path"));
5735
+ var import_util14 = require("util");
5287
5736
 
5288
5737
  // packages/playwright/src/runner/rebase.ts
5289
- var import_fs9 = __toESM(require("fs"));
5290
- var import_path12 = __toESM(require("path"));
5738
+ var import_fs10 = __toESM(require("fs"));
5739
+ var import_path13 = __toESM(require("path"));
5291
5740
  var babel3 = __toESM(require("../transform/babelBundle"));
5292
5741
  var colors3 = require("playwright-core/lib/utilsBundle").colors;
5293
5742
  var diff = require("playwright-core/lib/utilsBundle").diff;
@@ -5311,9 +5760,9 @@ async function applySuggestedRebaselines(config2, reporter, filteredProjects) {
5311
5760
  const patches = [];
5312
5761
  const files = [];
5313
5762
  const gitCache = /* @__PURE__ */ new Map();
5314
- const patchFile = import_path12.default.join(project.project.outputDir, "rebaselines.patch");
5763
+ const patchFile = import_path13.default.join(project.project.outputDir, "rebaselines.patch");
5315
5764
  for (const fileName of [...suggestedRebaselines.keys()].sort()) {
5316
- const source = await import_fs9.default.promises.readFile(fileName, "utf8");
5765
+ const source = await import_fs10.default.promises.readFile(fileName, "utf8");
5317
5766
  const lines = source.split("\n");
5318
5767
  const replacements = suggestedRebaselines.get(fileName);
5319
5768
  const fileNode = babel3.babelParse(source, fileName, true);
@@ -5347,15 +5796,15 @@ async function applySuggestedRebaselines(config2, reporter, filteredProjects) {
5347
5796
  let result = source;
5348
5797
  for (const range of ranges)
5349
5798
  result = result.substring(0, range.start) + range.newText + result.substring(range.end);
5350
- const relativeName = import_path12.default.relative(process.cwd(), fileName);
5799
+ const relativeName = import_path13.default.relative(process.cwd(), fileName);
5351
5800
  files.push(relativeName);
5352
5801
  if (config2.config.updateSourceMethod === "overwrite") {
5353
- await import_fs9.default.promises.writeFile(fileName, result);
5802
+ await import_fs10.default.promises.writeFile(fileName, result);
5354
5803
  } else if (config2.config.updateSourceMethod === "3way") {
5355
- await import_fs9.default.promises.writeFile(fileName, applyPatchWithConflictMarkers(source, result));
5804
+ await import_fs10.default.promises.writeFile(fileName, applyPatchWithConflictMarkers(source, result));
5356
5805
  } else {
5357
- const gitFolder = findGitRoot(import_path12.default.dirname(fileName), gitCache);
5358
- const relativeToGit = import_path12.default.relative(gitFolder || process.cwd(), fileName);
5806
+ const gitFolder = findGitRoot(import_path13.default.dirname(fileName), gitCache);
5807
+ const relativeToGit = import_path13.default.relative(gitFolder || process.cwd(), fileName);
5359
5808
  patches.push(createPatch(relativeToGit, source, result));
5360
5809
  }
5361
5810
  }
@@ -5366,10 +5815,10 @@ New baselines created for:
5366
5815
  ${fileList}
5367
5816
  `);
5368
5817
  if (config2.config.updateSourceMethod === "patch") {
5369
- await import_fs9.default.promises.mkdir(import_path12.default.dirname(patchFile), { recursive: true });
5370
- await import_fs9.default.promises.writeFile(patchFile, patches.join("\n"));
5818
+ await import_fs10.default.promises.mkdir(import_path13.default.dirname(patchFile), { recursive: true });
5819
+ await import_fs10.default.promises.writeFile(patchFile, patches.join("\n"));
5371
5820
  reporter.onStdErr(`
5372
- ` + colors3.cyan("git apply " + import_path12.default.relative(process.cwd(), patchFile)) + "\n");
5821
+ ` + colors3.cyan("git apply " + import_path13.default.relative(process.cwd(), patchFile)) + "\n");
5373
5822
  }
5374
5823
  }
5375
5824
  function createPatch(fileName, before, after) {
@@ -5386,12 +5835,12 @@ function findGitRoot(dir, cache) {
5386
5835
  const result = cache.get(dir);
5387
5836
  if (result !== void 0)
5388
5837
  return result;
5389
- const gitPath = import_path12.default.join(dir, ".git");
5390
- if (import_fs9.default.existsSync(gitPath) && import_fs9.default.lstatSync(gitPath).isDirectory()) {
5838
+ const gitPath = import_path13.default.join(dir, ".git");
5839
+ if (import_fs10.default.existsSync(gitPath) && import_fs10.default.lstatSync(gitPath).isDirectory()) {
5391
5840
  cache.set(dir, dir);
5392
5841
  return dir;
5393
5842
  }
5394
- const parentDir = import_path12.default.dirname(dir);
5843
+ const parentDir = import_path13.default.dirname(dir);
5395
5844
  if (dir === parentDir) {
5396
5845
  cache.set(dir, null);
5397
5846
  return null;
@@ -5435,8 +5884,8 @@ function applyPatchWithConflictMarkers(oldText, newText) {
5435
5884
  }
5436
5885
 
5437
5886
  // packages/playwright/src/runner/workerHost.ts
5438
- var import_fs10 = __toESM(require("fs"));
5439
- var import_path13 = __toESM(require("path"));
5887
+ var import_fs11 = __toESM(require("fs"));
5888
+ var import_path14 = __toESM(require("path"));
5440
5889
  var import_common6 = require("../common");
5441
5890
 
5442
5891
  // packages/playwright/src/isomorphic/folders.ts
@@ -5465,13 +5914,13 @@ var WorkerHost = class extends ProcessHost {
5465
5914
  repeatEachIndex: testGroup.repeatEachIndex,
5466
5915
  projectId: testGroup.projectId,
5467
5916
  config: options.config,
5468
- artifactsDir: import_path13.default.join(options.outputDir, artifactsFolderName(workerIndex)),
5917
+ artifactsDir: import_path14.default.join(options.outputDir, artifactsFolderName(workerIndex)),
5469
5918
  pauseOnError: options.pauseOnError,
5470
5919
  pauseAtEnd: options.pauseAtEnd
5471
5920
  };
5472
5921
  }
5473
5922
  async start() {
5474
- await import_fs10.default.promises.mkdir(this._params.artifactsDir, { recursive: true });
5923
+ await import_fs11.default.promises.mkdir(this._params.artifactsDir, { recursive: true });
5475
5924
  return await this.startRunner(this._params, {
5476
5925
  onStdOut: (chunk) => this.emit("stdOut", import_common6.ipc.stdioChunkToParams(chunk)),
5477
5926
  onStdErr: (chunk) => this.emit("stdErr", import_common6.ipc.stdioChunkToParams(chunk))
@@ -5507,7 +5956,7 @@ var WorkerHost = class extends ProcessHost {
5507
5956
 
5508
5957
  // packages/playwright/src/runner/dispatcher.ts
5509
5958
  var import_common7 = require("../common");
5510
- var import_util11 = require("../util");
5959
+ var import_util12 = require("../util");
5511
5960
  var colors4 = require("playwright-core/lib/utilsBundle").colors;
5512
5961
  var { ManualPromise: ManualPromise3 } = require("playwright-core/lib/coreBundle").iso;
5513
5962
  var { eventsHelper } = require("playwright-core/lib/coreBundle").utils;
@@ -5530,11 +5979,22 @@ var Dispatcher = class {
5530
5979
  this._workerLimitPerProjectId.set(project.id, project.workers);
5531
5980
  }
5532
5981
  }
5982
+ _heldLocks() {
5983
+ const heldLocks = /* @__PURE__ */ new Set();
5984
+ for (const slot of this._workerSlots) {
5985
+ for (const lock of slot.jobDispatcher?.job.locks || [])
5986
+ heldLocks.add(lock);
5987
+ }
5988
+ return heldLocks;
5989
+ }
5533
5990
  _findFirstJobToRun() {
5991
+ const heldLocks = this._heldLocks();
5534
5992
  for (let index = 0; index < this._queue.length; index++) {
5535
5993
  const job = this._queue[index];
5536
5994
  if (this._isolatedJobs.has(job) && this._workerSlots.some((w) => !!w.jobDispatcher))
5537
5995
  continue;
5996
+ if (job.locks.some((lock) => heldLocks.has(lock)))
5997
+ continue;
5538
5998
  const projectIdWorkerLimit = this._workerLimitPerProjectId.get(job.projectId);
5539
5999
  if (!projectIdWorkerLimit)
5540
6000
  return index;
@@ -5544,18 +6004,22 @@ var Dispatcher = class {
5544
6004
  }
5545
6005
  return -1;
5546
6006
  }
6007
+ _scheduleJobs() {
6008
+ while (this._scheduleJob()) {
6009
+ }
6010
+ }
5547
6011
  _scheduleJob() {
5548
- if (this._isStopped)
5549
- return;
6012
+ if (this._isStopped || !this._workerSlots.some((w) => !w.jobDispatcher))
6013
+ return false;
5550
6014
  const jobIndex = this._findFirstJobToRun();
5551
6015
  if (jobIndex === -1)
5552
- return;
6016
+ return false;
5553
6017
  const job = this._queue[jobIndex];
5554
6018
  let workerIndex = this._workerSlots.findIndex((w) => !w.jobDispatcher && w.worker && w.worker.hash() === job.workerHash && !w.worker.didSendStop());
5555
6019
  if (workerIndex === -1)
5556
6020
  workerIndex = this._workerSlots.findIndex((w) => !w.jobDispatcher);
5557
6021
  if (workerIndex === -1) {
5558
- return;
6022
+ return false;
5559
6023
  }
5560
6024
  this._queue.splice(jobIndex, 1);
5561
6025
  const jobDispatcher = new JobDispatcher(job, this._testRun, this._ignoreMaxFailures ? void 0 : () => this.stop().catch(() => {
@@ -5564,8 +6028,9 @@ var Dispatcher = class {
5564
6028
  void this._runJobInWorker(workerIndex, jobDispatcher).then(() => {
5565
6029
  this._workerSlots[workerIndex].jobDispatcher = void 0;
5566
6030
  this._checkFinished();
5567
- this._scheduleJob();
6031
+ this._scheduleJobs();
5568
6032
  });
6033
+ return true;
5569
6034
  }
5570
6035
  async _runJobInWorker(index, jobDispatcher) {
5571
6036
  const job = jobDispatcher.job;
@@ -5643,8 +6108,7 @@ var Dispatcher = class {
5643
6108
  void this.stop();
5644
6109
  for (let i = 0; i < this._testRun.config.config.workers; i++)
5645
6110
  this._workerSlots.push({});
5646
- for (let i = 0; i < this._workerSlots.length; i++)
5647
- this._scheduleJob();
6111
+ this._scheduleJobs();
5648
6112
  this._checkFinished();
5649
6113
  await this._finished;
5650
6114
  }
@@ -5786,19 +6250,23 @@ var JobDispatcher = class {
5786
6250
  const parentStep = params.parentStepId ? steps.get(params.parentStepId) : void 0;
5787
6251
  const step = {
5788
6252
  title: params.title,
6253
+ subtitle: params.subtitle,
5789
6254
  titlePath: () => {
5790
6255
  const parentPath = parentStep?.titlePath() || [];
5791
6256
  return [...parentPath, params.title];
5792
6257
  },
5793
6258
  parent: parentStep,
5794
6259
  category: params.category,
6260
+ params: params.params,
5795
6261
  startTime: new Date(params.wallTime),
5796
6262
  duration: -1,
5797
6263
  steps: [],
5798
6264
  attachments: [],
5799
6265
  annotations: [],
5800
6266
  location: params.location,
5801
- _stepId: params.stepId
6267
+ _stepId: params.stepId,
6268
+ _apiName: params.apiName,
6269
+ _channelMethod: params.channelMethod
5802
6270
  };
5803
6271
  steps.set(params.stepId, step);
5804
6272
  (parentStep || result).steps.push(step);
@@ -5980,7 +6448,7 @@ var JobDispatcher = class {
5980
6448
  addLocationAndSnippetToError(this._testRun.config.config, response.error);
5981
6449
  return response;
5982
6450
  } catch (e) {
5983
- const error = (0, import_util11.serializeError)(e);
6451
+ const error = (0, import_util12.serializeError)(e);
5984
6452
  addLocationAndSnippetToError(this._testRun.config.config, error);
5985
6453
  return { response: void 0, error };
5986
6454
  }
@@ -6099,7 +6567,7 @@ var FixedNodeSIGINTHandler = class {
6099
6567
  };
6100
6568
 
6101
6569
  // packages/playwright/src/runner/taskRunner.ts
6102
- var import_util12 = require("../util");
6570
+ var import_util13 = require("../util");
6103
6571
  var colors5 = require("playwright-core/lib/utilsBundle").colors;
6104
6572
  var debug4 = require("playwright-core/lib/utilsBundle").debug;
6105
6573
  var { ManualPromise: ManualPromise4 } = require("playwright-core/lib/coreBundle").iso;
@@ -6140,7 +6608,7 @@ var TaskRunner = class _TaskRunner {
6140
6608
  await task.setup?.(context, errors, softErrors);
6141
6609
  } catch (e) {
6142
6610
  debug4("pw:test:task")(`error in "${task.title}": `, e);
6143
- errors.push((0, import_util12.serializeError)(e));
6611
+ errors.push((0, import_util13.serializeError)(e));
6144
6612
  } finally {
6145
6613
  for (const error of [...softErrors, ...errors])
6146
6614
  this._reporter.onError?.(error);
@@ -6202,7 +6670,7 @@ var TimeoutWatcher = class {
6202
6670
 
6203
6671
  // packages/playwright/src/runner/vcs.ts
6204
6672
  var import_child_process2 = __toESM(require("child_process"));
6205
- var import_path14 = __toESM(require("path"));
6673
+ var import_path15 = __toESM(require("path"));
6206
6674
  var import_common8 = require("../common");
6207
6675
  async function detectChangedTestFiles(baseCommit, configDir) {
6208
6676
  function gitFileList(args) {
@@ -6232,20 +6700,20 @@ async function detectChangedTestFiles(baseCommit, configDir) {
6232
6700
  ].join("\n"));
6233
6701
  }
6234
6702
  }
6235
- const untrackedFiles = gitFileList(["ls-files", "--others", "--exclude-standard"]).map((file) => import_path14.default.join(configDir, file));
6703
+ const untrackedFiles = gitFileList(["ls-files", "--others", "--exclude-standard"]).map((file) => import_path15.default.join(configDir, file));
6236
6704
  const [gitRoot] = gitFileList(["rev-parse", "--show-toplevel"]);
6237
- const trackedFilesWithChanges = gitFileList(["diff", baseCommit, "--name-only"]).map((file) => import_path14.default.join(gitRoot, file));
6705
+ const trackedFilesWithChanges = gitFileList(["diff", baseCommit, "--name-only"]).map((file) => import_path15.default.join(gitRoot, file));
6238
6706
  return new Set(import_common8.cc.affectedTestFiles([...untrackedFiles, ...trackedFilesWithChanges]));
6239
6707
  }
6240
6708
 
6241
6709
  // packages/playwright/src/runner/tasks.ts
6242
6710
  var import_common9 = require("../common");
6243
- var import_util14 = require("../util");
6711
+ var import_util15 = require("../util");
6244
6712
  var debug5 = require("playwright-core/lib/utilsBundle").debug;
6245
6713
  var { ManualPromise: ManualPromise5 } = require("playwright-core/lib/coreBundle").iso;
6246
6714
  var { monotonicTime: monotonicTime6 } = require("playwright-core/lib/coreBundle").iso;
6247
6715
  var { removeFolders: removeFolders4 } = require("playwright-core/lib/coreBundle").utils;
6248
- var readDirAsync2 = (0, import_util13.promisify)(import_fs11.default.readdir);
6716
+ var readDirAsync2 = (0, import_util14.promisify)(import_fs12.default.readdir);
6249
6717
  var TestRun = class {
6250
6718
  constructor(config2, reporter, options) {
6251
6719
  this.rootSuite = void 0;
@@ -6316,7 +6784,6 @@ function createRunTestsTasks(config2) {
6316
6784
  return [
6317
6785
  createPhasesTask(),
6318
6786
  createReportBeginTask(),
6319
- ...config2.plugins.map((plugin) => createPluginBeginTask(plugin)),
6320
6787
  createRunTestsTask()
6321
6788
  ];
6322
6789
  }
@@ -6324,9 +6791,7 @@ function createClearCacheTask(config2) {
6324
6791
  return {
6325
6792
  title: "clear cache",
6326
6793
  setup: async () => {
6327
- await (0, import_util14.removeDirAndLogToConsole)(import_common9.cc.cacheDir);
6328
- for (const plugin of config2.plugins)
6329
- await plugin.instance?.clearCache?.();
6794
+ await (0, import_util15.removeDirAndLogToConsole)(import_common9.cc.cacheDir);
6330
6795
  }
6331
6796
  };
6332
6797
  }
@@ -6355,17 +6820,6 @@ function createPluginSetupTasks(config2) {
6355
6820
  }
6356
6821
  }));
6357
6822
  }
6358
- function createPluginBeginTask(plugin) {
6359
- return {
6360
- title: "plugin begin",
6361
- setup: async (testRun) => {
6362
- await plugin.instance?.begin?.(testRun.rootSuite);
6363
- },
6364
- teardown: async () => {
6365
- await plugin.instance?.end?.();
6366
- }
6367
- };
6368
- }
6369
6823
  function createGlobalSetupTask(file, config2) {
6370
6824
  let title = "global setup";
6371
6825
  if (config2.globalSetups.length > 1)
@@ -6408,7 +6862,7 @@ function createRemoveOutputDirsTask() {
6408
6862
  return;
6409
6863
  if (error.code === "EBUSY") {
6410
6864
  const entries = await readDirAsync2(outputDir).catch((e) => []);
6411
- await Promise.all(entries.map((entry) => removeFolders4([import_path15.default.join(outputDir, entry)])));
6865
+ await Promise.all(entries.map((entry) => removeFolders4([import_path16.default.join(outputDir, entry)])));
6412
6866
  } else {
6413
6867
  throw error;
6414
6868
  }
@@ -6427,7 +6881,7 @@ function createListFilesTask() {
6427
6881
  projectSuite._fullProject = project;
6428
6882
  testRun.rootSuite._addSuite(projectSuite);
6429
6883
  const suites = files.map((file) => {
6430
- const title = import_path15.default.relative(testRun.config.config.rootDir, file);
6884
+ const title = import_path16.default.relative(testRun.config.config.rootDir, file);
6431
6885
  const suite = new import_common9.test.Suite(title, "file");
6432
6886
  suite.location = { file, line: 0, column: 0 };
6433
6887
  projectSuite._addSuite(suite);
@@ -6457,8 +6911,8 @@ function createLoadTask(mode, options) {
6457
6911
  testRun.preOnlyTestFilters.push((test) => !testFilter(test));
6458
6912
  }
6459
6913
  if (testRun.options.grep || testRun.options.grepInvert) {
6460
- const grepMatcher = testRun.options.grep ? (0, import_util14.createTitleMatcher)((0, import_util14.forceRegExp)(testRun.options.grep)) : () => true;
6461
- const grepInvertMatcher = testRun.options.grepInvert ? (0, import_util14.createTitleMatcher)((0, import_util14.forceRegExp)(testRun.options.grepInvert)) : () => false;
6914
+ const grepMatcher = testRun.options.grep ? (0, import_util15.createTitleMatcher)((0, import_util15.forceRegExp)(testRun.options.grep)) : () => true;
6915
+ const grepInvertMatcher = testRun.options.grepInvert ? (0, import_util15.createTitleMatcher)((0, import_util15.forceRegExp)(testRun.options.grepInvert)) : () => false;
6462
6916
  testRun.preOnlyTestFilters.push((test) => {
6463
6917
  const grepTitle = test._grepTitleWithTags();
6464
6918
  return !grepInvertMatcher(grepTitle) && grepMatcher(grepTitle);
@@ -6470,10 +6924,6 @@ function createLoadTask(mode, options) {
6470
6924
  }
6471
6925
  await collectProjectsAndTestFiles(testRun, !!options.doNotRunDepsOutsideProjectFilter);
6472
6926
  await loadFileSuites(testRun, mode, options.failOnLoadErrors ? errors : softErrors);
6473
- if (testRun.options.onlyChanged || options.populateDependencies) {
6474
- for (const plugin of testRun.config.plugins)
6475
- await plugin.instance?.populateDependencies?.();
6476
- }
6477
6927
  if (testRun.options.onlyChanged) {
6478
6928
  const changedFiles = await detectChangedTestFiles(testRun.options.onlyChanged, testRun.config.configDir);
6479
6929
  testRun.preOnlyTestFilters.push((test) => changedFiles.has(test.location.file));
@@ -6597,25 +7047,32 @@ function createRunTestsTask() {
6597
7047
  }
6598
7048
 
6599
7049
  // packages/playwright/src/runner/lastRun.ts
6600
- var import_fs12 = __toESM(require("fs"));
6601
- var import_path16 = __toESM(require("path"));
7050
+ var import_fs13 = __toESM(require("fs"));
7051
+ var import_path17 = __toESM(require("path"));
7052
+ function didNotRun(test) {
7053
+ if (test.outcome() !== "skipped")
7054
+ return false;
7055
+ if (test.results.some((result) => result.status === "interrupted"))
7056
+ return false;
7057
+ return !test.results.length || test.expectedStatus !== "skipped";
7058
+ }
6602
7059
  var LastRunReporter = class {
6603
7060
  constructor(filteredProjects, listMode, lastFailedFileOverride) {
6604
7061
  this._listMode = !!listMode;
6605
7062
  const override = lastFailedFileOverride ?? process.env.PLAYWRIGHT_LAST_RUN_OUTPUT_FILE;
6606
7063
  if (override) {
6607
- this._lastRunFile = import_path16.default.resolve(process.cwd(), override);
7064
+ this._lastRunFile = import_path17.default.resolve(process.cwd(), override);
6608
7065
  } else {
6609
7066
  const [project] = filteredProjects;
6610
7067
  if (project)
6611
- this._lastRunFile = import_path16.default.join(project.project.outputDir, ".last-run.json");
7068
+ this._lastRunFile = import_path17.default.join(project.project.outputDir, ".last-run.json");
6612
7069
  }
6613
7070
  }
6614
7071
  async filterLastFailed() {
6615
7072
  if (!this._lastRunFile)
6616
7073
  return void 0;
6617
7074
  try {
6618
- const lastRunInfo = JSON.parse(await import_fs12.default.promises.readFile(this._lastRunFile, "utf8"));
7075
+ const lastRunInfo = JSON.parse(await import_fs13.default.promises.readFile(this._lastRunFile, "utf8"));
6619
7076
  return lastRunInfo.failedTests;
6620
7077
  } catch {
6621
7078
  return void 0;
@@ -6635,10 +7092,10 @@ var LastRunReporter = class {
6635
7092
  return;
6636
7093
  const lastRunInfo = {
6637
7094
  status: result.status,
6638
- failedTests: this._suite?.allTests().filter((t2) => !t2.ok()).map((t2) => t2.id) || []
7095
+ failedTests: this._suite?.allTests().filter((t2) => !t2.ok() || didNotRun(t2)).map((t2) => t2.id) || []
6639
7096
  };
6640
- await import_fs12.default.promises.mkdir(import_path16.default.dirname(this._lastRunFile), { recursive: true });
6641
- await import_fs12.default.promises.writeFile(this._lastRunFile, JSON.stringify(lastRunInfo, void 0, 2));
7097
+ await import_fs13.default.promises.mkdir(import_path17.default.dirname(this._lastRunFile), { recursive: true });
7098
+ await import_fs13.default.promises.writeFile(this._lastRunFile, JSON.stringify(lastRunInfo, void 0, 2));
6642
7099
  }
6643
7100
  };
6644
7101
 
@@ -6658,7 +7115,6 @@ var TestRunner = class extends import_events2.default {
6658
7115
  this._watchedTestDependencies = /* @__PURE__ */ new Set();
6659
7116
  this._queue = Promise.resolve();
6660
7117
  this._watchTestDirs = false;
6661
- this._populateDependenciesOnList = false;
6662
7118
  this._startingEnv = {};
6663
7119
  this.configLocation = configLocation;
6664
7120
  this._configCLIOverrides = configCLIOverrides;
@@ -6671,7 +7127,6 @@ var TestRunner = class extends import_events2.default {
6671
7127
  async initialize(params) {
6672
7128
  setPlaywrightTestProcessEnv();
6673
7129
  this._watchTestDirs = !!params.watchTestDirs;
6674
- this._populateDependenciesOnList = !!params.populateDependenciesOnList;
6675
7130
  this._startingEnv = { ...process.env };
6676
7131
  }
6677
7132
  resizeTerminal(params) {
@@ -6683,7 +7138,7 @@ var TestRunner = class extends import_events2.default {
6683
7138
  hasSomeBrowsers() {
6684
7139
  for (const browserName of ["chromium", "webkit", "firefox"]) {
6685
7140
  try {
6686
- import_coreBundle2.registry.registry.findExecutable(browserName).executablePathOrDie("javascript");
7141
+ import_coreBundle3.registry.registry.findExecutable(browserName).executablePathOrDie("javascript");
6687
7142
  return true;
6688
7143
  } catch {
6689
7144
  }
@@ -6691,8 +7146,8 @@ var TestRunner = class extends import_events2.default {
6691
7146
  return false;
6692
7147
  }
6693
7148
  async installBrowsers() {
6694
- const executables = import_coreBundle2.registry.registry.defaultExecutables();
6695
- await import_coreBundle2.registry.registry.install(executables);
7149
+ const executables = import_coreBundle3.registry.registry.defaultExecutables();
7150
+ await import_coreBundle3.registry.registry.install(executables);
6696
7151
  }
6697
7152
  async loadConfig() {
6698
7153
  const { config: config2, error } = await this._loadConfig(this._configCLIOverrides);
@@ -6732,7 +7187,6 @@ var TestRunner = class extends import_events2.default {
6732
7187
  if (!config2)
6733
7188
  return { status: "failed" };
6734
7189
  const status = await runTasks(new TestRun(config2, reporter), [
6735
- ...createPluginSetupTasks(config2),
6736
7190
  createClearCacheTask(config2)
6737
7191
  ]);
6738
7192
  return { status };
@@ -6779,7 +7233,7 @@ var TestRunner = class extends import_events2.default {
6779
7233
  listMode: true
6780
7234
  };
6781
7235
  const status = await runTasks(new TestRun(config2, reporter, options), [
6782
- createLoadTask("out-of-process", { failOnLoadErrors: false, filterOnly: false, populateDependencies: this._populateDependenciesOnList }),
7236
+ createLoadTask("out-of-process", { failOnLoadErrors: false, filterOnly: false }),
6783
7237
  createReportBeginTask()
6784
7238
  ]);
6785
7239
  return { config: config2, status };
@@ -6791,11 +7245,6 @@ var TestRunner = class extends import_events2.default {
6791
7245
  this._watchedProjectDirs.add(p.project.testDir);
6792
7246
  this._ignoredProjectOutputs.add(p.project.outputDir);
6793
7247
  }
6794
- const result = await resolveCtDirs(config2);
6795
- if (result) {
6796
- this._watchedProjectDirs.add(result.templateDir);
6797
- this._ignoredProjectOutputs.add(result.outDir);
6798
- }
6799
7248
  if (this._watchTestDirs)
6800
7249
  await this._updateWatcher(false);
6801
7250
  }
@@ -6886,7 +7335,7 @@ var TestRunner = class extends import_events2.default {
6886
7335
  return { errors: errorReporter.errors(), testFiles: [] };
6887
7336
  const status = await runTasks(new TestRun(config2, reporter), [
6888
7337
  ...createPluginSetupTasks(config2),
6889
- createLoadTask("out-of-process", { failOnLoadErrors: true, filterOnly: false, populateDependencies: true })
7338
+ createLoadTask("out-of-process", { failOnLoadErrors: true, filterOnly: false })
6890
7339
  ]);
6891
7340
  if (status !== "passed")
6892
7341
  return { errors: errorReporter.errors(), testFiles: [] };
@@ -6915,7 +7364,7 @@ var TestRunner = class extends import_events2.default {
6915
7364
  this._lastLoadedConfig = config2;
6916
7365
  return { config: config2 };
6917
7366
  } catch (e) {
6918
- return { config: null, error: (0, import_util15.serializeError)(e) };
7367
+ return { config: null, error: (0, import_util16.serializeError)(e) };
6919
7368
  }
6920
7369
  }
6921
7370
  lastLoadedConfig() {
@@ -6935,18 +7384,6 @@ var TestRunner = class extends import_events2.default {
6935
7384
  function printInternalError(e) {
6936
7385
  console.error("Internal error:", e);
6937
7386
  }
6938
- async function resolveCtDirs(config2) {
6939
- const use = config2.config.projects[0].use;
6940
- const relativeTemplateDir = use.ctTemplateDir || "playwright";
6941
- const templateDir = await import_fs13.default.promises.realpath(import_path17.default.normalize(import_path17.default.join(config2.configDir, relativeTemplateDir))).catch(() => void 0);
6942
- if (!templateDir)
6943
- return null;
6944
- const outDir = use.ctCacheDir ? import_path17.default.resolve(config2.configDir, use.ctCacheDir) : import_path17.default.resolve(templateDir, ".cache");
6945
- return {
6946
- outDir,
6947
- templateDir
6948
- };
6949
- }
6950
7387
  async function runAllTestsWithConfig(config2, options) {
6951
7388
  setPlaywrightTestProcessEnv();
6952
7389
  addGitCommitInfoPlugin(config2);
@@ -6983,8 +7420,8 @@ __export(testServer_exports, {
6983
7420
  runTestServer: () => runTestServer,
6984
7421
  runUIMode: () => runUIMode
6985
7422
  });
6986
- var import_util16 = __toESM(require("util"));
6987
- var import_coreBundle3 = require("playwright-core/lib/coreBundle");
7423
+ var import_util17 = __toESM(require("util"));
7424
+ var import_coreBundle4 = require("playwright-core/lib/coreBundle");
6988
7425
  var import_common11 = require("../common");
6989
7426
 
6990
7427
  // packages/playwright/src/runner/uiModeReporter.ts
@@ -7013,7 +7450,7 @@ var TestServer = class {
7013
7450
  }
7014
7451
  async start(options) {
7015
7452
  this._dispatcher = new TestServerDispatcher(this._configLocation, this._configCLIOverrides);
7016
- return await import_coreBundle3.server.startTraceViewerServer({
7453
+ return await import_coreBundle4.server.startTraceViewerServer({
7017
7454
  host: options.host,
7018
7455
  port: options.port,
7019
7456
  allowedFileRoots: () => this._allowedFileRoots(),
@@ -7143,7 +7580,7 @@ var TestServerDispatcher = class {
7143
7580
  if (interceptStdio) {
7144
7581
  if (debug6.log === originalDebugLog) {
7145
7582
  debug6.log = (...args) => {
7146
- const string = import_util16.default.format(...args) + "\n";
7583
+ const string = import_util17.default.format(...args) + "\n";
7147
7584
  return originalStderrWrite.apply(process.stderr, [string]);
7148
7585
  };
7149
7586
  }
@@ -7169,12 +7606,12 @@ var TestServerDispatcher = class {
7169
7606
  async function runUIMode(configFile, configCLIOverrides, options) {
7170
7607
  const configLocation = import_common11.configLoader.resolveConfigLocation(configFile);
7171
7608
  return await innerRunTestServer(configLocation, configCLIOverrides, options, async (server, cancelPromise) => {
7172
- await import_coreBundle3.server.installRootRedirect(server, void 0, { ...options, webApp: "uiMode.html" });
7609
+ await import_coreBundle4.server.installRootRedirect(server, void 0, { ...options, webApp: "uiMode.html" });
7173
7610
  if (options.host !== void 0 || options.port !== void 0) {
7174
- await import_coreBundle3.server.openTraceInBrowser(server.urlPrefix("human-readable"));
7611
+ await import_coreBundle4.server.openTraceInBrowser(server.urlPrefix("human-readable"));
7175
7612
  } else {
7176
7613
  const channel = await installedChromiumChannelForUI(configLocation, configCLIOverrides);
7177
- const page = await import_coreBundle3.server.openTraceViewerApp(server.urlPrefix("precise"), "chromium", {
7614
+ const page = await import_coreBundle4.server.openTraceViewerApp(server.urlPrefix("precise"), "chromium", {
7178
7615
  headless: isUnderTest() && process.env.PWTEST_HEADED_FOR_TEST !== "1",
7179
7616
  persistentContextOptions: {
7180
7617
  handleSIGINT: false,
@@ -7239,7 +7676,7 @@ __export(watchMode_exports, {
7239
7676
  var import_path18 = __toESM(require("path"));
7240
7677
  var import_readline = __toESM(require("readline"));
7241
7678
  var import_events3 = require("events");
7242
- var import_coreBundle4 = require("playwright-core/lib/coreBundle");
7679
+ var import_coreBundle5 = require("playwright-core/lib/coreBundle");
7243
7680
 
7244
7681
  // packages/playwright/src/isomorphic/testTree.ts
7245
7682
  var statusEx = /* @__PURE__ */ Symbol("statusEx");
@@ -7658,8 +8095,7 @@ async function runWatchModeLoop(configLocation, initialOptions) {
7658
8095
  testServerConnection.onReport((report2) => teleSuiteUpdater.processTestReportEvent(report2));
7659
8096
  await testServerConnection.initialize({
7660
8097
  interceptStdio: false,
7661
- watchTestDirs: true,
7662
- populateDependenciesOnList: true
8098
+ watchTestDirs: true
7663
8099
  });
7664
8100
  await testServerConnection.runGlobalSetup({});
7665
8101
  const { report } = await testServerConnection.listTests({});
@@ -7921,7 +8357,7 @@ ${colors6.dim("Waiting for file changes. Press")} ${colors6.bold("enter")} ${col
7921
8357
  }
7922
8358
  async function toggleShowBrowser() {
7923
8359
  if (!showBrowserServer) {
7924
- showBrowserServer = new import_coreBundle4.remote.PlaywrightServer({ mode: "extension", path: "/" + createGuid3(), maxConnections: 1 });
8360
+ showBrowserServer = new import_coreBundle5.remote.PlaywrightServer({ mode: "extension", path: "/" + createGuid3(), maxConnections: 1 });
7925
8361
  connectWsEndpoint = await showBrowserServer.listen();
7926
8362
  process.stdout.write(`${colors6.dim("Show & reuse browser:")} ${colors6.bold("on")}
7927
8363
  `);
@@ -7985,7 +8421,7 @@ var JsonStringInternalizer = class {
7985
8421
  };
7986
8422
 
7987
8423
  // packages/playwright/src/reporters/merge.ts
7988
- var import_util17 = require("../util");
8424
+ var import_util18 = require("../util");
7989
8425
  var { isPathInside } = require("playwright-core/lib/coreBundle").utils;
7990
8426
  var { ZipFile } = require("playwright-core/lib/coreBundle").utils;
7991
8427
  async function createMergedReport(config2, dir, reporterDescriptions, rootDirOverride) {
@@ -8081,7 +8517,7 @@ async function extractAndParseReports(dir, shardFiles, internalizer, printStatus
8081
8517
  const reportNames = new UniqueFileNameGenerator();
8082
8518
  for (const file of shardFiles) {
8083
8519
  const absolutePath = import_path19.default.join(dir, file);
8084
- printStatus(`extracting: ${(0, import_util17.relativeFilePath)(absolutePath)}`);
8520
+ printStatus(`extracting: ${(0, import_util18.relativeFilePath)(absolutePath)}`);
8085
8521
  const zipFile = new ZipFile(absolutePath);
8086
8522
  const entryNames = await zipFile.entries();
8087
8523
  for (const entryName of entryNames.sort()) {