@smoothdeploy/playwright 1.60.1 → 1.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -525,6 +525,8 @@ var TeleTestResult = class {
525
525
  }
526
526
  };
527
527
  var baseFullConfig = {
528
+ argv: [],
529
+ failOnFlakyTests: false,
528
530
  forbidOnly: false,
529
531
  fullyParallel: false,
530
532
  globalSetup: null,
@@ -704,15 +706,14 @@ async function gitCommitInfo(gitDir) {
704
706
  // committer name
705
707
  "%ce",
706
708
  // committer email
707
- "%ct",
709
+ "%ct"
708
710
  // committer date, UNIX timestamp
709
- ""
710
- // branch
711
711
  ];
712
- const output = await runGit(`git log -1 --pretty=format:"${tokens.join(separator2)}" && git rev-parse --abbrev-ref HEAD`, gitDir);
713
- if (!output)
712
+ const logOutput = await runGit(["log", "-1", `--pretty=format:${tokens.join(separator2)}`], gitDir);
713
+ if (!logOutput)
714
714
  return void 0;
715
- const [hash, shortHash, subject, body, authorName, authorEmail, authorTime, committerName, committerEmail, committerTime, branch] = output.split(separator2);
715
+ const branchOutput = await runGit(["rev-parse", "--abbrev-ref", "HEAD"], gitDir);
716
+ const [hash, shortHash, subject, body, authorName, authorEmail, authorTime, committerName, committerEmail, committerTime] = logOutput.split(separator2);
716
717
  return {
717
718
  shortHash,
718
719
  hash,
@@ -728,38 +729,38 @@ async function gitCommitInfo(gitDir) {
728
729
  email: committerEmail,
729
730
  time: +committerTime * 1e3
730
731
  },
731
- branch: branch.trim()
732
+ branch: branchOutput?.trim() ?? ""
732
733
  };
733
734
  }
734
735
  async function gitDiff(gitDir, ci) {
735
736
  const diffLimit = 1e5;
736
737
  if (ci?.prBaseHash) {
737
- await runGit(`git fetch origin ${ci.prBaseHash} --depth=1 --no-auto-maintenance --no-auto-gc --no-tags --no-recurse-submodules`, gitDir);
738
- const diff3 = await runGit(`git diff ${ci.prBaseHash} HEAD`, gitDir);
738
+ await runGit(["fetch", "origin", ci.prBaseHash, "--depth=1", "--no-auto-maintenance", "--no-auto-gc", "--no-tags", "--no-recurse-submodules"], gitDir);
739
+ const diff3 = await runGit(["diff", ci.prBaseHash, "HEAD"], gitDir);
739
740
  if (diff3)
740
741
  return diff3.substring(0, diffLimit);
741
742
  }
742
743
  if (ci)
743
744
  return;
744
- const uncommitted = await runGit("git diff", gitDir);
745
+ const uncommitted = await runGit(["diff"], gitDir);
745
746
  if (uncommitted === void 0) {
746
747
  return;
747
748
  }
748
749
  if (uncommitted)
749
750
  return uncommitted.substring(0, diffLimit);
750
- const diff2 = await runGit("git diff HEAD~1", gitDir);
751
+ const diff2 = await runGit(["diff", "HEAD~1"], gitDir);
751
752
  return diff2?.substring(0, diffLimit);
752
753
  }
