@smoothdeploy/playwright 1.60.1 → 1.62.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.
- package/lib/agents/copilot-setup-steps.yml +2 -2
- package/lib/agents/generateAgents.js +48 -0
- package/lib/cli/reportActions.js +2 -2
- package/lib/cli/testActions.js +2 -0
- package/lib/common/index.js +246 -187
- package/lib/common/index.js.txt +13 -14
- package/lib/errorContext.js +2 -3
- package/lib/index.js +48 -21
- package/lib/loader/loaderProcessEntry.js +1 -1
- package/lib/matchers/expect.js +4830 -4394
- package/lib/matchers/expect.js.LICENSE +87 -140
- package/lib/matchers/expect.js.txt +30 -35
- package/lib/mcp/test/testContext.js +5 -1
- package/lib/program.js +28 -3
- package/lib/runner/index.js +400 -194
- package/lib/runner/index.js.txt +19 -18
- package/lib/transform/babelBundle.js +12899 -11654
- package/lib/transform/babelBundle.js.LICENSE +379 -354
- package/lib/transform/babelBundle.js.txt +39 -39
- package/lib/transform/esmLoader.js +3275 -1154
- package/lib/transform/esmLoader.js.LICENSE +81 -61
- package/lib/transform/esmLoader.js.txt +23 -18
- package/lib/util.js +14 -44
- package/lib/worker/workerProcessEntry.js +60 -1461
- package/lib/worker/workerProcessEntry.js.txt +8 -13
- package/package.json +3 -6
- package/types/test.d.ts +458 -21
- package/types/testReporter.d.ts +79 -4
package/lib/runner/index.js
CHANGED
|
@@ -56,7 +56,7 @@ var import_events2 = __toESM(require("events"));
|
|
|
56
56
|
var import_fs13 = __toESM(require("fs"));
|
|
57
57
|
var import_path17 = __toESM(require("path"));
|
|
58
58
|
var import_coreBundle2 = require("playwright-core/lib/coreBundle");
|
|
59
|
-
var
|
|
59
|
+
var import_common10 = require("../common");
|
|
60
60
|
|
|
61
61
|
// packages/playwright/src/runner/fsWatcher.ts
|
|
62
62
|
var chokidar = require("playwright-core/lib/utilsBundle").chokidar;
|
|
@@ -432,6 +432,18 @@ var TeleSuite = class {
|
|
|
432
432
|
suite.parent = this;
|
|
433
433
|
this._entries.push(suite);
|
|
434
434
|
}
|
|
435
|
+
skip(_reason) {
|
|
436
|
+
throw new Error("Disposition methods are not supported on a TeleSuite (read-only).");
|
|
437
|
+
}
|
|
438
|
+
fixme(_reason) {
|
|
439
|
+
throw new Error("Disposition methods are not supported on a TeleSuite (read-only).");
|
|
440
|
+
}
|
|
441
|
+
fail(_reason) {
|
|
442
|
+
throw new Error("Disposition methods are not supported on a TeleSuite (read-only).");
|
|
443
|
+
}
|
|
444
|
+
exclude() {
|
|
445
|
+
throw new Error("Disposition methods are not supported on a TeleSuite (read-only).");
|
|
446
|
+
}
|
|
435
447
|
};
|
|
436
448
|
var TeleTestCase = class {
|
|
437
449
|
constructor(id, title, location, repeatEachIndex) {
|
|
@@ -467,6 +479,18 @@ var TeleTestCase = class {
|
|
|
467
479
|
this.results.push(result);
|
|
468
480
|
return result;
|
|
469
481
|
}
|
|
482
|
+
skip(_reason) {
|
|
483
|
+
throw new Error("Disposition methods are not supported on a TeleTestCase (read-only).");
|
|
484
|
+
}
|
|
485
|
+
fixme(_reason) {
|
|
486
|
+
throw new Error("Disposition methods are not supported on a TeleTestCase (read-only).");
|
|
487
|
+
}
|
|
488
|
+
fail(_reason) {
|
|
489
|
+
throw new Error("Disposition methods are not supported on a TeleTestCase (read-only).");
|
|
490
|
+
}
|
|
491
|
+
exclude() {
|
|
492
|
+
throw new Error("Disposition methods are not supported on a TeleTestCase (read-only).");
|
|
493
|
+
}
|
|
470
494
|
};
|
|
471
495
|
var TeleTestStep = class {
|
|
472
496
|
constructor(payload, parentStep, location, result) {
|
|
@@ -525,6 +549,8 @@ var TeleTestResult = class {
|
|
|
525
549
|
}
|
|
526
550
|
};
|
|
527
551
|
var baseFullConfig = {
|
|
552
|
+
argv: [],
|
|
553
|
+
failOnFlakyTests: false,
|
|
528
554
|
forbidOnly: false,
|
|
529
555
|
fullyParallel: false,
|
|
530
556
|
globalSetup: null,
|
|
@@ -704,15 +730,14 @@ async function gitCommitInfo(gitDir) {
|
|
|
704
730
|
// committer name
|
|
705
731
|
"%ce",
|
|
706
732
|
// committer email
|
|
707
|
-
"%ct"
|
|
733
|
+
"%ct"
|
|
708
734
|
// committer date, UNIX timestamp
|
|
709
|
-
""
|
|
710
|
-
// branch
|
|
711
735
|
];
|
|
712
|
-
const
|
|
713
|
-
if (!
|
|
736
|
+
const logOutput = await runGit(["log", "-1", `--pretty=format:${tokens.join(separator2)}`], gitDir);
|
|
737
|
+
if (!logOutput)
|
|
714
738
|
return void 0;
|
|
715
|
-
const
|
|
739
|
+
const branchOutput = await runGit(["rev-parse", "--abbrev-ref", "HEAD"], gitDir);
|
|
740
|
+
const [hash, shortHash, subject, body, authorName, authorEmail, authorTime, committerName, committerEmail, committerTime] = logOutput.split(separator2);
|
|
716
741
|
return {
|
|
717
742
|
shortHash,
|
|
718
743
|
hash,
|
|
@@ -728,38 +753,38 @@ async function gitCommitInfo(gitDir) {
|
|
|
728
753
|
email: committerEmail,
|
|
729
754
|
time: +committerTime * 1e3
|
|
730
755
|
},
|
|
731
|
-
branch:
|
|
756
|
+
branch: branchOutput?.trim() ?? ""
|
|
732
757
|
};
|
|
733
758
|
}
|
|
734
759
|
async function gitDiff(gitDir, ci) {
|
|
735
760
|
const diffLimit = 1e5;
|
|
736
761
|
if (ci?.prBaseHash) {
|
|
737
|
-
await runGit(
|
|
738
|
-
const diff3 = await runGit(
|
|
762
|
+
await runGit(["fetch", "origin", ci.prBaseHash, "--depth=1", "--no-auto-maintenance", "--no-auto-gc", "--no-tags", "--no-recurse-submodules"], gitDir);
|
|
763
|
+
const diff3 = await runGit(["diff", ci.prBaseHash, "HEAD"], gitDir);
|
|
739
764
|
if (diff3)
|
|
740
765
|
return diff3.substring(0, diffLimit);
|
|
741
766
|
}
|
|
742
767
|
if (ci)
|
|
743
768
|
return;
|
|
744
|
-
const uncommitted = await runGit("
|
|
769
|
+
const uncommitted = await runGit(["diff"], gitDir);
|
|
745
770
|
if (uncommitted === void 0) {
|
|
746
771
|
return;
|
|
747
772
|
}
|
|
748
773
|
if (uncommitted)
|
|
749
774
|
return uncommitted.substring(0, diffLimit);
|
|
750
|
-
const diff2 = await runGit("
|
|
775
|
+
const diff2 = await runGit(["diff", "HEAD~1"], gitDir);
|
|
751
776
|
return diff2?.substring(0, diffLimit);
|
|
752
777
|
}
|
|
753
|
-
async function runGit(
|
|
754
|
-
debug(`running "${
|
|
778
|
+
async function runGit(args, cwd) {
|
|
779
|
+
debug(`running "git ${args.join(" ")}"`);
|
|
755
780
|
const start = monotonicTime();
|
|
756
781
|
const result = await spawnAsync(
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
{ stdio: "pipe", cwd, timeout: GIT_OPERATIONS_TIMEOUT_MS
|
|
782
|
+
"git",
|
|
783
|
+
args,
|
|
784
|
+
{ stdio: "pipe", cwd, timeout: GIT_OPERATIONS_TIMEOUT_MS }
|
|
760
785
|
);
|
|
761
786
|
if (monotonicTime() - start > GIT_OPERATIONS_TIMEOUT_MS) {
|
|
762
|
-
print(`timeout of ${GIT_OPERATIONS_TIMEOUT_MS}ms exceeded while running "${
|
|
787
|
+
print(`timeout of ${GIT_OPERATIONS_TIMEOUT_MS}ms exceeded while running "git ${args.join(" ")}"`);
|
|
763
788
|
return;
|
|
764
789
|
}
|
|
765
790
|
if (result.code)
|
|
@@ -774,6 +799,7 @@ ${result.stderr}`);
|
|
|
774
799
|
// packages/playwright/src/plugins/webServerPlugin.ts
|
|
775
800
|
var import_net = __toESM(require("net"));
|
|
776
801
|
var import_path = __toESM(require("path"));
|
|
802
|
+
var import_util = require("util");
|
|
777
803
|
var colors = require("playwright-core/lib/utilsBundle").colors;
|
|
778
804
|
var debug2 = require("playwright-core/lib/utilsBundle").debug;
|
|
779
805
|
var { ManualPromise } = require("playwright-core/lib/coreBundle").iso;
|
|
@@ -882,7 +908,7 @@ var WebServerPlugin = class {
|
|
|
882
908
|
launchedProcess[stdio].on("data", (data) => {
|
|
883
909
|
if (!this._options.wait?.[stdio] || stdioWaitCollectors[stdio] === void 0)
|
|
884
910
|
return;
|
|
885
|
-
stdioWaitCollectors[stdio] += data.toString();
|
|
911
|
+
stdioWaitCollectors[stdio] += (0, import_util.stripVTControlCharacters)(data.toString());
|
|
886
912
|
this._options.wait[stdio].lastIndex = 0;
|
|
887
913
|
const result = this._options.wait[stdio].exec(stdioWaitCollectors[stdio]);
|
|
888
914
|
if (result) {
|
|
@@ -1004,18 +1030,29 @@ __export(base_exports, {
|
|
|
1004
1030
|
terminalScreen: () => terminalScreen
|
|
1005
1031
|
});
|
|
1006
1032
|
var import_path2 = __toESM(require("path"));
|
|
1007
|
-
var
|
|
1033
|
+
var import_stream = require("stream");
|
|
1034
|
+
var import_util2 = require("../util");
|
|
1008
1035
|
var realColors = require("playwright-core/lib/utilsBundle").colors;
|
|
1009
1036
|
var { noColors } = require("playwright-core/lib/coreBundle").iso;
|
|
1010
1037
|
var { msToString } = require("playwright-core/lib/coreBundle").iso;
|
|
1011
|
-
var { parseErrorStack } = require("playwright-core/lib/coreBundle").
|
|
1038
|
+
var { parseErrorStack } = require("playwright-core/lib/coreBundle").utils;
|
|
1012
1039
|
var { getPackageManagerExecCommand } = require("playwright-core/lib/coreBundle").utils;
|
|
1013
1040
|
var { fitToWidth } = require("playwright-core/lib/coreBundle").utils;
|
|
1014
|
-
var kOutputSymbol = Symbol("output");
|
|
1041
|
+
var kOutputSymbol = /* @__PURE__ */ Symbol("output");
|
|
1015
1042
|
var DEFAULT_TTY_WIDTH = 100;
|
|
1016
1043
|
var DEFAULT_TTY_HEIGHT = 40;
|
|
1017
1044
|
var originalProcessStdout = process.stdout;
|
|
1018
1045
|
var originalProcessStderr = process.stderr;
|
|
1046
|
+
var StripAnsiStream = class extends import_stream.Writable {
|
|
1047
|
+
constructor(target) {
|
|
1048
|
+
super();
|
|
1049
|
+
this._target = target;
|
|
1050
|
+
}
|
|
1051
|
+
write(chunk, encodingOrCallback, callback) {
|
|
1052
|
+
const cb = typeof encodingOrCallback === "function" ? encodingOrCallback : callback;
|
|
1053
|
+
return this._target.write((0, import_util2.stripAnsiEscapes)(chunk.toString()), cb);
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1019
1056
|
var terminalScreen = (() => {
|
|
1020
1057
|
let isTTY = !!originalProcessStdout.isTTY;
|
|
1021
1058
|
let ttyWidth = originalProcessStdout.columns || 0;
|
|
@@ -1044,7 +1081,7 @@ var terminalScreen = (() => {
|
|
|
1044
1081
|
ttyHeight = DEFAULT_TTY_HEIGHT;
|
|
1045
1082
|
}
|
|
1046
1083
|
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")
|
|
1084
|
+
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
1085
|
useColors = false;
|
|
1049
1086
|
else if (process.env.DEBUG_COLORS || process.env.FORCE_COLOR)
|
|
1050
1087
|
useColors = true;
|
|
@@ -1055,8 +1092,8 @@ var terminalScreen = (() => {
|
|
|
1055
1092
|
ttyWidth,
|
|
1056
1093
|
ttyHeight,
|
|
1057
1094
|
colors: colors7,
|
|
1058
|
-
stdout: originalProcessStdout,
|
|
1059
|
-
stderr: originalProcessStderr
|
|
1095
|
+
stdout: useColors ? originalProcessStdout : new StripAnsiStream(originalProcessStdout),
|
|
1096
|
+
stderr: useColors ? originalProcessStderr : new StripAnsiStream(originalProcessStderr)
|
|
1060
1097
|
};
|
|
1061
1098
|
})();
|
|
1062
1099
|
var nonTerminalScreen = {
|
|
@@ -1361,7 +1398,7 @@ function quotePathIfNeeded(path21) {
|
|
|
1361
1398
|
return `"${path21}"`;
|
|
1362
1399
|
return path21;
|
|
1363
1400
|
}
|
|
1364
|
-
var kReportedSymbol = Symbol("reported");
|
|
1401
|
+
var kReportedSymbol = /* @__PURE__ */ Symbol("reported");
|
|
1365
1402
|
function markErrorsAsReported(result) {
|
|
1366
1403
|
result[kReportedSymbol] = result.errors.length;
|
|
1367
1404
|
}
|
|
@@ -1444,7 +1481,7 @@ function formatError(screen, error) {
|
|
|
1444
1481
|
if (error.snippet) {
|
|
1445
1482
|
let snippet = error.snippet;
|
|
1446
1483
|
if (!screen.colors.enabled)
|
|
1447
|
-
snippet = (0,
|
|
1484
|
+
snippet = (0, import_util2.stripAnsiEscapes)(snippet);
|
|
1448
1485
|
tokens.push("");
|
|
1449
1486
|
tokens.push(snippet);
|
|
1450
1487
|
}
|
|
@@ -1464,13 +1501,13 @@ function separator(screen, text = "") {
|
|
|
1464
1501
|
if (text)
|
|
1465
1502
|
text += " ";
|
|
1466
1503
|
const columns = Math.min(100, screen.ttyWidth || 100);
|
|
1467
|
-
return text + screen.colors.dim("\u2500".repeat(Math.max(0, columns - (0,
|
|
1504
|
+
return text + screen.colors.dim("\u2500".repeat(Math.max(0, columns - (0, import_util2.stripAnsiEscapes)(text).length)));
|
|
1468
1505
|
}
|
|
1469
1506
|
function indent(lines, tab) {
|
|
1470
1507
|
return lines.replace(/^(?=.+$)/gm, tab);
|
|
1471
1508
|
}
|
|
1472
1509
|
function prepareErrorStack(stack) {
|
|
1473
|
-
return parseErrorStack(stack
|
|
1510
|
+
return parseErrorStack(stack);
|
|
1474
1511
|
}
|
|
1475
1512
|
function resolveFromEnv(name) {
|
|
1476
1513
|
const value = process.env[name];
|
|
@@ -1489,7 +1526,7 @@ function resolveOutputFile(reporterName, options) {
|
|
|
1489
1526
|
if (!outputDir && options.outputDir)
|
|
1490
1527
|
outputDir = import_path2.default.resolve(options.configDir, options.outputDir);
|
|
1491
1528
|
if (!outputDir && options.default)
|
|
1492
|
-
outputDir = (0,
|
|
1529
|
+
outputDir = (0, import_util2.resolveReporterOutputPath)(options.default.outputDir, options.configDir, void 0);
|
|
1493
1530
|
if (!outputDir)
|
|
1494
1531
|
outputDir = options.configDir;
|
|
1495
1532
|
const reportName = process.env[`PLAYWRIGHT_${name}_OUTPUT_NAME`] ?? options.fileName ?? options.default?.fileName;
|
|
@@ -1534,52 +1571,61 @@ function groupAttachments(attachments) {
|
|
|
1534
1571
|
var import_fs = __toESM(require("fs"));
|
|
1535
1572
|
|
|
1536
1573
|
// packages/playwright/src/reporters/multiplexer.ts
|
|
1574
|
+
var import_util3 = require("../util");
|
|
1537
1575
|
var Multiplexer = class {
|
|
1538
1576
|
constructor(reporters) {
|
|
1577
|
+
this._hasReporterErrors = false;
|
|
1539
1578
|
this._reporters = reporters;
|
|
1540
1579
|
}
|
|
1541
1580
|
version() {
|
|
1542
1581
|
return "v2";
|
|
1543
1582
|
}
|
|
1583
|
+
hasReporterErrors() {
|
|
1584
|
+
return this._hasReporterErrors;
|
|
1585
|
+
}
|
|
1544
1586
|
onConfigure(config2) {
|
|
1545
1587
|
for (const reporter of this._reporters)
|
|
1546
|
-
|
|
1588
|
+
this._wrap(() => reporter.onConfigure?.(config2));
|
|
1589
|
+
}
|
|
1590
|
+
async preprocess(params) {
|
|
1591
|
+
for (const reporter of this._reporters)
|
|
1592
|
+
await reporter.preprocess?.(params);
|
|
1547
1593
|
}
|
|
1548
1594
|
onBegin(suite) {
|
|
1549
1595
|
for (const reporter of this._reporters)
|
|
1550
|
-
|
|
1596
|
+
this._wrap(() => reporter.onBegin?.(suite));
|
|
1551
1597
|
}
|
|
1552
1598
|
onTestBegin(test, result) {
|
|
1553
1599
|
for (const reporter of this._reporters)
|
|
1554
|
-
|
|
1600
|
+
this._wrap(() => reporter.onTestBegin?.(test, result));
|
|
1555
1601
|
}
|
|
1556
1602
|
onStdOut(chunk, test, result) {
|
|
1557
1603
|
for (const reporter of this._reporters)
|
|
1558
|
-
|
|
1604
|
+
this._wrap(() => reporter.onStdOut?.(chunk, test, result));
|
|
1559
1605
|
}
|
|
1560
1606
|
onStdErr(chunk, test, result) {
|
|
1561
1607
|
for (const reporter of this._reporters)
|
|
1562
|
-
|
|
1608
|
+
this._wrap(() => reporter.onStdErr?.(chunk, test, result));
|
|
1563
1609
|
}
|
|
1564
1610
|
async onTestPaused(test, result) {
|
|
1565
1611
|
for (const reporter of this._reporters)
|
|
1566
|
-
await
|
|
1612
|
+
await this._wrapAsync(() => reporter.onTestPaused?.(test, result));
|
|
1567
1613
|
}
|
|
1568
1614
|
onTestEnd(test, result) {
|
|
1569
1615
|
for (const reporter of this._reporters)
|
|
1570
|
-
|
|
1616
|
+
this._wrap(() => reporter.onTestEnd?.(test, result));
|
|
1571
1617
|
}
|
|
1572
1618
|
onReportConfigure(params) {
|
|
1573
1619
|
for (const reporter of this._reporters)
|
|
1574
|
-
|
|
1620
|
+
this._wrap(() => reporter.onReportConfigure?.(params));
|
|
1575
1621
|
}
|
|
1576
1622
|
onReportEnd(params) {
|
|
1577
1623
|
for (const reporter of this._reporters)
|
|
1578
|
-
|
|
1624
|
+
this._wrap(() => reporter.onReportEnd?.(params));
|
|
1579
1625
|
}
|
|
1580
1626
|
async onEnd(result) {
|
|
1581
1627
|
for (const reporter of this._reporters) {
|
|
1582
|
-
const outResult = await
|
|
1628
|
+
const outResult = await this._wrapAsync(() => reporter.onEnd?.(result));
|
|
1583
1629
|
if (outResult?.status)
|
|
1584
1630
|
result.status = outResult.status;
|
|
1585
1631
|
}
|
|
@@ -1587,42 +1633,45 @@ var Multiplexer = class {
|
|
|
1587
1633
|
}
|
|
1588
1634
|
async onExit() {
|
|
1589
1635
|
for (const reporter of this._reporters)
|
|
1590
|
-
await
|
|
1636
|
+
await this._wrapAsync(() => reporter.onExit?.());
|
|
1591
1637
|
}
|
|
1592
1638
|
onError(error, workerInfo) {
|
|
1593
1639
|
for (const reporter of this._reporters)
|
|
1594
|
-
|
|
1640
|
+
this._wrap(() => reporter.onError?.(error, workerInfo), false);
|
|
1595
1641
|
}
|
|
1596
1642
|
onStepBegin(test, result, step) {
|
|
1597
1643
|
for (const reporter of this._reporters)
|
|
1598
|
-
|
|
1644
|
+
this._wrap(() => reporter.onStepBegin?.(test, result, step));
|
|
1599
1645
|
}
|
|
1600
1646
|
onStepEnd(test, result, step) {
|
|
1601
1647
|
for (const reporter of this._reporters)
|
|
1602
|
-
|
|
1648
|
+
this._wrap(() => reporter.onStepEnd?.(test, result, step));
|
|
1603
1649
|
}
|
|
1604
1650
|
printsToStdio() {
|
|
1605
1651
|
return this._reporters.some((r) => {
|
|
1606
1652
|
let prints = false;
|
|
1607
|
-
|
|
1653
|
+
this._wrap(() => prints = r.printsToStdio ? r.printsToStdio() : true, false);
|
|
1608
1654
|
return prints;
|
|
1609
1655
|
});
|
|
1610
1656
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1657
|
+
_wrap(callback, redispatch = true) {
|
|
1658
|
+
try {
|
|
1659
|
+
callback();
|
|
1660
|
+
} catch (e) {
|
|
1661
|
+
this._hasReporterErrors = true;
|
|
1662
|
+
if (redispatch)
|
|
1663
|
+
this.onError((0, import_util3.serializeError)(e));
|
|
1664
|
+
}
|
|
1617
1665
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1666
|
+
async _wrapAsync(callback) {
|
|
1667
|
+
try {
|
|
1668
|
+
return await callback();
|
|
1669
|
+
} catch (e) {
|
|
1670
|
+
this._hasReporterErrors = true;
|
|
1671
|
+
this.onError((0, import_util3.serializeError)(e));
|
|
1672
|
+
}
|
|
1624
1673
|
}
|
|
1625
|
-
}
|
|
1674
|
+
};
|
|
1626
1675
|
|
|
1627
1676
|
// packages/playwright/src/reporters/internalReporter.ts
|
|
1628
1677
|
var import_common = require("../common");
|
|
@@ -1648,6 +1697,9 @@ var ReporterV2Wrapper = class {
|
|
|
1648
1697
|
onConfigure(config2) {
|
|
1649
1698
|
this._config = config2;
|
|
1650
1699
|
}
|
|
1700
|
+
preprocess(params) {
|
|
1701
|
+
return this._reporter.preprocess?.(params);
|
|
1702
|
+
}
|
|
1651
1703
|
onBegin(suite) {
|
|
1652
1704
|
this._reporter.onBegin?.(this._config, suite);
|
|
1653
1705
|
const deferred = this._deferred;
|
|
@@ -1715,12 +1767,18 @@ var InternalReporter = class {
|
|
|
1715
1767
|
version() {
|
|
1716
1768
|
return "v2";
|
|
1717
1769
|
}
|
|
1770
|
+
hasReporterErrors() {
|
|
1771
|
+
return this._reporter.hasReporterErrors();
|
|
1772
|
+
}
|
|
1718
1773
|
onConfigure(config2) {
|
|
1719
1774
|
this._config = config2;
|
|
1720
1775
|
this._startTime = /* @__PURE__ */ new Date();
|
|
1721
1776
|
this._monotonicStartTime = monotonicTime3();
|
|
1722
1777
|
this._reporter.onConfigure?.(config2);
|
|
1723
1778
|
}
|
|
1779
|
+
async preprocess(params) {
|
|
1780
|
+
await this._reporter.preprocess(params);
|
|
1781
|
+
}
|
|
1724
1782
|
onBegin(suite) {
|
|
1725
1783
|
this._didBegin = true;
|
|
1726
1784
|
this._reporter.onBegin?.(suite);
|
|
@@ -1767,7 +1825,7 @@ var InternalReporter = class {
|
|
|
1767
1825
|
this._reporter.onStepEnd?.(test, result, step);
|
|
1768
1826
|
}
|
|
1769
1827
|
printsToStdio() {
|
|
1770
|
-
return this._reporter.printsToStdio
|
|
1828
|
+
return this._reporter.printsToStdio?.() ?? true;
|
|
1771
1829
|
}
|
|
1772
1830
|
_addSnippetToTestErrors(test, result) {
|
|
1773
1831
|
for (const error of result.errors)
|
|
@@ -1801,7 +1859,7 @@ function addLocationAndSnippetToError(config2, error, file) {
|
|
|
1801
1859
|
}
|
|
1802
1860
|
|
|
1803
1861
|
// packages/playwright/src/runner/testRunner.ts
|
|
1804
|
-
var
|
|
1862
|
+
var import_util15 = require("../util");
|
|
1805
1863
|
|
|
1806
1864
|
// packages/playwright/src/runner/reporters.ts
|
|
1807
1865
|
var reporters_exports = {};
|
|
@@ -1997,7 +2055,7 @@ var InProcessLoaderHost = class {
|
|
|
1997
2055
|
return result;
|
|
1998
2056
|
}
|
|
1999
2057
|
async stop() {
|
|
2000
|
-
await import_common2.
|
|
2058
|
+
await import_common2.transform.incorporateCompilationCache();
|
|
2001
2059
|
}
|
|
2002
2060
|
};
|
|
2003
2061
|
var OutOfProcessLoaderHost = class {
|
|
@@ -2028,7 +2086,7 @@ var OutOfProcessLoaderHost = class {
|
|
|
2028
2086
|
};
|
|
2029
2087
|
|
|
2030
2088
|
// packages/playwright/src/runner/loadUtils.ts
|
|
2031
|
-
var
|
|
2089
|
+
var import_util6 = require("../util");
|
|
2032
2090
|
|
|
2033
2091
|
// packages/playwright/src/runner/projectUtils.ts
|
|
2034
2092
|
var projectUtils_exports = {};
|
|
@@ -2042,12 +2100,12 @@ __export(projectUtils_exports, {
|
|
|
2042
2100
|
});
|
|
2043
2101
|
var import_fs2 = __toESM(require("fs"));
|
|
2044
2102
|
var import_path3 = __toESM(require("path"));
|
|
2045
|
-
var
|
|
2046
|
-
var
|
|
2047
|
-
var minimatch = require("playwright-core/lib/utilsBundle")
|
|
2103
|
+
var import_util4 = require("util");
|
|
2104
|
+
var import_util5 = require("../util");
|
|
2105
|
+
var { minimatch } = require("playwright-core/lib/utilsBundle");
|
|
2048
2106
|
var { escapeRegExp } = require("playwright-core/lib/coreBundle").iso;
|
|
2049
|
-
var readFileAsync = (0,
|
|
2050
|
-
var readDirAsync = (0,
|
|
2107
|
+
var readFileAsync = (0, import_util4.promisify)(import_fs2.default.readFile);
|
|
2108
|
+
var readDirAsync = (0, import_util4.promisify)(import_fs2.default.readdir);
|
|
2051
2109
|
function wildcardPatternToRegExp(pattern) {
|
|
2052
2110
|
return new RegExp("^" + pattern.split("*").map(escapeRegExp).join(".*") + "$", "ig");
|
|
2053
2111
|
}
|
|
@@ -2152,8 +2210,8 @@ async function collectFilesForProject(project, fsCache = /* @__PURE__ */ new Map
|
|
|
2152
2210
|
const extensions = /* @__PURE__ */ new Set([".js", ".ts", ".mjs", ".mts", ".cjs", ".cts", ".jsx", ".tsx", ".mjsx", ".mtsx", ".cjsx", ".ctsx"]);
|
|
2153
2211
|
const testFileExtension = (file) => extensions.has(import_path3.default.extname(file));
|
|
2154
2212
|
const allFiles = await cachedCollectFiles(project.project.testDir, project.respectGitIgnore, fsCache);
|
|
2155
|
-
const testMatch = (0,
|
|
2156
|
-
const testIgnore = (0,
|
|
2213
|
+
const testMatch = (0, import_util5.createFileMatcher)(project.project.testMatch);
|
|
2214
|
+
const testIgnore = (0, import_util5.createFileMatcher)(project.project.testIgnore);
|
|
2157
2215
|
const testFiles = allFiles.filter((file) => {
|
|
2158
2216
|
if (!testFileExtension(file))
|
|
2159
2217
|
return false;
|
|
@@ -2235,6 +2293,65 @@ async function collectFiles(testDir, respectGitIgnore) {
|
|
|
2235
2293
|
return files;
|
|
2236
2294
|
}
|
|
2237
2295
|
|
|
2296
|
+
// packages/playwright/src/runner/reporterTestRun.ts
|
|
2297
|
+
var import_common3 = require("../common");
|
|
2298
|
+
var ReporterTestRunImpl = class {
|
|
2299
|
+
constructor(_rootSuite, _readonlyProjectSuites) {
|
|
2300
|
+
this._rootSuite = _rootSuite;
|
|
2301
|
+
this._readonlyProjectSuites = _readonlyProjectSuites;
|
|
2302
|
+
this._active = true;
|
|
2303
|
+
this._skipSharding = false;
|
|
2304
|
+
this.skip = import_common3.transform.wrapFunctionWithLocation((location, target, reason) => this._modifier("skip", location, target, reason));
|
|
2305
|
+
this.fixme = import_common3.transform.wrapFunctionWithLocation((location, target, reason) => this._modifier("fixme", location, target, reason));
|
|
2306
|
+
this.fail = import_common3.transform.wrapFunctionWithLocation((location, target, reason) => this._modifier("fail", location, target, reason));
|
|
2307
|
+
}
|
|
2308
|
+
close() {
|
|
2309
|
+
this._active = false;
|
|
2310
|
+
}
|
|
2311
|
+
shouldSkipSharding() {
|
|
2312
|
+
return this._skipSharding;
|
|
2313
|
+
}
|
|
2314
|
+
skipSharding() {
|
|
2315
|
+
if (!this._active)
|
|
2316
|
+
throw new Error(`TestRun.skipSharding() can only be called from Reporter.preprocess().`);
|
|
2317
|
+
if (this._skipSharding)
|
|
2318
|
+
throw new Error(`Multiple reporters called 'skipSharding'. Only one reporter may handle sharding.`);
|
|
2319
|
+
this._skipSharding = true;
|
|
2320
|
+
}
|
|
2321
|
+
exclude(target) {
|
|
2322
|
+
if (!this._active)
|
|
2323
|
+
throw new Error(`TestRun.exclude() can only be called from Reporter.preprocess().`);
|
|
2324
|
+
const internalTarget = target;
|
|
2325
|
+
this._checkTarget("exclude", internalTarget);
|
|
2326
|
+
internalTarget.parent._detach(internalTarget);
|
|
2327
|
+
}
|
|
2328
|
+
_modifier(type, location, _target, reason) {
|
|
2329
|
+
if (!this._active)
|
|
2330
|
+
throw new Error(`TestRun.${type}() can only be called from Reporter.preprocess().`);
|
|
2331
|
+
const target = _target;
|
|
2332
|
+
this._checkTarget(type, target);
|
|
2333
|
+
const annotation = { type, description: reason, location };
|
|
2334
|
+
if (target instanceof import_common3.test.Suite) {
|
|
2335
|
+
for (const test of target.allTests())
|
|
2336
|
+
test._applyPlanAnnotation(annotation);
|
|
2337
|
+
} else {
|
|
2338
|
+
target._applyPlanAnnotation(annotation);
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
_checkTarget(method, target) {
|
|
2342
|
+
if (target === this._rootSuite)
|
|
2343
|
+
throw new Error(`TestRun.${method}() cannot be called on the root suite.`);
|
|
2344
|
+
let suite = target instanceof import_common3.test.Suite ? target : target.parent;
|
|
2345
|
+
while (suite) {
|
|
2346
|
+
if (this._readonlyProjectSuites.has(suite)) {
|
|
2347
|
+
const targetType = target instanceof import_common3.test.TestCase ? " test" : "";
|
|
2348
|
+
throw new Error(`TestRun.${method}() cannot be called on a setup or teardown project${targetType}; these always run in full.`);
|
|
2349
|
+
}
|
|
2350
|
+
suite = suite.parent;
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
};
|
|
2354
|
+
|
|
2238
2355
|
// packages/playwright/src/runner/testGroups.ts
|
|
2239
2356
|
function createTestGroups(projectSuite, expectedParallelism) {
|
|
2240
2357
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -2334,7 +2451,7 @@ function filterForShard(shard, weights, testGroups) {
|
|
|
2334
2451
|
}
|
|
2335
2452
|
|
|
2336
2453
|
// packages/playwright/src/runner/loadUtils.ts
|
|
2337
|
-
var
|
|
2454
|
+
var import_common4 = require("../common");
|
|
2338
2455
|
var sourceMapSupport = require("playwright-core/lib/utilsBundle").sourceMapSupport;
|
|
2339
2456
|
var { toPosixPath } = require("playwright-core/lib/coreBundle").utils;
|
|
2340
2457
|
async function collectProjectsAndTestFiles(testRun, doNotRunTestsOutsideProjectFilter) {
|
|
@@ -2387,7 +2504,7 @@ async function loadFileSuites(testRun, mode, errors) {
|
|
|
2387
2504
|
await loaderHost.stop();
|
|
2388
2505
|
}
|
|
2389
2506
|
for (const file of allTestFiles) {
|
|
2390
|
-
for (const dependency of
|
|
2507
|
+
for (const dependency of import_common4.cc.dependenciesForTestFile(file)) {
|
|
2391
2508
|
if (allTestFiles.has(dependency)) {
|
|
2392
2509
|
const importer = import_path4.default.relative(config2.config.rootDir, file);
|
|
2393
2510
|
const importee = import_path4.default.relative(config2.config.rootDir, dependency);
|
|
@@ -2405,7 +2522,7 @@ async function loadFileSuites(testRun, mode, errors) {
|
|
|
2405
2522
|
}
|
|
2406
2523
|
async function createRootSuite(testRun, errors, shouldFilterOnly) {
|
|
2407
2524
|
const config2 = testRun.config;
|
|
2408
|
-
const rootSuite = new
|
|
2525
|
+
const rootSuite = new import_common4.test.Suite("", "root");
|
|
2409
2526
|
const projectSuites = /* @__PURE__ */ new Map();
|
|
2410
2527
|
const filteredProjectSuites = /* @__PURE__ */ new Map();
|
|
2411
2528
|
{
|
|
@@ -2417,10 +2534,10 @@ async function createRootSuite(testRun, errors, shouldFilterOnly) {
|
|
|
2417
2534
|
}
|
|
2418
2535
|
}
|
|
2419
2536
|
if (shouldFilterOnly) {
|
|
2420
|
-
const filteredRoot = new
|
|
2537
|
+
const filteredRoot = new import_common4.test.Suite("", "root");
|
|
2421
2538
|
for (const filteredProjectSuite of filteredProjectSuites.values())
|
|
2422
2539
|
filteredRoot._addSuite(filteredProjectSuite);
|
|
2423
|
-
|
|
2540
|
+
import_common4.suiteUtils.filterOnly(filteredRoot);
|
|
2424
2541
|
for (const [project, filteredProjectSuite] of filteredProjectSuites) {
|
|
2425
2542
|
if (!filteredRoot.suites.includes(filteredProjectSuite))
|
|
2426
2543
|
filteredProjectSuites.delete(project);
|
|
@@ -2440,7 +2557,24 @@ async function createRootSuite(testRun, errors, shouldFilterOnly) {
|
|
|
2440
2557
|
errors.push(...createForbidOnlyErrors(onlyTestsAndSuites, config2.configCLIOverrides.forbidOnly, configFilePath));
|
|
2441
2558
|
}
|
|
2442
2559
|
}
|
|
2443
|
-
|
|
2560
|
+
const dependencySuites = /* @__PURE__ */ new Map();
|
|
2561
|
+
for (const [project, type] of projectClosure) {
|
|
2562
|
+
if (type !== "dependency")
|
|
2563
|
+
continue;
|
|
2564
|
+
const dependencySuite = buildProjectSuite(project, projectSuites.get(project));
|
|
2565
|
+
dependencySuites.set(project, dependencySuite);
|
|
2566
|
+
rootSuite._prependSuite(dependencySuite);
|
|
2567
|
+
}
|
|
2568
|
+
const reporterTestRun = new ReporterTestRunImpl(rootSuite, new Set(dependencySuites.values()));
|
|
2569
|
+
await testRun.reporter.preprocess({
|
|
2570
|
+
config: config2.config,
|
|
2571
|
+
suite: rootSuite,
|
|
2572
|
+
testRun: reporterTestRun
|
|
2573
|
+
});
|
|
2574
|
+
reporterTestRun.close();
|
|
2575
|
+
for (const dependencySuite of dependencySuites.values())
|
|
2576
|
+
rootSuite._detach(dependencySuite);
|
|
2577
|
+
if (config2.config.shard && !reporterTestRun.shouldSkipSharding()) {
|
|
2444
2578
|
const testGroups = [];
|
|
2445
2579
|
for (const projectSuite of rootSuite.suites) {
|
|
2446
2580
|
for (const group of createTestGroups(projectSuite, config2.config.shard.total))
|
|
@@ -2452,30 +2586,31 @@ async function createRootSuite(testRun, errors, shouldFilterOnly) {
|
|
|
2452
2586
|
for (const test of group.tests)
|
|
2453
2587
|
testsInThisShard.add(test);
|
|
2454
2588
|
}
|
|
2455
|
-
|
|
2589
|
+
import_common4.suiteUtils.filterTestsRemoveEmptySuites(rootSuite, (test) => testsInThisShard.has(test));
|
|
2456
2590
|
}
|
|
2457
2591
|
if (testRun.postShardTestFilters.length)
|
|
2458
|
-
|
|
2592
|
+
import_common4.suiteUtils.filterTestsRemoveEmptySuites(rootSuite, (test) => testRun.postShardTestFilters.every((filter) => filter(test)));
|
|
2459
2593
|
const topLevelProjects = [];
|
|
2460
2594
|
{
|
|
2461
|
-
const
|
|
2462
|
-
for (const [project,
|
|
2463
|
-
if (
|
|
2464
|
-
rootSuite.
|
|
2595
|
+
const finalProjectClosure = buildProjectsClosure(rootSuite.suites.map((suite) => suite._fullProject));
|
|
2596
|
+
for (const [project, type] of finalProjectClosure) {
|
|
2597
|
+
if (type === "dependency")
|
|
2598
|
+
rootSuite._addSuite(dependencySuites.get(project));
|
|
2465
2599
|
else
|
|
2466
2600
|
topLevelProjects.push(project);
|
|
2467
2601
|
}
|
|
2468
2602
|
}
|
|
2603
|
+
rootSuite._entries.sort((a, b) => config2.projects.indexOf(a._fullProject) - config2.projects.indexOf(b._fullProject));
|
|
2469
2604
|
testRun.rootSuite = rootSuite;
|
|
2470
2605
|
testRun.topLevelProjects = topLevelProjects;
|
|
2471
2606
|
}
|
|
2472
2607
|
function createProjectSuite(project, fileSuites) {
|
|
2473
|
-
const projectSuite = new
|
|
2608
|
+
const projectSuite = new import_common4.test.Suite(project.project.name, "project");
|
|
2474
2609
|
for (const fileSuite of fileSuites)
|
|
2475
|
-
projectSuite._addSuite(
|
|
2476
|
-
const grepMatcher = (0,
|
|
2477
|
-
const grepInvertMatcher = project.project.grepInvert ? (0,
|
|
2478
|
-
|
|
2610
|
+
projectSuite._addSuite(import_common4.suiteUtils.bindFileSuiteToProject(project, fileSuite));
|
|
2611
|
+
const grepMatcher = (0, import_util6.createTitleMatcher)(project.project.grep);
|
|
2612
|
+
const grepInvertMatcher = project.project.grepInvert ? (0, import_util6.createTitleMatcher)(project.project.grepInvert) : null;
|
|
2613
|
+
import_common4.suiteUtils.filterTestsRemoveEmptySuites(projectSuite, (test) => {
|
|
2479
2614
|
const grepTitle = test._grepTitleWithTags();
|
|
2480
2615
|
if (grepInvertMatcher?.(grepTitle))
|
|
2481
2616
|
return false;
|
|
@@ -2487,11 +2622,11 @@ function filterProjectSuite(projectSuite, testFilters) {
|
|
|
2487
2622
|
if (!testFilters.length)
|
|
2488
2623
|
return projectSuite;
|
|
2489
2624
|
const result = projectSuite._deepClone();
|
|
2490
|
-
|
|
2625
|
+
import_common4.suiteUtils.filterTestsRemoveEmptySuites(result, (test) => testFilters.every((filter) => filter(test)));
|
|
2491
2626
|
return result;
|
|
2492
2627
|
}
|
|
2493
2628
|
function buildProjectSuite(project, projectSuite) {
|
|
2494
|
-
const result = new
|
|
2629
|
+
const result = new import_common4.test.Suite(project.project.name, "project");
|
|
2495
2630
|
result._fullProject = project;
|
|
2496
2631
|
if (project.fullyParallel)
|
|
2497
2632
|
result._parallelMode = "parallel";
|
|
@@ -2499,7 +2634,7 @@ function buildProjectSuite(project, projectSuite) {
|
|
|
2499
2634
|
result._addSuite(fileSuite);
|
|
2500
2635
|
for (let repeatEachIndex = 1; repeatEachIndex < project.project.repeatEach; repeatEachIndex++) {
|
|
2501
2636
|
const clone = fileSuite._deepClone();
|
|
2502
|
-
|
|
2637
|
+
import_common4.suiteUtils.applyRepeatEachIndex(project, clone, repeatEachIndex);
|
|
2503
2638
|
result._addSuite(clone);
|
|
2504
2639
|
}
|
|
2505
2640
|
}
|
|
@@ -2542,11 +2677,11 @@ function buildItemLocation(rootDir, testOrSuite) {
|
|
|
2542
2677
|
return `${import_path4.default.relative(rootDir, testOrSuite.location.file)}:${testOrSuite.location.line}`;
|
|
2543
2678
|
}
|
|
2544
2679
|
async function requireOrImportDefaultFunction(file, expectConstructor) {
|
|
2545
|
-
let func = await
|
|
2680
|
+
let func = await import_common4.transform.requireOrImport(file);
|
|
2546
2681
|
if (func && typeof func === "object" && "default" in func)
|
|
2547
2682
|
func = func["default"];
|
|
2548
2683
|
if (typeof func !== "function")
|
|
2549
|
-
throw (0,
|
|
2684
|
+
throw (0, import_util6.errorWithFile)(file, `file must export a single ${expectConstructor ? "class" : "function"}.`);
|
|
2550
2685
|
return func;
|
|
2551
2686
|
}
|
|
2552
2687
|
function loadGlobalHook(config2, file) {
|
|
@@ -2585,7 +2720,7 @@ async function loadTestList(config2, filePath) {
|
|
|
2585
2720
|
project = tokens[0].substring(1, tokens[0].length - 1);
|
|
2586
2721
|
tokens.shift();
|
|
2587
2722
|
}
|
|
2588
|
-
return { project, file: toPosixPath((0,
|
|
2723
|
+
return { project, file: toPosixPath((0, import_util6.parseLocationArg)(tokens[0]).file), titlePath: tokens.slice(1) };
|
|
2589
2724
|
});
|
|
2590
2725
|
const testFilter = (test) => descriptions.some((d) => {
|
|
2591
2726
|
const [projectName, , ...titles] = test.titlePath();
|
|
@@ -2602,14 +2737,14 @@ async function loadTestList(config2, filePath) {
|
|
|
2602
2737
|
};
|
|
2603
2738
|
return { testFilter, fileFilter };
|
|
2604
2739
|
} catch (e) {
|
|
2605
|
-
throw (0,
|
|
2740
|
+
throw (0, import_util6.errorWithFile)(filePath, "Cannot read test list file: " + e.message);
|
|
2606
2741
|
}
|
|
2607
2742
|
}
|
|
2608
2743
|
|
|
2609
2744
|
// packages/playwright/src/reporters/blob.ts
|
|
2610
2745
|
var import_fs4 = __toESM(require("fs"));
|
|
2611
2746
|
var import_path6 = __toESM(require("path"));
|
|
2612
|
-
var
|
|
2747
|
+
var import_stream2 = require("stream");
|
|
2613
2748
|
var import_coreBundle = require("playwright-core/lib/coreBundle");
|
|
2614
2749
|
|
|
2615
2750
|
// packages/playwright/src/reporters/teleEmitter.ts
|
|
@@ -2621,7 +2756,7 @@ var TeleReporterEmitter = class {
|
|
|
2621
2756
|
this._resultKnownErrorCounts = /* @__PURE__ */ new Map();
|
|
2622
2757
|
// In case there is blob reporter and UI mode, make sure one doesn't override
|
|
2623
2758
|
// the id assigned by the other.
|
|
2624
|
-
this._idSymbol = Symbol("id");
|
|
2759
|
+
this._idSymbol = /* @__PURE__ */ Symbol("id");
|
|
2625
2760
|
this._messageSink = messageSink;
|
|
2626
2761
|
this._emitterOptions = options;
|
|
2627
2762
|
}
|
|
@@ -2762,7 +2897,8 @@ var TeleReporterEmitter = class {
|
|
|
2762
2897
|
globalSetup: config2.globalSetup,
|
|
2763
2898
|
globalTeardown: config2.globalTeardown,
|
|
2764
2899
|
tags: config2.tags,
|
|
2765
|
-
webServer: config2.webServer
|
|
2900
|
+
webServer: config2.webServer,
|
|
2901
|
+
failOnFlakyTests: config2.failOnFlakyTests
|
|
2766
2902
|
};
|
|
2767
2903
|
}
|
|
2768
2904
|
_serializeProject(suite) {
|
|
@@ -2955,7 +3091,7 @@ var BlobReporter = class extends TeleReporterEmitter {
|
|
|
2955
3091
|
zipFile.addFile(originalPath, zipEntryPath);
|
|
2956
3092
|
}
|
|
2957
3093
|
const lines = this._messages.map((m) => JSON.stringify(m) + "\n");
|
|
2958
|
-
const content =
|
|
3094
|
+
const content = import_stream2.Readable.from(lines);
|
|
2959
3095
|
zipFile.addReadStream(content, "report.jsonl");
|
|
2960
3096
|
zipFile.end();
|
|
2961
3097
|
await finishPromise;
|
|
@@ -3089,14 +3225,17 @@ var empty_default = EmptyReporter;
|
|
|
3089
3225
|
|
|
3090
3226
|
// packages/playwright/src/reporters/github.ts
|
|
3091
3227
|
var import_path7 = __toESM(require("path"));
|
|
3092
|
-
var
|
|
3228
|
+
var import_util7 = require("../util");
|
|
3093
3229
|
var { noColors: noColors2 } = require("playwright-core/lib/coreBundle").iso;
|
|
3094
3230
|
var { msToString: msToString2 } = require("playwright-core/lib/coreBundle").iso;
|
|
3095
3231
|
var GitHubLogger = class {
|
|
3232
|
+
newLine() {
|
|
3233
|
+
process.stdout.write("\n");
|
|
3234
|
+
}
|
|
3096
3235
|
_log(message, type = "notice", options = {}) {
|
|
3097
3236
|
message = message.replace(/\n/g, "%0A");
|
|
3098
3237
|
const configs = Object.entries(options).map(([key, option]) => `${key}=${option}`).join(",");
|
|
3099
|
-
process.stdout.write((0,
|
|
3238
|
+
process.stdout.write((0, import_util7.stripAnsiEscapes)(`::${type} ${configs}::${message}
|
|
3100
3239
|
`));
|
|
3101
3240
|
}
|
|
3102
3241
|
debug(message, options) {
|
|
@@ -3129,6 +3268,7 @@ var GitHubReporter = class extends TerminalReporter {
|
|
|
3129
3268
|
if (!this._shouldPrintFailureAnnotations(test))
|
|
3130
3269
|
return;
|
|
3131
3270
|
this._failedTestCount++;
|
|
3271
|
+
this.githubLogger.newLine();
|
|
3132
3272
|
for (const r of test.results)
|
|
3133
3273
|
this._printFailureAnnotation(test, r, this._failedTestCount);
|
|
3134
3274
|
}
|
|
@@ -3203,9 +3343,9 @@ __export(html_exports, {
|
|
|
3203
3343
|
var import_fs5 = __toESM(require("fs"));
|
|
3204
3344
|
var import_os = __toESM(require("os"));
|
|
3205
3345
|
var import_path8 = __toESM(require("path"));
|
|
3206
|
-
var
|
|
3346
|
+
var import_stream3 = require("stream");
|
|
3207
3347
|
var babel2 = __toESM(require("../transform/babelBundle"));
|
|
3208
|
-
var
|
|
3348
|
+
var import_util8 = require("../util");
|
|
3209
3349
|
var colors2 = require("playwright-core/lib/utilsBundle").colors;
|
|
3210
3350
|
var mime2 = require("playwright-core/lib/utilsBundle").mime;
|
|
3211
3351
|
var open = require("playwright-core/lib/utilsBundle").open;
|
|
@@ -3263,7 +3403,7 @@ var HtmlReporter = class {
|
|
|
3263
3403
|
this.suite = suite;
|
|
3264
3404
|
}
|
|
3265
3405
|
_resolveOptions() {
|
|
3266
|
-
const outputFolder = reportFolderFromEnv() ?? (0,
|
|
3406
|
+
const outputFolder = reportFolderFromEnv() ?? (0, import_util8.resolveReporterOutputPath)("playwright-report", this._options.configDir, this._options.outputFolder);
|
|
3267
3407
|
return {
|
|
3268
3408
|
outputFolder,
|
|
3269
3409
|
open: getHtmlReportOptionProcessEnv() || this._options.open || "on-failure",
|
|
@@ -3293,10 +3433,12 @@ var HtmlReporter = class {
|
|
|
3293
3433
|
const noSnippets = parseBooleanEnvVar("PLAYWRIGHT_HTML_NO_SNIPPETS") ?? this._options.noSnippets;
|
|
3294
3434
|
const noCopyPrompt = parseBooleanEnvVar("PLAYWRIGHT_HTML_NO_COPY_PROMPT") ?? this._options.noCopyPrompt;
|
|
3295
3435
|
const doNotInlineAssets = parseBooleanEnvVar("PLAYWRIGHT_HTML_DO_NOT_INLINE_ASSETS") ?? this._options.doNotInlineAssets ?? false;
|
|
3436
|
+
const mergeFiles = parseBooleanEnvVar("PLAYWRIGHT_HTML_MERGE_FILES") ?? this._options.mergeFiles;
|
|
3296
3437
|
const builder = new HtmlBuilder(yazl2, this.config, this._outputFolder, this._attachmentsBaseURL, doNotInlineAssets, {
|
|
3297
3438
|
title: process.env.PLAYWRIGHT_HTML_TITLE || this._options.title,
|
|
3298
3439
|
noSnippets,
|
|
3299
|
-
noCopyPrompt
|
|
3440
|
+
noCopyPrompt,
|
|
3441
|
+
mergeFiles
|
|
3300
3442
|
});
|
|
3301
3443
|
this._buildResult = await builder.build(this.config.metadata, projectSuites, result, this._topLevelErrors, this._machines);
|
|
3302
3444
|
}
|
|
@@ -3343,7 +3485,7 @@ function parseBooleanEnvVar(name) {
|
|
|
3343
3485
|
return void 0;
|
|
3344
3486
|
}
|
|
3345
3487
|
function standaloneDefaultFolder() {
|
|
3346
|
-
return reportFolderFromEnv() ?? (0,
|
|
3488
|
+
return reportFolderFromEnv() ?? (0, import_util8.resolveReporterOutputPath)("playwright-report", process.cwd(), void 0);
|
|
3347
3489
|
}
|
|
3348
3490
|
async function resolveReportFolder(reportPath) {
|
|
3349
3491
|
const stat = await import_fs5.default.promises.stat(reportPath).catch(() => null);
|
|
@@ -3520,9 +3662,9 @@ var HtmlBuilder = class {
|
|
|
3520
3662
|
}
|
|
3521
3663
|
async _writeReportData(filePath) {
|
|
3522
3664
|
import_fs5.default.appendFileSync(filePath, '<template id="playwrightReportBase64">data:application/zip;base64,');
|
|
3523
|
-
await new Promise((
|
|
3665
|
+
await new Promise((resolve, reject) => {
|
|
3524
3666
|
this._dataZipFile.end(void 0, () => {
|
|
3525
|
-
this._dataZipFile.outputStream.pipe(new Base64Encoder()).pipe(import_fs5.default.createWriteStream(filePath, { flags: "a" })).on("close",
|
|
3667
|
+
this._dataZipFile.outputStream.pipe(new Base64Encoder()).pipe(import_fs5.default.createWriteStream(filePath, { flags: "a" })).on("close", resolve).on("error", reject);
|
|
3526
3668
|
});
|
|
3527
3669
|
});
|
|
3528
3670
|
import_fs5.default.appendFileSync(filePath, "</template>");
|
|
@@ -3608,10 +3750,10 @@ var HtmlBuilder = class {
|
|
|
3608
3750
|
this._hasTraces = true;
|
|
3609
3751
|
if ((a.name === "stdout" || a.name === "stderr") && a.contentType === "text/plain") {
|
|
3610
3752
|
if (lastAttachment && lastAttachment.name === a.name && lastAttachment.contentType === a.contentType) {
|
|
3611
|
-
lastAttachment.body += (0,
|
|
3753
|
+
lastAttachment.body += (0, import_util8.stripAnsiEscapes)(a.body);
|
|
3612
3754
|
return null;
|
|
3613
3755
|
}
|
|
3614
|
-
a.body = (0,
|
|
3756
|
+
a.body = (0, import_util8.stripAnsiEscapes)(a.body);
|
|
3615
3757
|
lastAttachment = a;
|
|
3616
3758
|
return a;
|
|
3617
3759
|
}
|
|
@@ -3751,7 +3893,7 @@ var addStats = (stats, delta) => {
|
|
|
3751
3893
|
stats.ok = stats.ok && delta.ok;
|
|
3752
3894
|
return stats;
|
|
3753
3895
|
};
|
|
3754
|
-
var Base64Encoder = class extends
|
|
3896
|
+
var Base64Encoder = class extends import_stream3.Transform {
|
|
3755
3897
|
_transform(chunk, encoding, callback) {
|
|
3756
3898
|
if (this._remainder) {
|
|
3757
3899
|
chunk = Buffer.concat([this._remainder, chunk]);
|
|
@@ -3842,7 +3984,7 @@ function createErrorCodeframe(message, location) {
|
|
|
3842
3984
|
highlightCode: false,
|
|
3843
3985
|
linesAbove: 100,
|
|
3844
3986
|
linesBelow: 100,
|
|
3845
|
-
message: (0,
|
|
3987
|
+
message: (0, import_util8.stripAnsiEscapes)(message).split("\n")[0] || void 0
|
|
3846
3988
|
}
|
|
3847
3989
|
);
|
|
3848
3990
|
}
|
|
@@ -3854,7 +3996,7 @@ var html_default = HtmlReporter;
|
|
|
3854
3996
|
// packages/playwright/src/reporters/json.ts
|
|
3855
3997
|
var import_fs6 = __toESM(require("fs"));
|
|
3856
3998
|
var import_path9 = __toESM(require("path"));
|
|
3857
|
-
var
|
|
3999
|
+
var import_common5 = require("../common");
|
|
3858
4000
|
var { MultiMap: MultiMap2 } = require("playwright-core/lib/coreBundle").iso;
|
|
3859
4001
|
var { toPosixPath: toPosixPath3 } = require("playwright-core/lib/coreBundle").utils;
|
|
3860
4002
|
var JSONReporter = class {
|
|
@@ -3891,7 +4033,7 @@ var JSONReporter = class {
|
|
|
3891
4033
|
repeatEach: project.repeatEach,
|
|
3892
4034
|
retries: project.retries,
|
|
3893
4035
|
metadata: project.metadata,
|
|
3894
|
-
id:
|
|
4036
|
+
id: import_common5.config.getProjectId(project),
|
|
3895
4037
|
name: project.name,
|
|
3896
4038
|
testDir: toPosixPath3(project.testDir),
|
|
3897
4039
|
testIgnore: serializePatterns(project.testIgnore),
|
|
@@ -3918,7 +4060,7 @@ var JSONReporter = class {
|
|
|
3918
4060
|
_mergeSuites(suites) {
|
|
3919
4061
|
const fileSuites = new MultiMap2();
|
|
3920
4062
|
for (const projectSuite of suites) {
|
|
3921
|
-
const projectId =
|
|
4063
|
+
const projectId = import_common5.config.getProjectId(projectSuite.project());
|
|
3922
4064
|
const projectName = projectSuite.project().name;
|
|
3923
4065
|
for (const fileSuite of projectSuite.suites) {
|
|
3924
4066
|
const file = fileSuite.location.file;
|
|
@@ -4072,7 +4214,7 @@ var json_default = JSONReporter;
|
|
|
4072
4214
|
// packages/playwright/src/reporters/junit.ts
|
|
4073
4215
|
var import_fs7 = __toESM(require("fs"));
|
|
4074
4216
|
var import_path10 = __toESM(require("path"));
|
|
4075
|
-
var
|
|
4217
|
+
var import_util9 = require("../util");
|
|
4076
4218
|
var { getAsBooleanFromENV } = require("playwright-core/lib/coreBundle").utils;
|
|
4077
4219
|
var JUnitReporter = class {
|
|
4078
4220
|
constructor(options) {
|
|
@@ -4238,7 +4380,7 @@ var JUnitReporter = class {
|
|
|
4238
4380
|
entry.children.push({
|
|
4239
4381
|
name: errorInfo.elementName,
|
|
4240
4382
|
attributes: { message: errorInfo.message, type: errorInfo.type },
|
|
4241
|
-
text: (0,
|
|
4383
|
+
text: (0, import_util9.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test))
|
|
4242
4384
|
});
|
|
4243
4385
|
return errorInfo.elementName;
|
|
4244
4386
|
}
|
|
@@ -4248,7 +4390,7 @@ var JUnitReporter = class {
|
|
|
4248
4390
|
message: `${import_path10.default.basename(test.location.file)}:${test.location.line}:${test.location.column} ${test.title}`,
|
|
4249
4391
|
type: "FAILURE"
|
|
4250
4392
|
},
|
|
4251
|
-
text: (0,
|
|
4393
|
+
text: (0, import_util9.stripAnsiEscapes)(formatFailure(nonTerminalScreen, this.config, test))
|
|
4252
4394
|
});
|
|
4253
4395
|
return "failure";
|
|
4254
4396
|
}
|
|
@@ -4295,7 +4437,7 @@ Warning: attachment ${attachmentPath} is missing`);
|
|
|
4295
4437
|
children: []
|
|
4296
4438
|
};
|
|
4297
4439
|
const stackTrace = result.error?.stack || result.error?.message || result.error?.value || "";
|
|
4298
|
-
entry.children.push({ name: "stackTrace", text: (0,
|
|
4440
|
+
entry.children.push({ name: "stackTrace", text: (0, import_util9.stripAnsiEscapes)(stackTrace) });
|
|
4299
4441
|
await this._appendStdIO(entry, [result]);
|
|
4300
4442
|
return entry;
|
|
4301
4443
|
}
|
|
@@ -4304,7 +4446,7 @@ function classifyResultError(result) {
|
|
|
4304
4446
|
const error = result.error;
|
|
4305
4447
|
if (!error)
|
|
4306
4448
|
return null;
|
|
4307
|
-
const rawMessage = (0,
|
|
4449
|
+
const rawMessage = (0, import_util9.stripAnsiEscapes)(error.message || error.value || "");
|
|
4308
4450
|
const nameMatch = rawMessage.match(/^(\w+): /);
|
|
4309
4451
|
const errorName = nameMatch ? nameMatch[1] : "";
|
|
4310
4452
|
const messageBody = nameMatch ? rawMessage.slice(nameMatch[0].length) : rawMessage;
|
|
@@ -4346,7 +4488,7 @@ function serializeXML(entry, tokens, stripANSIControlSequences) {
|
|
|
4346
4488
|
var discouragedXMLCharacters = /[\u0000-\u0008\u000b-\u000c\u000e-\u001f\u007f-\u0084\u0086-\u009f]/g;
|
|
4347
4489
|
function escape(text, stripANSIControlSequences, isCharacterData) {
|
|
4348
4490
|
if (stripANSIControlSequences)
|
|
4349
|
-
text = (0,
|
|
4491
|
+
text = (0, import_util9.stripAnsiEscapes)(text);
|
|
4350
4492
|
if (isCharacterData) {
|
|
4351
4493
|
text = "<![CDATA[" + text.replace(/]]>/g, "]]>") + "]]>";
|
|
4352
4494
|
} else {
|
|
@@ -4468,7 +4610,7 @@ var LineReporter = class extends TerminalReporter {
|
|
|
4468
4610
|
var line_default = LineReporter;
|
|
4469
4611
|
|
|
4470
4612
|
// packages/playwright/src/reporters/list.ts
|
|
4471
|
-
var
|
|
4613
|
+
var import_util10 = require("../util");
|
|
4472
4614
|
var { msToString: msToString3 } = require("playwright-core/lib/coreBundle").iso;
|
|
4473
4615
|
var { getAsBooleanFromENV: getAsBooleanFromENV2 } = require("playwright-core/lib/coreBundle").utils;
|
|
4474
4616
|
var DOES_NOT_SUPPORT_UTF8_IN_TERMINAL = process.platform === "win32" && process.env.TERM_PROGRAM !== "vscode" && !process.env.WT_SESSION;
|
|
@@ -4484,8 +4626,10 @@ var ListReporter = class extends TerminalReporter {
|
|
|
4484
4626
|
this._resultIndex = /* @__PURE__ */ new Map();
|
|
4485
4627
|
this._stepIndex = /* @__PURE__ */ new Map();
|
|
4486
4628
|
this._needNewLine = false;
|
|
4629
|
+
this._failureIndex = 0;
|
|
4487
4630
|
this._paused = /* @__PURE__ */ new Set();
|
|
4488
4631
|
this._printSteps = getAsBooleanFromENV2("PLAYWRIGHT_LIST_PRINT_STEPS", options?.printSteps);
|
|
4632
|
+
this._printFailuresInline = getAsBooleanFromENV2("PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE", options?.printFailuresInline);
|
|
4489
4633
|
}
|
|
4490
4634
|
onBegin(suite) {
|
|
4491
4635
|
super.onBegin(suite);
|
|
@@ -4612,6 +4756,15 @@ var ListReporter = class extends TerminalReporter {
|
|
|
4612
4756
|
const wasPaused = this._paused.delete(result);
|
|
4613
4757
|
if (!wasPaused)
|
|
4614
4758
|
this._updateTestLine(test, result);
|
|
4759
|
+
const isFailure = result.status !== "skipped" && result.status !== test.expectedStatus;
|
|
4760
|
+
if (!wasPaused && this._printFailuresInline && isFailure)
|
|
4761
|
+
this._printFailure(test);
|
|
4762
|
+
}
|
|
4763
|
+
_printFailure(test) {
|
|
4764
|
+
this._maybeWriteNewLine();
|
|
4765
|
+
const message = "\n" + this.formatFailure(test, ++this._failureIndex) + "\n";
|
|
4766
|
+
this._updateLineCountAndNewLineFlagForOutput(message);
|
|
4767
|
+
this.screen.stdout.write(message);
|
|
4615
4768
|
}
|
|
4616
4769
|
_updateTestLine(test, result) {
|
|
4617
4770
|
const title = this.formatTestTitle(test);
|
|
@@ -4675,7 +4828,7 @@ var ListReporter = class extends TerminalReporter {
|
|
|
4675
4828
|
this.screen.stdout.write(`\x1B[${this._lastRow - row}E`);
|
|
4676
4829
|
}
|
|
4677
4830
|
_testPrefix(index, statusMark) {
|
|
4678
|
-
const statusMarkLength = (0,
|
|
4831
|
+
const statusMarkLength = (0, import_util10.stripAnsiEscapes)(statusMark).length;
|
|
4679
4832
|
const indexLength = Math.ceil(Math.log10(this.totalTestCount + 1));
|
|
4680
4833
|
return " " + statusMark + " ".repeat(3 - statusMarkLength) + this.screen.colors.dim(index.padStart(indexLength) + " ");
|
|
4681
4834
|
}
|
|
@@ -4692,10 +4845,10 @@ var ListReporter = class extends TerminalReporter {
|
|
|
4692
4845
|
async onEnd(result) {
|
|
4693
4846
|
await super.onEnd(result);
|
|
4694
4847
|
this.screen.stdout.write("\n");
|
|
4695
|
-
this.epilogue(
|
|
4848
|
+
this.epilogue(!this._printFailuresInline);
|
|
4696
4849
|
}
|
|
4697
4850
|
};
|
|
4698
|
-
var lastStepOrdinalSymbol = Symbol("lastStepOrdinal");
|
|
4851
|
+
var lastStepOrdinalSymbol = /* @__PURE__ */ Symbol("lastStepOrdinal");
|
|
4699
4852
|
var list_default = ListReporter;
|
|
4700
4853
|
|
|
4701
4854
|
// packages/playwright/src/reporters/listModeReporter.ts
|
|
@@ -5130,7 +5283,7 @@ function computeCommandHash(config2, runOptions) {
|
|
|
5130
5283
|
// packages/playwright/src/runner/tasks.ts
|
|
5131
5284
|
var import_fs11 = __toESM(require("fs"));
|
|
5132
5285
|
var import_path15 = __toESM(require("path"));
|
|
5133
|
-
var
|
|
5286
|
+
var import_util13 = require("util");
|
|
5134
5287
|
|
|
5135
5288
|
// packages/playwright/src/runner/rebase.ts
|
|
5136
5289
|
var import_fs9 = __toESM(require("fs"));
|
|
@@ -5284,7 +5437,7 @@ function applyPatchWithConflictMarkers(oldText, newText) {
|
|
|
5284
5437
|
// packages/playwright/src/runner/workerHost.ts
|
|
5285
5438
|
var import_fs10 = __toESM(require("fs"));
|
|
5286
5439
|
var import_path13 = __toESM(require("path"));
|
|
5287
|
-
var
|
|
5440
|
+
var import_common6 = require("../common");
|
|
5288
5441
|
|
|
5289
5442
|
// packages/playwright/src/isomorphic/folders.ts
|
|
5290
5443
|
function artifactsFolderName(workerIndex) {
|
|
@@ -5320,8 +5473,8 @@ var WorkerHost = class extends ProcessHost {
|
|
|
5320
5473
|
async start() {
|
|
5321
5474
|
await import_fs10.default.promises.mkdir(this._params.artifactsDir, { recursive: true });
|
|
5322
5475
|
return await this.startRunner(this._params, {
|
|
5323
|
-
onStdOut: (chunk) => this.emit("stdOut",
|
|
5324
|
-
onStdErr: (chunk) => this.emit("stdErr",
|
|
5476
|
+
onStdOut: (chunk) => this.emit("stdOut", import_common6.ipc.stdioChunkToParams(chunk)),
|
|
5477
|
+
onStdErr: (chunk) => this.emit("stdErr", import_common6.ipc.stdioChunkToParams(chunk))
|
|
5325
5478
|
});
|
|
5326
5479
|
}
|
|
5327
5480
|
async onExit() {
|
|
@@ -5353,16 +5506,17 @@ var WorkerHost = class extends ProcessHost {
|
|
|
5353
5506
|
};
|
|
5354
5507
|
|
|
5355
5508
|
// packages/playwright/src/runner/dispatcher.ts
|
|
5356
|
-
var
|
|
5357
|
-
var
|
|
5509
|
+
var import_common7 = require("../common");
|
|
5510
|
+
var import_util11 = require("../util");
|
|
5358
5511
|
var colors4 = require("playwright-core/lib/utilsBundle").colors;
|
|
5359
5512
|
var { ManualPromise: ManualPromise3 } = require("playwright-core/lib/coreBundle").iso;
|
|
5360
5513
|
var { eventsHelper } = require("playwright-core/lib/coreBundle").utils;
|
|
5361
5514
|
var Dispatcher = class {
|
|
5362
|
-
constructor(testRun) {
|
|
5515
|
+
constructor(testRun, options = {}) {
|
|
5363
5516
|
// Worker slot is claimed when it has jobDispatcher assigned.
|
|
5364
5517
|
this._workerSlots = [];
|
|
5365
5518
|
this._queue = [];
|
|
5519
|
+
this._isolatedJobs = /* @__PURE__ */ new Set();
|
|
5366
5520
|
this._workerLimitPerProjectId = /* @__PURE__ */ new Map();
|
|
5367
5521
|
this._queuedOrRunningHashCount = /* @__PURE__ */ new Map();
|
|
5368
5522
|
this._finished = new ManualPromise3();
|
|
@@ -5370,6 +5524,7 @@ var Dispatcher = class {
|
|
|
5370
5524
|
this._extraEnvByProjectId = /* @__PURE__ */ new Map();
|
|
5371
5525
|
this._producedEnvByProjectId = /* @__PURE__ */ new Map();
|
|
5372
5526
|
this._testRun = testRun;
|
|
5527
|
+
this._ignoreMaxFailures = !!options.ignoreMaxFailures;
|
|
5373
5528
|
for (const project of testRun.config.projects) {
|
|
5374
5529
|
if (project.workers)
|
|
5375
5530
|
this._workerLimitPerProjectId.set(project.id, project.workers);
|
|
@@ -5378,6 +5533,8 @@ var Dispatcher = class {
|
|
|
5378
5533
|
_findFirstJobToRun() {
|
|
5379
5534
|
for (let index = 0; index < this._queue.length; index++) {
|
|
5380
5535
|
const job = this._queue[index];
|
|
5536
|
+
if (this._isolatedJobs.has(job) && this._workerSlots.some((w) => !!w.jobDispatcher))
|
|
5537
|
+
continue;
|
|
5381
5538
|
const projectIdWorkerLimit = this._workerLimitPerProjectId.get(job.projectId);
|
|
5382
5539
|
if (!projectIdWorkerLimit)
|
|
5383
5540
|
return index;
|
|
@@ -5401,7 +5558,7 @@ var Dispatcher = class {
|
|
|
5401
5558
|
return;
|
|
5402
5559
|
}
|
|
5403
5560
|
this._queue.splice(jobIndex, 1);
|
|
5404
|
-
const jobDispatcher = new JobDispatcher(job, this._testRun, () => this.stop().catch(() => {
|
|
5561
|
+
const jobDispatcher = new JobDispatcher(job, this._testRun, this._ignoreMaxFailures ? void 0 : () => this.stop().catch(() => {
|
|
5405
5562
|
}));
|
|
5406
5563
|
this._workerSlots[workerIndex].jobDispatcher = jobDispatcher;
|
|
5407
5564
|
void this._runJobInWorker(workerIndex, jobDispatcher).then(() => {
|
|
@@ -5423,7 +5580,7 @@ var Dispatcher = class {
|
|
|
5423
5580
|
}
|
|
5424
5581
|
let startError;
|
|
5425
5582
|
if (!worker) {
|
|
5426
|
-
worker = this._createWorker(job, index,
|
|
5583
|
+
worker = this._createWorker(job, index, import_common7.ipc.serializeConfig(this._testRun.config, true));
|
|
5427
5584
|
this._workerSlots[index].worker = worker;
|
|
5428
5585
|
worker.on("exit", () => this._workerSlots[index].worker = void 0);
|
|
5429
5586
|
startError = await worker.start();
|
|
@@ -5443,9 +5600,16 @@ var Dispatcher = class {
|
|
|
5443
5600
|
);
|
|
5444
5601
|
else if (this._isWorkerRedundant(worker))
|
|
5445
5602
|
void worker.stop();
|
|
5446
|
-
if (!this._isStopped
|
|
5447
|
-
|
|
5448
|
-
|
|
5603
|
+
if (!this._isStopped) {
|
|
5604
|
+
if (result.remainingJob) {
|
|
5605
|
+
this._queue.unshift(result.remainingJob);
|
|
5606
|
+
this._updateCounterForWorkerHash(result.remainingJob.workerHash, 1);
|
|
5607
|
+
}
|
|
5608
|
+
if (result.isolatedRetriesJob) {
|
|
5609
|
+
this._isolatedJobs.add(result.isolatedRetriesJob);
|
|
5610
|
+
this._queue.push(result.isolatedRetriesJob);
|
|
5611
|
+
this._updateCounterForWorkerHash(result.isolatedRetriesJob.workerHash, 1);
|
|
5612
|
+
}
|
|
5449
5613
|
}
|
|
5450
5614
|
}
|
|
5451
5615
|
_checkFinished() {
|
|
@@ -5475,7 +5639,7 @@ var Dispatcher = class {
|
|
|
5475
5639
|
this._updateCounterForWorkerHash(group.workerHash, 1);
|
|
5476
5640
|
this._isStopped = false;
|
|
5477
5641
|
this._workerSlots = [];
|
|
5478
|
-
if (this._testRun.hasReachedMaxFailures())
|
|
5642
|
+
if (!this._ignoreMaxFailures && this._testRun.hasReachedMaxFailures())
|
|
5479
5643
|
void this.stop();
|
|
5480
5644
|
for (let i = 0; i < this._testRun.config.config.workers; i++)
|
|
5481
5645
|
this._workerSlots.push({});
|
|
@@ -5548,7 +5712,7 @@ var Dispatcher = class {
|
|
|
5548
5712
|
}
|
|
5549
5713
|
};
|
|
5550
5714
|
var JobDispatcher = class {
|
|
5551
|
-
constructor(job, testRun,
|
|
5715
|
+
constructor(job, testRun, onMaxFailuresReached) {
|
|
5552
5716
|
this.jobResult = new ManualPromise3();
|
|
5553
5717
|
this._listeners = [];
|
|
5554
5718
|
this._failedTests = /* @__PURE__ */ new Set();
|
|
@@ -5559,9 +5723,12 @@ var JobDispatcher = class {
|
|
|
5559
5723
|
this._workerIndex = 0;
|
|
5560
5724
|
this.job = job;
|
|
5561
5725
|
this._testRun = testRun;
|
|
5562
|
-
this.
|
|
5726
|
+
this._onMaxFailuresReached = onMaxFailuresReached;
|
|
5563
5727
|
this._remainingByTestId = new Map(this.job.tests.map((e) => [e.id, e]));
|
|
5564
5728
|
}
|
|
5729
|
+
_isStoppedByMaxFailures() {
|
|
5730
|
+
return !!this._onMaxFailuresReached && this._testRun.hasReachedMaxFailures();
|
|
5731
|
+
}
|
|
5565
5732
|
_onTestBegin(params) {
|
|
5566
5733
|
const test = this._remainingByTestId.get(params.testId);
|
|
5567
5734
|
if (!test) {
|
|
@@ -5576,7 +5743,7 @@ var JobDispatcher = class {
|
|
|
5576
5743
|
this._currentlyRunning = { test, result };
|
|
5577
5744
|
}
|
|
5578
5745
|
_onTestEnd(params) {
|
|
5579
|
-
if (this.
|
|
5746
|
+
if (this._isStoppedByMaxFailures()) {
|
|
5580
5747
|
params.status = "interrupted";
|
|
5581
5748
|
params.errors = [];
|
|
5582
5749
|
}
|
|
@@ -5696,7 +5863,7 @@ var JobDispatcher = class {
|
|
|
5696
5863
|
for (const test of this._remainingByTestId.values()) {
|
|
5697
5864
|
if (!testIds.has(test.id))
|
|
5698
5865
|
continue;
|
|
5699
|
-
if (!this.
|
|
5866
|
+
if (!this._isStoppedByMaxFailures()) {
|
|
5700
5867
|
this._failTestWithErrors(test, errors);
|
|
5701
5868
|
errors = [];
|
|
5702
5869
|
}
|
|
@@ -5755,12 +5922,18 @@ var JobDispatcher = class {
|
|
|
5755
5922
|
serialSuite.allTests().forEach((test) => retryCandidates.add(test));
|
|
5756
5923
|
}
|
|
5757
5924
|
const remaining = [...this._remainingByTestId.values()];
|
|
5925
|
+
const isolatedRetries = [];
|
|
5758
5926
|
for (const test of retryCandidates) {
|
|
5759
|
-
if (test.results.length < test.retries + 1)
|
|
5760
|
-
|
|
5927
|
+
if (test.results.length < test.retries + 1) {
|
|
5928
|
+
if (this._testRun.config.retryStrategy === "immediate")
|
|
5929
|
+
remaining.push(test);
|
|
5930
|
+
else
|
|
5931
|
+
isolatedRetries.push(test);
|
|
5932
|
+
}
|
|
5761
5933
|
}
|
|
5762
|
-
const
|
|
5763
|
-
|
|
5934
|
+
const remainingJob = remaining.length ? { ...this.job, tests: remaining } : void 0;
|
|
5935
|
+
const isolatedRetriesJob = isolatedRetries.length ? { ...this.job, tests: isolatedRetries } : void 0;
|
|
5936
|
+
this._finished({ didFail: true, remainingJob, isolatedRetriesJob });
|
|
5764
5937
|
}
|
|
5765
5938
|
onExit(data) {
|
|
5766
5939
|
const unexpectedExitError = data.unexpectedly ? {
|
|
@@ -5778,7 +5951,7 @@ var JobDispatcher = class {
|
|
|
5778
5951
|
const runPayload = {
|
|
5779
5952
|
file: this.job.requireFile,
|
|
5780
5953
|
entries: this.job.tests.map((test) => {
|
|
5781
|
-
return { testId: test.id, retry: test.results.length };
|
|
5954
|
+
return { testId: test.id, retry: test.results.length, planAnnotations: test._planAnnotations };
|
|
5782
5955
|
})
|
|
5783
5956
|
};
|
|
5784
5957
|
worker.runTestGroup(runPayload);
|
|
@@ -5807,7 +5980,7 @@ var JobDispatcher = class {
|
|
|
5807
5980
|
addLocationAndSnippetToError(this._testRun.config.config, response.error);
|
|
5808
5981
|
return response;
|
|
5809
5982
|
} catch (e) {
|
|
5810
|
-
const error = (0,
|
|
5983
|
+
const error = (0, import_util11.serializeError)(e);
|
|
5811
5984
|
addLocationAndSnippetToError(this._testRun.config.config, error);
|
|
5812
5985
|
return { response: void 0, error };
|
|
5813
5986
|
}
|
|
@@ -5822,7 +5995,7 @@ var JobDispatcher = class {
|
|
|
5822
5995
|
}
|
|
5823
5996
|
skipWholeJob() {
|
|
5824
5997
|
const allTestsSkipped = this.job.tests.every((test) => test.expectedStatus === "skipped");
|
|
5825
|
-
if (allTestsSkipped && !this.
|
|
5998
|
+
if (allTestsSkipped && !this._isStoppedByMaxFailures()) {
|
|
5826
5999
|
for (const test of this.job.tests) {
|
|
5827
6000
|
const result = test._appendTestResult();
|
|
5828
6001
|
this._testRun.reporter.onTestBegin?.(test, result);
|
|
@@ -5839,11 +6012,11 @@ var JobDispatcher = class {
|
|
|
5839
6012
|
}
|
|
5840
6013
|
_reportTestEnd(test, result) {
|
|
5841
6014
|
this._testRun.reporter.onTestEnd?.(test, result);
|
|
5842
|
-
const hadMaxFailures = this.
|
|
6015
|
+
const hadMaxFailures = this._isStoppedByMaxFailures();
|
|
5843
6016
|
if (test.outcome() === "unexpected" && test.results.length > test.retries)
|
|
5844
6017
|
++this._testRun.failedTestCount;
|
|
5845
|
-
if (!hadMaxFailures && this.
|
|
5846
|
-
this.
|
|
6018
|
+
if (!hadMaxFailures && this._isStoppedByMaxFailures()) {
|
|
6019
|
+
this._onMaxFailuresReached?.();
|
|
5847
6020
|
this._testRun.reporter.onError?.({ message: colors4.red(`Testing stopped early after ${this._testRun.config.config.maxFailures} maximum allowed failures.`) });
|
|
5848
6021
|
}
|
|
5849
6022
|
}
|
|
@@ -5926,7 +6099,7 @@ var FixedNodeSIGINTHandler = class {
|
|
|
5926
6099
|
};
|
|
5927
6100
|
|
|
5928
6101
|
// packages/playwright/src/runner/taskRunner.ts
|
|
5929
|
-
var
|
|
6102
|
+
var import_util12 = require("../util");
|
|
5930
6103
|
var colors5 = require("playwright-core/lib/utilsBundle").colors;
|
|
5931
6104
|
var debug4 = require("playwright-core/lib/utilsBundle").debug;
|
|
5932
6105
|
var { ManualPromise: ManualPromise4 } = require("playwright-core/lib/coreBundle").iso;
|
|
@@ -5967,7 +6140,7 @@ var TaskRunner = class _TaskRunner {
|
|
|
5967
6140
|
await task.setup?.(context, errors, softErrors);
|
|
5968
6141
|
} catch (e) {
|
|
5969
6142
|
debug4("pw:test:task")(`error in "${task.title}": `, e);
|
|
5970
|
-
errors.push((0,
|
|
6143
|
+
errors.push((0, import_util12.serializeError)(e));
|
|
5971
6144
|
} finally {
|
|
5972
6145
|
for (const error of [...softErrors, ...errors])
|
|
5973
6146
|
this._reporter.onError?.(error);
|
|
@@ -6030,7 +6203,7 @@ var TimeoutWatcher = class {
|
|
|
6030
6203
|
// packages/playwright/src/runner/vcs.ts
|
|
6031
6204
|
var import_child_process2 = __toESM(require("child_process"));
|
|
6032
6205
|
var import_path14 = __toESM(require("path"));
|
|
6033
|
-
var
|
|
6206
|
+
var import_common8 = require("../common");
|
|
6034
6207
|
async function detectChangedTestFiles(baseCommit, configDir) {
|
|
6035
6208
|
function gitFileList(args) {
|
|
6036
6209
|
try {
|
|
@@ -6062,17 +6235,17 @@ async function detectChangedTestFiles(baseCommit, configDir) {
|
|
|
6062
6235
|
const untrackedFiles = gitFileList(["ls-files", "--others", "--exclude-standard"]).map((file) => import_path14.default.join(configDir, file));
|
|
6063
6236
|
const [gitRoot] = gitFileList(["rev-parse", "--show-toplevel"]);
|
|
6064
6237
|
const trackedFilesWithChanges = gitFileList(["diff", baseCommit, "--name-only"]).map((file) => import_path14.default.join(gitRoot, file));
|
|
6065
|
-
return new Set(
|
|
6238
|
+
return new Set(import_common8.cc.affectedTestFiles([...untrackedFiles, ...trackedFilesWithChanges]));
|
|
6066
6239
|
}
|
|
6067
6240
|
|
|
6068
6241
|
// packages/playwright/src/runner/tasks.ts
|
|
6069
|
-
var
|
|
6070
|
-
var
|
|
6242
|
+
var import_common9 = require("../common");
|
|
6243
|
+
var import_util14 = require("../util");
|
|
6071
6244
|
var debug5 = require("playwright-core/lib/utilsBundle").debug;
|
|
6072
6245
|
var { ManualPromise: ManualPromise5 } = require("playwright-core/lib/coreBundle").iso;
|
|
6073
6246
|
var { monotonicTime: monotonicTime6 } = require("playwright-core/lib/coreBundle").iso;
|
|
6074
6247
|
var { removeFolders: removeFolders4 } = require("playwright-core/lib/coreBundle").utils;
|
|
6075
|
-
var readDirAsync2 = (0,
|
|
6248
|
+
var readDirAsync2 = (0, import_util13.promisify)(import_fs11.default.readdir);
|
|
6076
6249
|
var TestRun = class {
|
|
6077
6250
|
constructor(config2, reporter, options) {
|
|
6078
6251
|
this.rootSuite = void 0;
|
|
@@ -6100,7 +6273,7 @@ var TestRun = class {
|
|
|
6100
6273
|
result() {
|
|
6101
6274
|
const hasFailedTests = this.rootSuite?.allTests().some((test) => !test.ok());
|
|
6102
6275
|
const hasFlakyTests = this.rootSuite?.allTests().some((test) => test.outcome() === "flaky");
|
|
6103
|
-
return this.hasWorkerErrors || this.hasReachedMaxFailures() || hasFailedTests || this.config.failOnFlakyTests && hasFlakyTests ? "failed" : "passed";
|
|
6276
|
+
return this.hasWorkerErrors || this.reporter.hasReporterErrors() || this.hasReachedMaxFailures() || hasFailedTests || this.config.config.failOnFlakyTests && hasFlakyTests ? "failed" : "passed";
|
|
6104
6277
|
}
|
|
6105
6278
|
};
|
|
6106
6279
|
async function runTasks(testRun, tasks, globalTimeout, cancelPromise) {
|
|
@@ -6127,6 +6300,8 @@ async function finishTaskRun(testRun, status) {
|
|
|
6127
6300
|
if (modifiedResult && modifiedResult.status)
|
|
6128
6301
|
status = modifiedResult.status;
|
|
6129
6302
|
await testRun.reporter.onExit();
|
|
6303
|
+
if (status === "passed" && testRun.reporter.hasReporterErrors())
|
|
6304
|
+
status = "failed";
|
|
6130
6305
|
return status;
|
|
6131
6306
|
}
|
|
6132
6307
|
function createGlobalSetupTasks(config2) {
|
|
@@ -6149,7 +6324,7 @@ function createClearCacheTask(config2) {
|
|
|
6149
6324
|
return {
|
|
6150
6325
|
title: "clear cache",
|
|
6151
6326
|
setup: async () => {
|
|
6152
|
-
await (0,
|
|
6327
|
+
await (0, import_util14.removeDirAndLogToConsole)(import_common9.cc.cacheDir);
|
|
6153
6328
|
for (const plugin of config2.plugins)
|
|
6154
6329
|
await plugin.instance?.clearCache?.();
|
|
6155
6330
|
}
|
|
@@ -6248,12 +6423,12 @@ function createListFilesTask() {
|
|
|
6248
6423
|
await createRootSuite(testRun, errors, false);
|
|
6249
6424
|
await collectProjectsAndTestFiles(testRun, false);
|
|
6250
6425
|
for (const [project, files] of testRun.projectFiles) {
|
|
6251
|
-
const projectSuite = new
|
|
6426
|
+
const projectSuite = new import_common9.test.Suite(project.project.name, "project");
|
|
6252
6427
|
projectSuite._fullProject = project;
|
|
6253
6428
|
testRun.rootSuite._addSuite(projectSuite);
|
|
6254
6429
|
const suites = files.map((file) => {
|
|
6255
6430
|
const title = import_path15.default.relative(testRun.config.config.rootDir, file);
|
|
6256
|
-
const suite = new
|
|
6431
|
+
const suite = new import_common9.test.Suite(title, "file");
|
|
6257
6432
|
suite.location = { file, line: 0, column: 0 };
|
|
6258
6433
|
projectSuite._addSuite(suite);
|
|
6259
6434
|
return suite;
|
|
@@ -6268,7 +6443,7 @@ function createLoadTask(mode, options) {
|
|
|
6268
6443
|
title: "load tests",
|
|
6269
6444
|
setup: async (testRun, errors, softErrors) => {
|
|
6270
6445
|
if (testRun.options.locations?.length) {
|
|
6271
|
-
const { testFilter, fileFilter } =
|
|
6446
|
+
const { testFilter, fileFilter } = import_common9.suiteUtils.createFiltersFromArguments(testRun.options.locations);
|
|
6272
6447
|
testRun.loadFileFilters.push(fileFilter);
|
|
6273
6448
|
testRun.preOnlyTestFilters.push(testFilter);
|
|
6274
6449
|
}
|
|
@@ -6282,14 +6457,14 @@ function createLoadTask(mode, options) {
|
|
|
6282
6457
|
testRun.preOnlyTestFilters.push((test) => !testFilter(test));
|
|
6283
6458
|
}
|
|
6284
6459
|
if (testRun.options.grep || testRun.options.grepInvert) {
|
|
6285
|
-
const grepMatcher = testRun.options.grep ? (0,
|
|
6286
|
-
const grepInvertMatcher = testRun.options.grepInvert ? (0,
|
|
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;
|
|
6287
6462
|
testRun.preOnlyTestFilters.push((test) => {
|
|
6288
6463
|
const grepTitle = test._grepTitleWithTags();
|
|
6289
6464
|
return !grepInvertMatcher(grepTitle) && grepMatcher(grepTitle);
|
|
6290
6465
|
});
|
|
6291
6466
|
}
|
|
6292
|
-
if (testRun.options.lastFailedTestIds
|
|
6467
|
+
if (testRun.options.lastFailedTestIds) {
|
|
6293
6468
|
const failedTestIds = new Set(testRun.options.lastFailedTestIds);
|
|
6294
6469
|
testRun.postShardTestFilters.push((test) => failedTestIds.has(test.id));
|
|
6295
6470
|
}
|
|
@@ -6337,6 +6512,7 @@ function createPhasesTask() {
|
|
|
6337
6512
|
const projectToSuite = new Map(testRun.rootSuite.suites.map((suite) => [suite._fullProject, suite]));
|
|
6338
6513
|
const allProjects = [...projectToSuite.keys()];
|
|
6339
6514
|
const teardownToSetups = buildTeardownToSetupsMap(allProjects);
|
|
6515
|
+
const ignoreMaxFailuresProjectIds = new Set(testRun.config.config.maxFailures > 0 ? [...teardownToSetups.keys()].map((project) => project.id) : []);
|
|
6340
6516
|
const teardownToSetupsDependents = /* @__PURE__ */ new Map();
|
|
6341
6517
|
for (const [teardown, setups] of teardownToSetups) {
|
|
6342
6518
|
const closure = buildDependentProjects(setups, allProjects);
|
|
@@ -6355,11 +6531,14 @@ function createPhasesTask() {
|
|
|
6355
6531
|
}
|
|
6356
6532
|
for (const project of phaseProjects)
|
|
6357
6533
|
processed.add(project);
|
|
6358
|
-
|
|
6534
|
+
for (const ignoreMaxFailures of [false, true]) {
|
|
6535
|
+
const projects = phaseProjects.filter((project) => ignoreMaxFailuresProjectIds.has(project.id) === ignoreMaxFailures);
|
|
6536
|
+
if (!projects.length)
|
|
6537
|
+
continue;
|
|
6359
6538
|
let testGroupsInPhase = 0;
|
|
6360
|
-
const phase = { dispatcher: new Dispatcher(testRun), projects: [] };
|
|
6539
|
+
const phase = { dispatcher: new Dispatcher(testRun, { ignoreMaxFailures }), projects: [] };
|
|
6361
6540
|
testRun.phases.push(phase);
|
|
6362
|
-
for (const project of
|
|
6541
|
+
for (const project of projects) {
|
|
6363
6542
|
const projectSuite = projectToSuite.get(project);
|
|
6364
6543
|
const testGroups = createTestGroups(projectSuite, testRun.config.config.workers);
|
|
6365
6544
|
phase.projects.push({ project, projectSuite, testGroups });
|
|
@@ -6421,20 +6600,25 @@ function createRunTestsTask() {
|
|
|
6421
6600
|
var import_fs12 = __toESM(require("fs"));
|
|
6422
6601
|
var import_path16 = __toESM(require("path"));
|
|
6423
6602
|
var LastRunReporter = class {
|
|
6424
|
-
constructor(filteredProjects, listMode) {
|
|
6603
|
+
constructor(filteredProjects, listMode, lastFailedFileOverride) {
|
|
6425
6604
|
this._listMode = !!listMode;
|
|
6426
|
-
const
|
|
6427
|
-
if (
|
|
6428
|
-
this._lastRunFile = import_path16.default.
|
|
6605
|
+
const override = lastFailedFileOverride ?? process.env.PLAYWRIGHT_LAST_RUN_OUTPUT_FILE;
|
|
6606
|
+
if (override) {
|
|
6607
|
+
this._lastRunFile = import_path16.default.resolve(process.cwd(), override);
|
|
6608
|
+
} else {
|
|
6609
|
+
const [project] = filteredProjects;
|
|
6610
|
+
if (project)
|
|
6611
|
+
this._lastRunFile = import_path16.default.join(project.project.outputDir, ".last-run.json");
|
|
6612
|
+
}
|
|
6429
6613
|
}
|
|
6430
6614
|
async filterLastFailed() {
|
|
6431
6615
|
if (!this._lastRunFile)
|
|
6432
|
-
return
|
|
6616
|
+
return void 0;
|
|
6433
6617
|
try {
|
|
6434
6618
|
const lastRunInfo = JSON.parse(await import_fs12.default.promises.readFile(this._lastRunFile, "utf8"));
|
|
6435
6619
|
return lastRunInfo.failedTests;
|
|
6436
6620
|
} catch {
|
|
6437
|
-
return
|
|
6621
|
+
return void 0;
|
|
6438
6622
|
}
|
|
6439
6623
|
}
|
|
6440
6624
|
version() {
|
|
@@ -6480,7 +6664,7 @@ var TestRunner = class extends import_events2.default {
|
|
|
6480
6664
|
this._configCLIOverrides = configCLIOverrides;
|
|
6481
6665
|
this._watcher = new FSWatcher((events) => {
|
|
6482
6666
|
const collector = /* @__PURE__ */ new Set();
|
|
6483
|
-
events.forEach((f) =>
|
|
6667
|
+
events.forEach((f) => import_common10.cc.collectAffectedTestFiles(f.file, collector));
|
|
6484
6668
|
this.emit(TestRunnerEvent.TestFilesChanged, [...collector]);
|
|
6485
6669
|
});
|
|
6486
6670
|
}
|
|
@@ -6649,7 +6833,8 @@ var TestRunner = class extends import_events2.default {
|
|
|
6649
6833
|
},
|
|
6650
6834
|
...params.updateSnapshots ? { updateSnapshots: params.updateSnapshots } : {},
|
|
6651
6835
|
...params.updateSourceMethod ? { updateSourceMethod: params.updateSourceMethod } : {},
|
|
6652
|
-
...params.workers ? { workers: params.workers } : {}
|
|
6836
|
+
...params.workers ? { workers: params.workers } : {},
|
|
6837
|
+
...params.maxFailures ? { maxFailures: params.maxFailures } : {}
|
|
6653
6838
|
};
|
|
6654
6839
|
const config2 = await this._loadConfigOrReportError(new InternalReporter([userReporter]), overrides);
|
|
6655
6840
|
if (!config2)
|
|
@@ -6689,7 +6874,7 @@ var TestRunner = class extends import_events2.default {
|
|
|
6689
6874
|
this._watchedTestDependencies = /* @__PURE__ */ new Set();
|
|
6690
6875
|
for (const fileName of fileNames) {
|
|
6691
6876
|
this._watchedTestDependencies.add(fileName);
|
|
6692
|
-
|
|
6877
|
+
import_common10.cc.dependenciesForTestFile(fileName).forEach((file) => this._watchedTestDependencies.add(file));
|
|
6693
6878
|
}
|
|
6694
6879
|
await this._updateWatcher(true);
|
|
6695
6880
|
}
|
|
@@ -6705,7 +6890,7 @@ var TestRunner = class extends import_events2.default {
|
|
|
6705
6890
|
]);
|
|
6706
6891
|
if (status !== "passed")
|
|
6707
6892
|
return { errors: errorReporter.errors(), testFiles: [] };
|
|
6708
|
-
return { testFiles:
|
|
6893
|
+
return { testFiles: import_common10.cc.affectedTestFiles(files) };
|
|
6709
6894
|
}
|
|
6710
6895
|
async stopTests() {
|
|
6711
6896
|
this._testRun?.stop?.resolve();
|
|
@@ -6719,7 +6904,7 @@ var TestRunner = class extends import_events2.default {
|
|
|
6719
6904
|
}
|
|
6720
6905
|
async _loadConfig(overrides) {
|
|
6721
6906
|
try {
|
|
6722
|
-
const config2 = await
|
|
6907
|
+
const config2 = await import_common10.configLoader.loadConfig(this.configLocation, overrides);
|
|
6723
6908
|
if (!this._plugins) {
|
|
6724
6909
|
webServerPluginsForConfig(config2).forEach((p) => config2.plugins.push({ factory: p }));
|
|
6725
6910
|
addGitCommitInfoPlugin(config2);
|
|
@@ -6727,11 +6912,15 @@ var TestRunner = class extends import_events2.default {
|
|
|
6727
6912
|
} else {
|
|
6728
6913
|
config2.plugins.splice(0, config2.plugins.length, ...this._plugins);
|
|
6729
6914
|
}
|
|
6915
|
+
this._lastLoadedConfig = config2;
|
|
6730
6916
|
return { config: config2 };
|
|
6731
6917
|
} catch (e) {
|
|
6732
|
-
return { config: null, error: (0,
|
|
6918
|
+
return { config: null, error: (0, import_util15.serializeError)(e) };
|
|
6733
6919
|
}
|
|
6734
6920
|
}
|
|
6921
|
+
lastLoadedConfig() {
|
|
6922
|
+
return this._lastLoadedConfig;
|
|
6923
|
+
}
|
|
6735
6924
|
async _loadConfigOrReportError(reporter, overrides) {
|
|
6736
6925
|
const { config: config2, error } = await this._loadConfig(overrides);
|
|
6737
6926
|
if (config2)
|
|
@@ -6764,10 +6953,10 @@ async function runAllTestsWithConfig(config2, options) {
|
|
|
6764
6953
|
webServerPluginsForConfig(config2).forEach((p) => config2.plugins.push({ factory: p }));
|
|
6765
6954
|
const filteredProjects = filterProjects(config2.projects, options.projectFilter);
|
|
6766
6955
|
const reporters = await createReporters(config2, options.listMode ? "list" : "test", void 0, options);
|
|
6767
|
-
const lastRun = new LastRunReporter(filteredProjects, options.listMode);
|
|
6956
|
+
const lastRun = new LastRunReporter(filteredProjects, options.listMode, options.lastFailedFile);
|
|
6768
6957
|
if (options.lastFailed) {
|
|
6769
6958
|
const lastFailedTestIds = await lastRun.filterLastFailed();
|
|
6770
|
-
if (lastFailedTestIds
|
|
6959
|
+
if (lastFailedTestIds)
|
|
6771
6960
|
options = { ...options, lastFailedTestIds };
|
|
6772
6961
|
}
|
|
6773
6962
|
const reporter = new InternalReporter([...reporters, lastRun]);
|
|
@@ -6794,9 +6983,9 @@ __export(testServer_exports, {
|
|
|
6794
6983
|
runTestServer: () => runTestServer,
|
|
6795
6984
|
runUIMode: () => runUIMode
|
|
6796
6985
|
});
|
|
6797
|
-
var
|
|
6986
|
+
var import_util16 = __toESM(require("util"));
|
|
6798
6987
|
var import_coreBundle3 = require("playwright-core/lib/coreBundle");
|
|
6799
|
-
var
|
|
6988
|
+
var import_common11 = require("../common");
|
|
6800
6989
|
|
|
6801
6990
|
// packages/playwright/src/runner/uiModeReporter.ts
|
|
6802
6991
|
var UIModeReporter = class extends TeleReporterEmitter {
|
|
@@ -6824,7 +7013,23 @@ var TestServer = class {
|
|
|
6824
7013
|
}
|
|
6825
7014
|
async start(options) {
|
|
6826
7015
|
this._dispatcher = new TestServerDispatcher(this._configLocation, this._configCLIOverrides);
|
|
6827
|
-
return await import_coreBundle3.server.startTraceViewerServer({
|
|
7016
|
+
return await import_coreBundle3.server.startTraceViewerServer({
|
|
7017
|
+
host: options.host,
|
|
7018
|
+
port: options.port,
|
|
7019
|
+
allowedFileRoots: () => this._allowedFileRoots(),
|
|
7020
|
+
transport: this._dispatcher.transport
|
|
7021
|
+
});
|
|
7022
|
+
}
|
|
7023
|
+
_allowedFileRoots() {
|
|
7024
|
+
const roots = /* @__PURE__ */ new Set([process.cwd(), this._configLocation.configDir]);
|
|
7025
|
+
const config2 = this._dispatcher?._testRunner.lastLoadedConfig();
|
|
7026
|
+
if (config2) {
|
|
7027
|
+
for (const project of config2.projects) {
|
|
7028
|
+
roots.add(project.project.outputDir);
|
|
7029
|
+
roots.add(project.project.testDir);
|
|
7030
|
+
}
|
|
7031
|
+
}
|
|
7032
|
+
return [...roots];
|
|
6828
7033
|
}
|
|
6829
7034
|
async stop() {
|
|
6830
7035
|
await this._dispatcher?.stop();
|
|
@@ -6938,7 +7143,7 @@ var TestServerDispatcher = class {
|
|
|
6938
7143
|
if (interceptStdio) {
|
|
6939
7144
|
if (debug6.log === originalDebugLog) {
|
|
6940
7145
|
debug6.log = (...args) => {
|
|
6941
|
-
const string =
|
|
7146
|
+
const string = import_util16.default.format(...args) + "\n";
|
|
6942
7147
|
return originalStderrWrite.apply(process.stderr, [string]);
|
|
6943
7148
|
};
|
|
6944
7149
|
}
|
|
@@ -6962,7 +7167,7 @@ var TestServerDispatcher = class {
|
|
|
6962
7167
|
}
|
|
6963
7168
|
};
|
|
6964
7169
|
async function runUIMode(configFile, configCLIOverrides, options) {
|
|
6965
|
-
const configLocation =
|
|
7170
|
+
const configLocation = import_common11.configLoader.resolveConfigLocation(configFile);
|
|
6966
7171
|
return await innerRunTestServer(configLocation, configCLIOverrides, options, async (server, cancelPromise) => {
|
|
6967
7172
|
await import_coreBundle3.server.installRootRedirect(server, void 0, { ...options, webApp: "uiMode.html" });
|
|
6968
7173
|
if (options.host !== void 0 || options.port !== void 0) {
|
|
@@ -6981,7 +7186,7 @@ async function runUIMode(configFile, configCLIOverrides, options) {
|
|
|
6981
7186
|
});
|
|
6982
7187
|
}
|
|
6983
7188
|
async function installedChromiumChannelForUI(configLocation, configCLIOverrides) {
|
|
6984
|
-
const config2 = await
|
|
7189
|
+
const config2 = await import_common11.configLoader.loadConfig(configLocation, configCLIOverrides).catch((e) => null);
|
|
6985
7190
|
if (!config2)
|
|
6986
7191
|
return void 0;
|
|
6987
7192
|
if (config2.projects.some((p) => (!p.project.use.browserName || p.project.use.browserName === "chromium") && !p.project.use.channel))
|
|
@@ -6993,7 +7198,7 @@ async function installedChromiumChannelForUI(configLocation, configCLIOverrides)
|
|
|
6993
7198
|
return void 0;
|
|
6994
7199
|
}
|
|
6995
7200
|
async function runTestServer(configFile, configCLIOverrides, options) {
|
|
6996
|
-
const configLocation =
|
|
7201
|
+
const configLocation = import_common11.configLoader.resolveConfigLocation(configFile);
|
|
6997
7202
|
return await innerRunTestServer(configLocation, configCLIOverrides, options, async (server) => {
|
|
6998
7203
|
console.log("Listening on " + server.urlPrefix("precise").replace("http:", "ws:") + "/" + server.wsGuid());
|
|
6999
7204
|
});
|
|
@@ -7033,11 +7238,11 @@ __export(watchMode_exports, {
|
|
|
7033
7238
|
});
|
|
7034
7239
|
var import_path18 = __toESM(require("path"));
|
|
7035
7240
|
var import_readline = __toESM(require("readline"));
|
|
7036
|
-
var
|
|
7241
|
+
var import_events3 = require("events");
|
|
7037
7242
|
var import_coreBundle4 = require("playwright-core/lib/coreBundle");
|
|
7038
7243
|
|
|
7039
7244
|
// packages/playwright/src/isomorphic/testTree.ts
|
|
7040
|
-
var statusEx = Symbol("statusEx");
|
|
7245
|
+
var statusEx = /* @__PURE__ */ Symbol("statusEx");
|
|
7041
7246
|
|
|
7042
7247
|
// packages/playwright/src/isomorphic/teleSuiteUpdater.ts
|
|
7043
7248
|
var TeleSuiteUpdater = class {
|
|
@@ -7380,7 +7585,7 @@ var { ManualPromise: ManualPromise8 } = require("playwright-core/lib/coreBundle"
|
|
|
7380
7585
|
var { createGuid: createGuid3 } = require("playwright-core/lib/coreBundle").utils;
|
|
7381
7586
|
var { getPackageManagerExecCommand: getPackageManagerExecCommand3 } = require("playwright-core/lib/coreBundle").utils;
|
|
7382
7587
|
var { eventsHelper: eventsHelper2 } = require("playwright-core/lib/coreBundle").utils;
|
|
7383
|
-
var InMemoryTransport = class extends
|
|
7588
|
+
var InMemoryTransport = class extends import_events3.EventEmitter {
|
|
7384
7589
|
constructor(send) {
|
|
7385
7590
|
super();
|
|
7386
7591
|
this._send = send;
|
|
@@ -7780,7 +7985,7 @@ var JsonStringInternalizer = class {
|
|
|
7780
7985
|
};
|
|
7781
7986
|
|
|
7782
7987
|
// packages/playwright/src/reporters/merge.ts
|
|
7783
|
-
var
|
|
7988
|
+
var import_util17 = require("../util");
|
|
7784
7989
|
var { isPathInside } = require("playwright-core/lib/coreBundle").utils;
|
|
7785
7990
|
var { ZipFile } = require("playwright-core/lib/coreBundle").utils;
|
|
7786
7991
|
async function createMergedReport(config2, dir, reporterDescriptions, rootDirOverride) {
|
|
@@ -7845,6 +8050,7 @@ async function createMergedReport(config2, dir, reporterDescriptions, rootDirOve
|
|
|
7845
8050
|
});
|
|
7846
8051
|
}
|
|
7847
8052
|
await dispatchEvents(eventData.epilogue);
|
|
8053
|
+
return multiplexer.hasReporterErrors() ? "failed" : "passed";
|
|
7848
8054
|
}
|
|
7849
8055
|
var commonEventNames = ["onBlobReportMetadata", "onConfigure", "onProject", "onBegin", "onEnd"];
|
|
7850
8056
|
var commonEvents = new Set(commonEventNames);
|
|
@@ -7875,7 +8081,7 @@ async function extractAndParseReports(dir, shardFiles, internalizer, printStatus
|
|
|
7875
8081
|
const reportNames = new UniqueFileNameGenerator();
|
|
7876
8082
|
for (const file of shardFiles) {
|
|
7877
8083
|
const absolutePath = import_path19.default.join(dir, file);
|
|
7878
|
-
printStatus(`extracting: ${(0,
|
|
8084
|
+
printStatus(`extracting: ${(0, import_util17.relativeFilePath)(absolutePath)}`);
|
|
7879
8085
|
const zipFile = new ZipFile(absolutePath);
|
|
7880
8086
|
const entryNames = await zipFile.entries();
|
|
7881
8087
|
for (const entryName of entryNames.sort()) {
|