753
- async function runGit(command, cwd) {
754
- debug(`running "${command}"`);
754
+ async function runGit(args, cwd) {
755
+ debug(`running "git ${args.join(" ")}"`);
755
756
  const start = monotonicTime();
756
757
  const result = await spawnAsync(
757
- command,
758
- [],
759
- { stdio: "pipe", cwd, timeout: GIT_OPERATIONS_TIMEOUT_MS, shell: true }
758
+ "git",
759
+ args,
760
+ { stdio: "pipe", cwd, timeout: GIT_OPERATIONS_TIMEOUT_MS }
760
761
  );
761
762
  if (monotonicTime() - start > GIT_OPERATIONS_TIMEOUT_MS) {
762
- print(`timeout of ${GIT_OPERATIONS_TIMEOUT_MS}ms exceeded while running "${command}"`);
763
+ print(`timeout of ${GIT_OPERATIONS_TIMEOUT_MS}ms exceeded while running "git ${args.join(" ")}"`);
763
764
  return;
764
765
  }
765
766
  if (result.code)
@@ -774,6 +775,7 @@ ${result.stderr}`);
774
775
  // packages/playwright/src/plugins/webServerPlugin.ts
775
776
  var import_net = __toESM(require("net"));
776
777
  var import_path = __toESM(require("path"));
778
+ var import_util = require("util");
777
779
  var colors = require("playwright-core/lib/utilsBundle").colors;
778
780
  var debug2 = require("playwright-core/lib/utilsBundle").debug;
779
781
  var { ManualPromise } = require("playwright-core/lib/coreBundle").iso;
@@ -882,7 +884,7 @@ var WebServerPlugin = class {
882
884
  launchedProcess[stdio].on("data", (data) => {
883
885
  if (!this._options.wait?.[stdio] || stdioWaitCollectors[stdio] === void 0)
884
886
  return;
885
- stdioWaitCollectors[stdio] += data.toString();
887
+ stdioWaitCollectors[stdio] += (0, import_util.stripVTControlCharacters)(data.toString());
886
888
  this._options.wait[stdio].lastIndex = 0;
887
889
  const result = this._options.wait[stdio].exec(stdioWaitCollectors[stdio]);
888
890
  if (result) {
@@ -1004,7 +1006,8 @@ __export(base_exports, {
1004
1006
  terminalScreen: () => terminalScreen
1005
1007
  });
1006
1008
  var import_path2 = __toESM(require("path"));
1007
- var import_util = require("../util");
1009
+ var import_stream = require("stream");
1010
+ var import_util2 = require("../util");
1008
1011
  var realColors = require("playwright-core/lib/utilsBundle").colors;
1009
1012
  var { noColors } = require("playwright-core/lib/coreBundle").iso;
1010
1013
  var { msToString } = require("playwright-core/lib/coreBundle").iso;
@@ -1016,6 +1019,15 @@ var DEFAULT_TTY_WIDTH = 100;
1016
1019
  var DEFAULT_TTY_HEIGHT = 40;
1017
1020
  var originalProcessStdout = process.stdout;
1018
1021
  var originalProcessStderr = process.stderr;
1022
+ var StripAnsiStream = class extends import_stream.Writable {
1023
+ constructor(target) {
1024
+ super();
1025
+ this._target = target;
1026
+ }
1027
+ _write(chunk, encoding, callback) {
1028
+ this._target.write((0, import_util2.stripAnsiEscapes)(chunk.toString()), callback);
1029
+ }
1030
+ };
1019
1031
  var terminalScreen = (() => {
1020
1032
  let isTTY = !!originalProcessStdout.isTTY;
1021
1033
  let ttyWidth = originalProcessStdout.columns || 0;
@@ -1044,7 +1056,7 @@ var terminalScreen = (() => {
1044
1056
  ttyHeight = DEFAULT_TTY_HEIGHT;
1045
1057
  }
1046
1058
  let useColors = isTTY;
1047
- if (process.env.DEBUG_COLORS === "0" || process.env.DEBUG_COLORS === "false" || process.env.FORCE_COLOR === "0" || process.env.FORCE_COLOR === "false")
1059
+ if (process.env.DEBUG_COLORS === "0" || process.env.DEBUG_COLORS === "false" || process.env.FORCE_COLOR === "0" || process.env.FORCE_COLOR === "false" || process.env.NO_COLOR !== void 0 && process.env.NO_COLOR !== "")
1048
1060
  useColors = false;
1049
1061
  else if (process.env.DEBUG_COLORS || process.env.FORCE_COLOR)
1050
1062
  useColors = true;
@@ -1055,8 +1067,8 @@ var terminalScreen = (() => {
1055
1067
  ttyWidth,
1056
1068
  ttyHeight,
1057
1069
  colors: colors7,
1058
- stdout: originalProcessStdout,
1059
- stderr: originalProcessStderr
1070
+ stdout: useColors ? originalProcessStdout : new StripAnsiStream(originalProcessStdout),
1071
+ stderr: useColors ? originalProcessStderr : new StripAnsiStream(originalProcessStderr)
1060
1072
  };
1061
1073
  })();
1062
1074
  var nonTerminalScreen = {
@@ -1444,7 +1456,7 @@ function formatError(screen, error) {
1444
1456
  if (error.snippet) {
1445
1457
  let snippet = error.snippet;
1446
1458
  if (!screen.colors.enabled)
1447
- snippet = (0, import_util.stripAnsiEscapes)(snippet);
1459
+ snippet = (0, import_util2.stripAnsiEscapes)(snippet);
1448
1460
  tokens.push("");
1449
1461
  tokens.push(snippet);
1450
1462
  }
@@ -1464,7 +1476,7 @@ function separator(screen, text = "") {
1464
1476
  if (text)
1465
1477
  text += " ";
1466
1478
  const columns = Math.min(100, screen.ttyWidth || 100);
1467
- return text + screen.colors.dim("\u2500".repeat(Math.max(0, columns - (0, import_util.stripAnsiEscapes)(text).length)));
1479
+ return text + screen.colors.dim("\u2500".repeat(Math.max(0, columns - (0, import_util2.stripAnsiEscapes)(text).length)));
1468
1480
  }
1469
1481
  function indent(lines, tab) {
1470
1482
  return lines.replace(/^(?=.+$)/gm, tab);
@@ -1489,7 +1501,7 @@ function resolveOutputFile(reporterName, options) {
1489
1501
  if (!outputDir && options.outputDir)
1490
1502
  outputDir = import_path2.default.resolve(options.configDir, options.outputDir);
1491
1503
  if (!outputDir && options.default)
1492
- outputDir = (0, import_util.resolveReporterOutputPath)(options.default.outputDir, options.configDir, void 0);
1504
+ outputDir = (0, import_util2.resolveReporterOutputPath)(options.default.outputDir, options.configDir, void 0);
1493
1505
  if (!outputDir)
1494
1506
  outputDir = options.configDir;
1495
1507
  const reportName = process.env[`PLAYWRIGHT_${name}_OUTPUT_NAME`] ?? options.fileName ?? options.default?.fileName;
@@ -1801,7 +1813,7 @@ function addLocationAndSnippetToError(config2, error, file) {
1801
1813
  }
1802
1814
 
1803
1815
  // packages/playwright/src/runner/testRunner.ts
1804
- var import_util13 = require("../util");
1816
+ var import_util14 = require("../util");
1805
1817
 
1806
1818
  // packages/playwright/src/runner/reporters.ts
1807
1819
  var reporters_exports = {};
@@ -1997,7 +2009,7 @@ var InProcessLoaderHost = class {
1997
2009
  return result;
1998
2010
  }
1999
2011
  async stop() {
2000
- await import_common2.esm.incorporateCompilationCache();
2012
+ await import_common2.transform.incorporateCompilationCache();
2001
2013
  }
2002
2014
  };
2003
2015
  var OutOfProcessLoaderHost = class {
@@ -2028,7 +2040,7 @@ var OutOfProcessLoaderHost = class {
2028
2040
  };
2029
2041
 
2030
2042
  // packages/playwright/src/runner/loadUtils.ts
2031
- var import_util4 = require("../util");
2043
+ var import_util5 = require("../util");
2032
2044
 
2033
2045
  // packages/playwright/src/runner/projectUtils.ts
2034
2046
  var projectUtils_exports = {};
@@ -2042,12 +2054,12 @@ __export(projectUtils_exports, {
2042
2054
  });
2043
2055
  var import_fs2 = __toESM(require("fs"));
2044
2056
  var import_path3 = __toESM(require("path"));
2045
- var import_util2 = require("util");
2046
- var import_util3 = require("../util");
2057
+ var import_util3 = require("util");
2058
+ var import_util4 = require("../util");
2047
2059
  var minimatch = require("playwright-core/lib/utilsBundle").minimatch;
2048
2060
  var { escapeRegExp } = require("playwright-core/lib/coreBundle").iso;
2049
- var readFileAsync = (0, import_util2.promisify)(import_fs2.default.readFile);
2050
- var readDirAsync = (0, import_util2.promisify)(import_fs2.default.readdir);
2061
+ var readFileAsync = (0, import_util3.promisify)(import_fs2.default.readFile);
2062
+ var readDirAsync = (0, import_util3.promisify)(import_fs2.default.readdir);
2051
2063
  function wildcardPatternToRegExp(pattern) {
2052
2064
  return new RegExp("^" + pattern.split("*").map(escapeRegExp).join(".*") + "$", "ig");
2053
2065
  }
@@ -2152,8 +2164,8 @@ async function collectFilesForProject(project, fsCache = /* @__PURE__ */ new Map
2152
2164
  const extensions = /* @__PURE__ */ new Set([".js", ".ts", ".mjs", ".mts", ".cjs", ".cts", ".jsx", ".tsx", ".mjsx", ".mtsx", ".cjsx", ".ctsx"]);
2153
2165
  const testFileExtension = (file) => extensions.has(import_path3.default.extname(file));
2154
2166
  const allFiles = await cachedCollectFiles(project.project.testDir, project.respectGitIgnore, fsCache);
2155
- const testMatch = (0, import_util3.createFileMatcher)(project.project.testMatch);
2156
- const testIgnore = (0, import_util3.createFileMatcher)(project.project.testIgnore);
2167
+ const testMatch = (0, import_util4.createFileMatcher)(project.project.testMatch);
2168
+ const testIgnore = (0, import_util4.createFileMatcher)(project.project.testIgnore);
2157
2169
  const testFiles = allFiles.filter((file) => {
2158
2170
  if (!testFileExtension(file))
2159
2171
  return false;
@@ -2473,8 +2485,8 @@ function createProjectSuite(project, fileSuites) {
2473
2485
  const projectSuite = new import_common3.test.Suite(project.project.name, "project");
2474
2486
  for (const fileSuite of fileSuites)
2475
2487
  projectSuite._addSuite(import_common3.suiteUtils.bindFileSuiteToProject(project, fileSuite));
2476
- const grepMatcher = (0, import_util4.createTitleMatcher)(project.project.grep);
2477
- const grepInvertMatcher = project.project.grepInvert ? (0, import_util4.createTitleMatcher)(project.project.grepInvert) : null;
2488
+ const grepMatcher = (0, import_util5.createTitleMatcher)(project.project.grep);
2489
+ const grepInvertMatcher = project.project.grepInvert ? (0, import_util5.createTitleMatcher)(project.project.grepInvert) : null;
2478
2490
  import_common3.suiteUtils.filterTestsRemoveEmptySuites(projectSuite, (test) => {
2479
2491
  const grepTitle = test._grepTitleWithTags();
2480
2492
  if (grepInvertMatcher?.(grepTitle))
@@ -2546,7 +2558,7 @@ async function requireOrImportDefaultFunction(file, expectConstructor) {
2546
2558
  if (func && typeof func === "object" && "default" in func)
2547
2559
  func = func["default"];
2548
2560
  if (typeof func !== "function")
2549
- throw (0, import_util4.errorWithFile)(file, `file must export a single ${expectConstructor ? "class" : "function"}.`);
2561
+ throw (0, import_util5.errorWithFile)(file, `file must export a single ${expectConstructor ? "class" : "function"}.`);
2550
2562
  return func;
2551
2563
  }
2552
2564
  function loadGlobalHook(config2, file) {
@@ -2585,7 +2597,7 @@ async function loadTestList(config2, filePath) {
2585
2597
  project = tokens[0].substring(1, tokens[0].length - 1);
2586
2598
  tokens.shift();
2587
2599
  }
2588
- return { project, file: toPosixPath((0, import_util4.parseLocationArg)(tokens[0]).file), titlePath: tokens.slice(1) };
2600
+ return { project, file: toPosixPath((0, import_util5.parseLocationArg)(tokens[0]).file), titlePath: tokens.slice(1) };
2589
2601
  });
2590
2602
  const testFilter = (test) => descriptions.some((d) => {
2591
2603
  const [projectName, , ...titles] = test.titlePath();
@@ -2602,14 +2614,14 @@ async function loadTestList(config2, filePath) {
2602
2614
  };
2603
2615
  return { testFilter, fileFilter };
2604
2616
  } catch (e) {
2605
- throw (0, import_util4.errorWithFile)(filePath, "Cannot read test list file: " + e.message);
2617
+ throw (0, import_util5.errorWithFile)(filePath, "Cannot read test list file: " + e.message);
2606
2618
  }
2607
2619
  }
2608
2620
 
2609
2621
  // packages/playwright/src/reporters/blob.ts
2610
2622
  var import_fs4 = __toESM(require("fs"));
2611
2623
  var import_path6 = __toESM(require("path"));
2612
- var import_stream = require("stream");
2624
+ var import_stream2 = require("stream");
2613
2625
  var import_coreBundle = require("playwright-core/lib/coreBundle");
2614
2626
 
2615
2627
  // packages/playwright/src/reporters/teleEmitter.ts
@@ -2762,7 +2774,8 @@ var TeleReporterEmitter = class {
2762
2774
  globalSetup: config2.globalSetup,
2763
2775
  globalTeardown: config2.globalTeardown,
2764
2776
  tags: config2.tags,
2765
- webServer: config2.webServer
2777
+ webServer: config2.webServer,
2778
+ failOnFlakyTests: config2.failOnFlakyTests
2766
2779
  };
2767
2780
  }
2768
2781
  _serializeProject(suite) {
@@ -2955,7 +2968,7 @@ var BlobReporter = class extends TeleReporterEmitter {
2955
2968
  zipFile.addFile(originalPath, zipEntryPath);
2956
2969
  }
2957
2970
  const lines = this._messages.map((m) => JSON.stringify(m) + "\n");
2958
- const content = import_stream.Readable.from(lines);
2971
+ const content = import_stream2.Readable.from(lines);
2959
2972
  zipFile.addReadStream(content, "report.jsonl");
2960
2973
  zipFile.end();
2961
2974
  await finishPromise;
@@ -3089,14 +3102,14 @@ var empty_default = EmptyReporter;
3089
3102
 
3090
3103
  // packages/playwright/src/reporters/github.ts
3091
3104
  var import_path7 = __toESM(require("path"));
3092
- var import_util5 = require("../util");
3105
+ var import_util6 = require("../util");
3093
3106
  var { noColors: noColors2 } = require("playwright-core/lib/coreBundle").iso;
3094
3107
  var { msToString: msToString2 } = require("playwright-core/lib/coreBundle").iso;
3095
3108
  var GitHubLogger = class {
3096
3109
  _log(message, type = "notice", options = {}) {
3097
3110
  message = message.replace(/\n/g, "%0A");
3098
3111
  const configs = Object.entries(options).map(([key, option]) => `${key}=${option}`).join(",");
3099
- process.stdout.write((0, import_util5.stripAnsiEscapes)(`::${type} ${configs}::${message}
3112
+ process.stdout.write((0, import_util6.stripAnsiEscapes)(`::${type} ${configs}::${message}
3100
3113
  `));
3101
3114
  }
3102
3115
  debug(message, options) {
@@ -3203,9 +3216,9 @@ __export(html_exports, {
3203
3216
  var import_fs5 = __toESM(require("fs"));
3204
3217
  var import_os = __toESM(require("os"));
3205
3218
  var import_path8 = __toESM(require("path"));
3206
- var import_stream2 = require("stream");
3219
+ var import_stream3 = require("stream");
3207
3220
  var babel2 = __toESM(require("../transform/babelBundle"));
3208
- var import_util6 = require("../util");
3221
+ var import_util7 = require("../util");
3209
3222
  var colors2 = require("playwright-core/lib/utilsBundle").colors;
3210
3223
  var mime2 = require("playwright-core/lib/utilsBundle").mime;
3211
3224
  var open = require("playwright-core/lib/utilsBundle").open;
@@ -3263,7 +3276,7 @@ var HtmlReporter = class {
3263
3276
  this.suite = suite;
3264
3277
  }
3265
3278
  _resolveOptions() {
3266
- const outputFolder = reportFolderFromEnv() ?? (0, import_util6.resolveReporterOutputPath)("playwright-report", this._options.configDir, this._options.outputFolder);
3279
+ const outputFolder = reportFolderFromEnv() ?? (0, import_util7.resolveReporterOutputPath)("playwright-report", this._options.configDir, this._options.outputFolder);
3267
3280
  return {
3268
3281
  outputFolder,
3269
3282
  open: getHtmlReportOptionProcessEnv() || this._options.open || "on-failure",
@@ -3343,7 +3356,7 @@ function parseBooleanEnvVar(name) {
3343
3356
  return void 0;
3344
3357
  }
3345
3358
  function standaloneDefaultFolder() {
3346
- return reportFolderFromEnv() ?? (0, import_util6.resolveReporterOutputPath)("playwright-report", process.cwd(), void 0);
3359
+ return reportFolderFromEnv() ?? (0, import_util7.resolveReporterOutputPath)("playwright-report", process.cwd(), void 0);
3347
3360
  }
3348
3361
  async function resolveReportFolder(reportPath) {
3349
3362
  const stat = await import_fs5.default.promises.stat(reportPath).catch(() => null);
@@ -3520,9 +3533,9 @@ var HtmlBuilder = class {
3520
3533
  }
3521
3534
  async _writeReportData(filePath) {
3522
3535
  import_fs5.default.appendFileSync(filePath, '<template id="playwrightReportBase64">data:application/zip;base64,');
3523
- await new Promise((f) => {
3536
+ await new Promise((resolve, reject) => {
3524
3537
  this._dataZipFile.end(void 0, () => {
3525
- this._dataZipFile.outputStream.pipe(new Base64Encoder()).pipe(import_fs5.default.createWriteStream(filePath, { flags: "a" })).on("close", f);
3538
+ this._dataZipFile.outputStream.pipe(new Base64Encoder()).pipe(import_fs5.default.createWriteStream(filePath, { flags: "a" })).on("close", resolve).on("error", reject);
3526
3539
  });
3527
3540
  });
3528
3541
  import_fs5.default.appendFileSync(filePath, "</template>");
@@ -3608,10 +3621,10 @@ var HtmlBuilder = class {
3608
3621
  this._hasTraces = true;
3609
3622
  if ((a.name === "stdout" || a.name === "stderr") && a.contentType === "text/plain") {
3610
3623
  if (lastAttachment && lastAttachment.name === a.name && lastAttachment.contentType === a.contentType) {
3611
- lastAttachment.body += (0, import_util6.stripAnsiEscapes)(a.body);
3624
+ lastAttachment.body += (0, import_util7.stripAnsiEscapes)(a.body);
3612
3625
  return null;
3613
3626
  }
3614
- a.body = (0, import_util6.stripAnsiEscapes)(a.body);
3627
+ a.body = (0, import_util7.stripAnsiEscapes)(a.body);
3615
3628
  lastAttachment = a;
3616
3629
  return a;
3617
3630
  }
@@ -3751,7 +3764,7 @@ var addStats = (stats, delta) => {
3751
3764
  stats.ok = stats.ok && delta.ok;
3752
3765
  return stats;
3753
3766
  };
3754
- var Base64Encoder = class extends import_stream2.Transform {
3767
+ var Base64Encoder = class extends import_stream3.Transform {
3755
3768
  _transform(chunk, encoding, callback) {
3756
3769
  if (this._remainder) {
3757
3770
  chunk = Buffer.concat([this._remainder, chunk]);
@@ -3842,7 +3855,7 @@ function createErrorCodeframe(message, location) {
3842
3855
  highlightCode: false,
3843
3856
  linesAbove: 100,
3844
3857
  linesBelow: 100,
3845
- message: (0, import_util6.stripAnsiEscapes)(message).split("\n")[0] || void 0
3858
+ message: (0, import_util7.stripAnsiEscapes)(message).split("\n")[0] || void 0
3846
3859
  }
3847
3860
  );
3848
3861
  }
@@ -4072,7 +4085,7 @@ var json_default = JSONReporter;
4072
4085
  // packages/playwright/src/reporters/junit.ts
4073
4086
  var import_fs7 = __toESM(require("fs"));
4074
4087
  var import_path10 = __toESM(require("path"));
4075
- var import_util7 = require("../util");
4088
+ var import_util8 = require("../util");
4076
4089
  var { getAsBooleanFromENV } = require("playwright-core/lib/coreBundle").utils;
4077
4090
  var JUnitReporter = class {
4078
4091
  constructor(options) {
@@ -4238,7 +4251,7 @@ var JUnitReporter = class {
4238
4251
  entry.children.push({
4239
4252
  name: errorInfo.elementName,
4240
4253
  attributes: { message: errorInfo.message, type: errorInfo.type },
4241
- text: (0, import_util7.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test))
4254
+ text: (0, import_util8.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test))
4242
4255
  });
4243
4256
  return errorInfo.elementName;
4244
4257
  }
@@ -4248,7 +4261,7 @@ var JUnitReporter = class {
4248
4261
  message: `${import_path10.default.basename(test.location.file)}:${test.location.line}:${test.location.column} ${test.title}`,
4249
4262
  type: "FAILURE"
4250
4263
  },
4251
- text: (0, import_util7.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test))
4264
+ text: (0, import_util8.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test))
4252
4265
  });
4253
4266
  return "failure";
4254
4267
  }
@@ -4295,7 +4308,7 @@ Warning: attachment ${attachmentPath} is missing`);
4295
4308
  children: []
4296
4309
  };
4297
4310
  const stackTrace = result.error?.stack || result.error?.message || result.error?.value || "";
4298
- entry.children.push({ name: "stackTrace", text: (0, import_util7.stripAnsiEscapes)(stackTrace) });
4311
+ entry.children.push({ name: "stackTrace", text: (0, import_util8.stripAnsiEscapes)(stackTrace) });
4299
4312
  await this._appendStdIO(entry, [result]);
4300
4313
  return entry;
4301
4314
  }
@@ -4304,7 +4317,7 @@ function classifyResultError(result) {
4304
4317
  const error = result.error;
4305
4318
  if (!error)
4306
4319
  return null;
4307
- const rawMessage = (0, import_util7.stripAnsiEscapes)(error.message || error.value || "");
4320
+ const rawMessage = (0, import_util8.stripAnsiEscapes)(error.message || error.value || "");
4308
4321
  const nameMatch = rawMessage.match(/^(\w+): /);
4309
4322
  const errorName = nameMatch ? nameMatch[1] : "";
4310
4323
  const messageBody = nameMatch ? rawMessage.slice(nameMatch[0].length) : rawMessage;
@@ -4346,7 +4359,7 @@ function serializeXML(entry, tokens, stripANSIControlSequences) {
4346
4359
  var discouragedXMLCharacters = /[\u0000-\u0008\u000b-\u000c\u000e-\u001f\u007f-\u0084\u0086-\u009f]/g;
4347
4360
  function escape(text, stripANSIControlSequences, isCharacterData) {
4348
4361
  if (stripANSIControlSequences)
4349
- text = (0, import_util7.stripAnsiEscapes)(text);
4362
+ text = (0, import_util8.stripAnsiEscapes)(text);
4350
4363
  if (isCharacterData) {
4351
4364
  text = "<![CDATA[" + text.replace(/]]>/g, "]]&gt;") + "]]>";
4352
4365
  } else {
@@ -4468,7 +4481,7 @@ var LineReporter = class extends TerminalReporter {
4468
4481
  var line_default = LineReporter;
4469
4482
 
4470
4483
  // packages/playwright/src/reporters/list.ts
4471
- var import_util8 = require("../util");
4484
+ var import_util9 = require("../util");
4472
4485
  var { msToString: msToString3 } = require("playwright-core/lib/coreBundle").iso;
4473
4486
  var { getAsBooleanFromENV: getAsBooleanFromENV2 } = require("playwright-core/lib/coreBundle").utils;
4474
4487
  var DOES_NOT_SUPPORT_UTF8_IN_TERMINAL = process.platform === "win32" && process.env.TERM_PROGRAM !== "vscode" && !process.env.WT_SESSION;
@@ -4484,8 +4497,10 @@ var ListReporter = class extends TerminalReporter {
4484
4497
  this._resultIndex = /* @__PURE__ */ new Map();
4485
4498
  this._stepIndex = /* @__PURE__ */ new Map();
4486
4499
  this._needNewLine = false;
4500
+ this._failureIndex = 0;
4487
4501
  this._paused = /* @__PURE__ */ new Set();
4488
4502
  this._printSteps = getAsBooleanFromENV2("PLAYWRIGHT_LIST_PRINT_STEPS", options?.printSteps);
4503
+ this._printFailuresInline = getAsBooleanFromENV2("PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE", options?.printFailuresInline);
4489
4504
  }
4490
4505
  onBegin(suite) {
4491
4506
  super.onBegin(suite);
@@ -4612,6 +4627,15 @@ var ListReporter = class extends TerminalReporter {
4612
4627
  const wasPaused = this._paused.delete(result);
4613
4628
  if (!wasPaused)
4614
4629
  this._updateTestLine(test, result);
4630
+ const isFailure = result.status !== "skipped" && result.status !== test.expectedStatus;
4631
+ if (!wasPaused && this._printFailuresInline && isFailure)
4632
+ this._printFailure(test);
4633
+ }
4634
+ _printFailure(test) {
4635
+ this._maybeWriteNewLine();
4636
+ const message = "\n" + this.formatFailure(test, ++this._failureIndex) + "\n";
4637
+ this._updateLineCountAndNewLineFlagForOutput(message);
4638
+ this.screen.stdout.write(message);
4615
4639
  }
4616
4640
  _updateTestLine(test, result) {
4617
4641
  const title = this.formatTestTitle(test);
@@ -4675,7 +4699,7 @@ var ListReporter = class extends TerminalReporter {
4675
4699
  this.screen.stdout.write(`\x1B[${this._lastRow - row}E`);
4676
4700
  }
4677
4701
  _testPrefix(index, statusMark) {
4678
- const statusMarkLength = (0, import_util8.stripAnsiEscapes)(statusMark).length;
4702
+ const statusMarkLength = (0, import_util9.stripAnsiEscapes)(statusMark).length;
4679
4703
  const indexLength = Math.ceil(Math.log10(this.totalTestCount + 1));
4680
4704
  return " " + statusMark + " ".repeat(3 - statusMarkLength) + this.screen.colors.dim(index.padStart(indexLength) + " ");
4681
4705
  }
@@ -4692,7 +4716,7 @@ var ListReporter = class extends TerminalReporter {
4692
4716
  async onEnd(result) {
4693
4717
  await super.onEnd(result);
4694
4718
  this.screen.stdout.write("\n");
4695
- this.epilogue(true);
4719
+ this.epilogue(!this._printFailuresInline);
4696
4720
  }
4697
4721
  };
4698
4722
  var lastStepOrdinalSymbol = Symbol("lastStepOrdinal");
@@ -5130,7 +5154,7 @@ function computeCommandHash(config2, runOptions) {
5130
5154
  // packages/playwright/src/runner/tasks.ts
5131
5155
  var import_fs11 = __toESM(require("fs"));
5132
5156
  var import_path15 = __toESM(require("path"));
5133
- var import_util11 = require("util");
5157
+ var import_util12 = require("util");
5134
5158
 
5135
5159
  // packages/playwright/src/runner/rebase.ts
5136
5160
  var import_fs9 = __toESM(require("fs"));
@@ -5354,7 +5378,7 @@ var WorkerHost = class extends ProcessHost {
5354
5378
 
5355
5379
  // packages/playwright/src/runner/dispatcher.ts
5356
5380
  var import_common6 = require("../common");
5357
- var import_util9 = require("../util");
5381
+ var import_util10 = require("../util");
5358
5382
  var colors4 = require("playwright-core/lib/utilsBundle").colors;
5359
5383
  var { ManualPromise: ManualPromise3 } = require("playwright-core/lib/coreBundle").iso;
5360
5384
  var { eventsHelper } = require("playwright-core/lib/coreBundle").utils;
@@ -5807,7 +5831,7 @@ var JobDispatcher = class {
5807
5831
  addLocationAndSnippetToError(this._testRun.config.config, response.error);
5808
5832
  return response;
5809
5833
  } catch (e) {
5810
- const error = (0, import_util9.serializeError)(e);
5834
+ const error = (0, import_util10.serializeError)(e);
5811
5835
  addLocationAndSnippetToError(this._testRun.config.config, error);
5812
5836
  return { response: void 0, error };
5813
5837
  }
@@ -5926,7 +5950,7 @@ var FixedNodeSIGINTHandler = class {
5926
5950
  };
5927
5951
 
5928
5952
  // packages/playwright/src/runner/taskRunner.ts
5929
- var import_util10 = require("../util");
5953
+ var import_util11 = require("../util");
5930
5954
  var colors5 = require("playwright-core/lib/utilsBundle").colors;
5931
5955
  var debug4 = require("playwright-core/lib/utilsBundle").debug;
5932
5956
  var { ManualPromise: ManualPromise4 } = require("playwright-core/lib/coreBundle").iso;
@@ -5967,7 +5991,7 @@ var TaskRunner = class _TaskRunner {
5967
5991
  await task.setup?.(context, errors, softErrors);
5968
5992
  } catch (e) {
5969
5993
  debug4("pw:test:task")(`error in "${task.title}": `, e);
5970
- errors.push((0, import_util10.serializeError)(e));
5994
+ errors.push((0, import_util11.serializeError)(e));
5971
5995
  } finally {
5972
5996
  for (const error of [...softErrors, ...errors])
5973
5997
  this._reporter.onError?.(error);
@@ -6067,12 +6091,12 @@ async function detectChangedTestFiles(baseCommit, configDir) {
6067
6091
 
6068
6092
  // packages/playwright/src/runner/tasks.ts
6069
6093
  var import_common8 = require("../common");
6070
- var import_util12 = require("../util");
6094
+ var import_util13 = require("../util");
6071
6095
  var debug5 = require("playwright-core/lib/utilsBundle").debug;
6072
6096
  var { ManualPromise: ManualPromise5 } = require("playwright-core/lib/coreBundle").iso;
6073
6097
  var { monotonicTime: monotonicTime6 } = require("playwright-core/lib/coreBundle").iso;
6074
6098
  var { removeFolders: removeFolders4 } = require("playwright-core/lib/coreBundle").utils;
6075
- var readDirAsync2 = (0, import_util11.promisify)(import_fs11.default.readdir);
6099
+ var readDirAsync2 = (0, import_util12.promisify)(import_fs11.default.readdir);
6076
6100
  var TestRun = class {
6077
6101
  constructor(config2, reporter, options) {
6078
6102
  this.rootSuite = void 0;
@@ -6100,7 +6124,7 @@ var TestRun = class {
6100
6124
  result() {
6101
6125
  const hasFailedTests = this.rootSuite?.allTests().some((test) => !test.ok());
6102
6126
  const hasFlakyTests = this.rootSuite?.allTests().some((test) => test.outcome() === "flaky");
6103
- return this.hasWorkerErrors || this.hasReachedMaxFailures() || hasFailedTests || this.config.failOnFlakyTests && hasFlakyTests ? "failed" : "passed";
6127
+ return this.hasWorkerErrors || this.hasReachedMaxFailures() || hasFailedTests || this.config.config.failOnFlakyTests && hasFlakyTests ? "failed" : "passed";
6104
6128
  }
6105
6129
  };
6106
6130
  async function runTasks(testRun, tasks, globalTimeout, cancelPromise) {
@@ -6149,7 +6173,7 @@ function createClearCacheTask(config2) {
6149
6173
  return {
6150
6174
  title: "clear cache",
6151
6175
  setup: async () => {
6152
- await (0, import_util12.removeDirAndLogToConsole)(import_common8.cc.cacheDir);
6176
+ await (0, import_util13.removeDirAndLogToConsole)(import_common8.cc.cacheDir);
6153
6177
  for (const plugin of config2.plugins)
6154
6178
  await plugin.instance?.clearCache?.();
6155
6179
  }
@@ -6282,8 +6306,8 @@ function createLoadTask(mode, options) {
6282
6306
  testRun.preOnlyTestFilters.push((test) => !testFilter(test));
6283
6307
  }
6284
6308
  if (testRun.options.grep || testRun.options.grepInvert) {
6285
- const grepMatcher = testRun.options.grep ? (0, import_util12.createTitleMatcher)((0, import_util12.forceRegExp)(testRun.options.grep)) : () => true;
6286
- const grepInvertMatcher = testRun.options.grepInvert ? (0, import_util12.createTitleMatcher)((0, import_util12.forceRegExp)(testRun.options.grepInvert)) : () => false;
6309
+ const grepMatcher = testRun.options.grep ? (0, import_util13.createTitleMatcher)((0, import_util13.forceRegExp)(testRun.options.grep)) : () => true;
6310
+ const grepInvertMatcher = testRun.options.grepInvert ? (0, import_util13.createTitleMatcher)((0, import_util13.forceRegExp)(testRun.options.grepInvert)) : () => false;
6287
6311
  testRun.preOnlyTestFilters.push((test) => {
6288
6312
  const grepTitle = test._grepTitleWithTags();
6289
6313
  return !grepInvertMatcher(grepTitle) && grepMatcher(grepTitle);
@@ -6421,11 +6445,16 @@ function createRunTestsTask() {
6421
6445
  var import_fs12 = __toESM(require("fs"));
6422
6446
  var import_path16 = __toESM(require("path"));
6423
6447
  var LastRunReporter = class {
6424
- constructor(filteredProjects, listMode) {
6448
+ constructor(filteredProjects, listMode, lastFailedFileOverride) {
6425
6449
  this._listMode = !!listMode;
6426
- const [project] = filteredProjects;
6427
- if (project)
6428
- this._lastRunFile = import_path16.default.join(project.project.outputDir, ".last-run.json");
6450
+ const override = lastFailedFileOverride ?? process.env.PLAYWRIGHT_LAST_RUN_OUTPUT_FILE;
6451
+ if (override) {
6452
+ this._lastRunFile = import_path16.default.resolve(process.cwd(), override);
6453
+ } else {
6454
+ const [project] = filteredProjects;
6455
+ if (project)
6456
+ this._lastRunFile = import_path16.default.join(project.project.outputDir, ".last-run.json");
6457
+ }
6429
6458
  }
6430
6459
  async filterLastFailed() {
6431
6460
  if (!this._lastRunFile)
@@ -6649,7 +6678,8 @@ var TestRunner = class extends import_events2.default {
6649
6678
  },
6650
6679
  ...params.updateSnapshots ? { updateSnapshots: params.updateSnapshots } : {},
6651
6680
  ...params.updateSourceMethod ? { updateSourceMethod: params.updateSourceMethod } : {},
6652
- ...params.workers ? { workers: params.workers } : {}
6681
+ ...params.workers ? { workers: params.workers } : {},
6682
+ ...params.maxFailures ? { maxFailures: params.maxFailures } : {}
6653
6683
  };
6654
6684
  const config2 = await this._loadConfigOrReportError(new InternalReporter([userReporter]), overrides);
6655
6685
  if (!config2)
@@ -6727,11 +6757,15 @@ var TestRunner = class extends import_events2.default {
6727
6757
  } else {
6728
6758
  config2.plugins.splice(0, config2.plugins.length, ...this._plugins);
6729
6759
  }
6760
+ this._lastLoadedConfig = config2;
6730
6761
  return { config: config2 };
6731
6762
  } catch (e) {
6732
- return { config: null, error: (0, import_util13.serializeError)(e) };
6763
+ return { config: null, error: (0, import_util14.serializeError)(e) };
6733
6764
  }
6734
6765
  }
6766
+ lastLoadedConfig() {
6767
+ return this._lastLoadedConfig;
6768
+ }
6735
6769
  async _loadConfigOrReportError(reporter, overrides) {
6736
6770
  const { config: config2, error } = await this._loadConfig(overrides);
6737
6771
  if (config2)
@@ -6764,7 +6798,7 @@ async function runAllTestsWithConfig(config2, options) {
6764
6798
  webServerPluginsForConfig(config2).forEach((p) => config2.plugins.push({ factory: p }));
6765
6799
  const filteredProjects = filterProjects(config2.projects, options.projectFilter);
6766
6800
  const reporters = await createReporters(config2, options.listMode ? "list" : "test", void 0, options);
6767
- const lastRun = new LastRunReporter(filteredProjects, options.listMode);
6801
+ const lastRun = new LastRunReporter(filteredProjects, options.listMode, options.lastFailedFile);
6768
6802
  if (options.lastFailed) {
6769
6803
  const lastFailedTestIds = await lastRun.filterLastFailed();
6770
6804
  if (lastFailedTestIds.length)
@@ -6794,7 +6828,7 @@ __export(testServer_exports, {
6794
6828
  runTestServer: () => runTestServer,
6795
6829
  runUIMode: () => runUIMode
6796
6830
  });
6797
- var import_util14 = __toESM(require("util"));
6831
+ var import_util15 = __toESM(require("util"));
6798
6832
  var import_coreBundle3 = require("playwright-core/lib/coreBundle");
6799
6833
  var import_common10 = require("../common");
6800
6834
 
@@ -6824,7 +6858,23 @@ var TestServer = class {
6824
6858
  }
6825
6859
  async start(options) {
6826
6860
  this._dispatcher = new TestServerDispatcher(this._configLocation, this._configCLIOverrides);
6827
- return await import_coreBundle3.server.startTraceViewerServer({ ...options, transport: this._dispatcher.transport });
6861
+ return await import_coreBundle3.server.startTraceViewerServer({
6862
+ host: options.host,
6863
+ port: options.port,
6864
+ allowedFileRoots: () => this._allowedFileRoots(),
6865
+ transport: this._dispatcher.transport
6866
+ });
6867
+ }
6868
+ _allowedFileRoots() {
6869
+ const roots = /* @__PURE__ */ new Set([process.cwd(), this._configLocation.configDir]);
6870
+ const config2 = this._dispatcher?._testRunner.lastLoadedConfig();
6871
+ if (config2) {
6872
+ for (const project of config2.projects) {
6873
+ roots.add(project.project.outputDir);
6874
+ roots.add(project.project.testDir);
6875
+ }
6876
+ }
6877
+ return [...roots];
6828
6878
  }
6829
6879
  async stop() {
6830
6880
  await this._dispatcher?.stop();
@@ -6938,7 +6988,7 @@ var TestServerDispatcher = class {
6938
6988
  if (interceptStdio) {
6939
6989
  if (debug6.log === originalDebugLog) {
6940
6990
  debug6.log = (...args) => {
6941
- const string = import_util14.default.format(...args) + "\n";
6991
+ const string = import_util15.default.format(...args) + "\n";
6942
6992
  return originalStderrWrite.apply(process.stderr, [string]);
6943
6993
  };
6944
6994
  }
@@ -7033,7 +7083,7 @@ __export(watchMode_exports, {
7033
7083
  });
7034
7084
  var import_path18 = __toESM(require("path"));
7035
7085
  var import_readline = __toESM(require("readline"));
7036
- var import_stream3 = require("stream");
7086
+ var import_events3 = require("events");
7037
7087
  var import_coreBundle4 = require("playwright-core/lib/coreBundle");
7038
7088
 
7039
7089
  // packages/playwright/src/isomorphic/testTree.ts
@@ -7380,7 +7430,7 @@ var { ManualPromise: ManualPromise8 } = require("playwright-core/lib/coreBundle"
7380
7430
  var { createGuid: createGuid3 } = require("playwright-core/lib/coreBundle").utils;
7381
7431
  var { getPackageManagerExecCommand: getPackageManagerExecCommand3 } = require("playwright-core/lib/coreBundle").utils;
7382
7432
  var { eventsHelper: eventsHelper2 } = require("playwright-core/lib/coreBundle").utils;
7383
- var InMemoryTransport = class extends import_stream3.EventEmitter {
7433
+ var InMemoryTransport = class extends import_events3.EventEmitter {
7384
7434
  constructor(send) {
7385
7435
  super();
7386
7436
  this._send = send;
@@ -7780,7 +7830,7 @@ var JsonStringInternalizer = class {
7780
7830
  };
7781
7831
 
7782
7832
  // packages/playwright/src/reporters/merge.ts
7783
- var import_util15 = require("../util");
7833
+ var import_util16 = require("../util");
7784
7834
  var { isPathInside } = require("playwright-core/lib/coreBundle").utils;
7785
7835
  var { ZipFile } = require("playwright-core/lib/coreBundle").utils;
7786
7836
  async function createMergedReport(config2, dir, reporterDescriptions, rootDirOverride) {
@@ -7875,7 +7925,7 @@ async function extractAndParseReports(dir, shardFiles, internalizer, printStatus
7875
7925
  const reportNames = new UniqueFileNameGenerator();
7876
7926
  for (const file of shardFiles) {
7877
7927
  const absolutePath = import_path19.default.join(dir, file);
7878
- printStatus(`extracting: ${(0, import_util15.relativeFilePath)(absolutePath)}`);
7928
+ printStatus(`extracting: ${(0, import_util16.relativeFilePath)(absolutePath)}`);
7879
7929
  const zipFile = new ZipFile(absolutePath);
7880
7930
  const entryNames = await zipFile.entries();
7881
7931
  for (const entryName of entryNames.sort()) {