as-test 1.1.1 → 1.1.2
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/CHANGELOG.md +8 -3
- package/README.md +14 -7
- package/as-test.config.schema.json +142 -142
- package/assembly/__fuzz__/math.fuzz.ts +17 -14
- package/assembly/__fuzz__/seed-perf.fuzz.ts +4 -2
- package/assembly/index.ts +1 -4
- package/assembly/src/expectation.ts +7 -1
- package/assembly/src/fuzz.ts +44 -23
- package/assembly/util/format.ts +10 -1
- package/assembly/util/wipc.ts +1 -2
- package/bin/build-worker-pool.js +7 -1
- package/bin/commands/build-core.js +6 -1
- package/bin/commands/build.js +1 -1
- package/bin/commands/clean-core.js +3 -1
- package/bin/commands/clean.js +0 -37
- package/bin/commands/fuzz-core.js +2 -2
- package/bin/commands/run-core.js +35 -24
- package/bin/commands/web-runner-source.js +14 -14
- package/bin/commands/web-session.js +6 -1
- package/bin/crash-store.js +3 -1
- package/bin/index.js +301 -123
- package/bin/reporters/default.js +175 -33
- package/bin/util.js +36 -11
- package/lib/build/index.js +74 -24
- package/lib/src/index.ts +96 -35
- package/package.json +1 -1
- package/transform/lib/coverage.js +3 -1
package/bin/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
-
import { build, formatInvocation as formatBuildInvocation, getBuildInvocationPreview, } from "./commands/build.js";
|
|
3
|
+
import { build, BuildFailureError, formatInvocation as formatBuildInvocation, getBuildInvocationPreview, } from "./commands/build.js";
|
|
4
4
|
import { createRunReporter, run } from "./commands/run.js";
|
|
5
5
|
import { executeBuildCommand } from "./commands/build.js";
|
|
6
6
|
import { executeRunCommand } from "./commands/run.js";
|
|
@@ -10,7 +10,7 @@ import { executeInitCommand } from "./commands/init.js";
|
|
|
10
10
|
import { executeDoctorCommand } from "./commands/doctor.js";
|
|
11
11
|
import { executeCleanCommand } from "./commands/clean.js";
|
|
12
12
|
import { fuzz } from "./commands/fuzz-core.js";
|
|
13
|
-
import { applyMode,
|
|
13
|
+
import { applyMode, formatTime, formatSpecDisplayPath, getDefaultModeNames, getCliVersion, loadConfig, resolveModeNames, } from "./util.js";
|
|
14
14
|
import * as path from "path";
|
|
15
15
|
import { spawnSync } from "child_process";
|
|
16
16
|
import { glob } from "glob";
|
|
@@ -374,7 +374,6 @@ function printCommandHelp(command) {
|
|
|
374
374
|
process.stdout.write(chalk.bold("Flags:\n"));
|
|
375
375
|
process.stdout.write(" --config <path> Use a specific config file\n");
|
|
376
376
|
process.stdout.write(" --mode <name[,name...]> Clean one or multiple named modes\n");
|
|
377
|
-
process.stdout.write(" -f, --force Skip the full-clean confirmation prompt\n");
|
|
378
377
|
process.stdout.write(" --help, -h Show this help\n");
|
|
379
378
|
return;
|
|
380
379
|
}
|
|
@@ -1070,10 +1069,12 @@ function resolveCommandTokens(rawArgs, command) {
|
|
|
1070
1069
|
}
|
|
1071
1070
|
async function buildFileForMode(args) {
|
|
1072
1071
|
if (args.buildPool) {
|
|
1072
|
+
const buildInvocation = await getBuildInvocationPreview(args.configPath, args.file, args.modeName, args.buildFeatureToggles);
|
|
1073
1073
|
await args.buildPool.buildFileMode({
|
|
1074
1074
|
configPath: args.configPath,
|
|
1075
1075
|
file: args.file,
|
|
1076
1076
|
modeName: args.modeName,
|
|
1077
|
+
buildCommand: formatBuildInvocation(buildInvocation),
|
|
1077
1078
|
featureToggles: args.buildFeatureToggles,
|
|
1078
1079
|
});
|
|
1079
1080
|
}
|
|
@@ -1104,21 +1105,30 @@ async function runTestSequential(runFlags, configPath, selectors, suiteSelectors
|
|
|
1104
1105
|
const duplicateSpecBasenames = resolveDuplicateSpecBasenames(files);
|
|
1105
1106
|
for (const file of files) {
|
|
1106
1107
|
const buildStartedAt = Date.now();
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1108
|
+
let result;
|
|
1109
|
+
try {
|
|
1110
|
+
await build(configPath, [file], modeName, buildFeatureToggles);
|
|
1111
|
+
buildIntervals.push({ start: buildStartedAt, end: Date.now() });
|
|
1112
|
+
const buildInvocation = await getBuildInvocationPreview(configPath, file, modeName, buildFeatureToggles);
|
|
1113
|
+
const artifactKey = resolvePerFileArtifactKey(file, duplicateSpecBasenames);
|
|
1114
|
+
result = await run(runFlags, configPath, [file], false, {
|
|
1115
|
+
reporter,
|
|
1116
|
+
webSession,
|
|
1117
|
+
suiteSelectors,
|
|
1118
|
+
emitRunStart: false,
|
|
1119
|
+
emitRunComplete: false,
|
|
1120
|
+
logFileName: `test.${artifactKey}.log.json`,
|
|
1121
|
+
coverageFileName: `coverage.${artifactKey}.log.json`,
|
|
1122
|
+
buildCommand: formatBuildInvocation(buildInvocation),
|
|
1123
|
+
modeName,
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
catch (error) {
|
|
1127
|
+
const buildFailure = getBuildFailureErrorLike(error);
|
|
1128
|
+
if (!buildFailure)
|
|
1129
|
+
throw error;
|
|
1130
|
+
result = createBuildFailureRunResult(buildFailure);
|
|
1131
|
+
}
|
|
1122
1132
|
results.push(result);
|
|
1123
1133
|
if (result?.failed)
|
|
1124
1134
|
failed = true;
|
|
@@ -1305,7 +1315,7 @@ async function runRuntimeMatrix(runFlags, configPath, selectors, suiteSelectors,
|
|
|
1305
1315
|
const buildIntervals = [];
|
|
1306
1316
|
for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
|
|
1307
1317
|
const file = files[fileIndex];
|
|
1308
|
-
const fileName =
|
|
1318
|
+
const fileName = formatSpecDisplayPath(file);
|
|
1309
1319
|
const fileResults = [];
|
|
1310
1320
|
const modeTimes = modes.map(() => "...");
|
|
1311
1321
|
if (liveMatrix) {
|
|
@@ -1481,7 +1491,7 @@ async function runTestMatrix(runFlags, configPath, selectors, suiteSelectors, fu
|
|
|
1481
1491
|
const buildIntervals = [];
|
|
1482
1492
|
for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
|
|
1483
1493
|
const file = files[fileIndex];
|
|
1484
|
-
const fileName =
|
|
1494
|
+
const fileName = formatSpecDisplayPath(file);
|
|
1485
1495
|
const fileResults = [];
|
|
1486
1496
|
const modeTimes = modes.map(() => "...");
|
|
1487
1497
|
if (liveMatrix) {
|
|
@@ -1489,6 +1499,7 @@ async function runTestMatrix(runFlags, configPath, selectors, suiteSelectors, fu
|
|
|
1489
1499
|
}
|
|
1490
1500
|
for (let i = 0; i < modes.length; i++) {
|
|
1491
1501
|
const modeName = modes[i];
|
|
1502
|
+
let result;
|
|
1492
1503
|
try {
|
|
1493
1504
|
const buildStartedAt = Date.now();
|
|
1494
1505
|
await buildFileForMode({
|
|
@@ -1500,7 +1511,7 @@ async function runTestMatrix(runFlags, configPath, selectors, suiteSelectors, fu
|
|
|
1500
1511
|
buildIntervals.push({ start: buildStartedAt, end: Date.now() });
|
|
1501
1512
|
const buildInvocation = await getBuildInvocationPreview(configPath, file, modeName, buildFeatureToggles);
|
|
1502
1513
|
const artifactKey = resolvePerFileArtifactKey(file, duplicateSpecBasenames);
|
|
1503
|
-
|
|
1514
|
+
result = await run(runFlags, configPath, [file], false, {
|
|
1504
1515
|
reporter: silentReporter,
|
|
1505
1516
|
reporterKind: "default",
|
|
1506
1517
|
emitRunStart: false,
|
|
@@ -1510,23 +1521,27 @@ async function runTestMatrix(runFlags, configPath, selectors, suiteSelectors, fu
|
|
|
1510
1521
|
buildCommand: formatBuildInvocation(buildInvocation),
|
|
1511
1522
|
modeName,
|
|
1512
1523
|
});
|
|
1513
|
-
modeTimes[i] = formatMatrixModeTime(result.stats.time);
|
|
1514
|
-
if (liveMatrix) {
|
|
1515
|
-
renderMatrixLiveLine(fileName, modeLabels, modeTimes, showPerModeTimes);
|
|
1516
|
-
}
|
|
1517
|
-
if (result.failed) {
|
|
1518
|
-
modeState[i].failed = true;
|
|
1519
|
-
}
|
|
1520
|
-
else if (result.stats.passedFiles > 0) {
|
|
1521
|
-
modeState[i].passed = true;
|
|
1522
|
-
}
|
|
1523
|
-
fileResults.push(result);
|
|
1524
|
-
allResults.push(result);
|
|
1525
1524
|
}
|
|
1526
1525
|
catch (error) {
|
|
1527
|
-
|
|
1528
|
-
|
|
1526
|
+
const buildFailure = getBuildFailureErrorLike(error);
|
|
1527
|
+
if (!buildFailure) {
|
|
1528
|
+
clearLiveLine();
|
|
1529
|
+
throw error;
|
|
1530
|
+
}
|
|
1531
|
+
result = createBuildFailureRunResult(buildFailure);
|
|
1532
|
+
}
|
|
1533
|
+
modeTimes[i] = formatMatrixModeTime(result.stats.time);
|
|
1534
|
+
if (liveMatrix) {
|
|
1535
|
+
renderMatrixLiveLine(fileName, modeLabels, modeTimes, showPerModeTimes);
|
|
1536
|
+
}
|
|
1537
|
+
if (result.failed) {
|
|
1538
|
+
modeState[i].failed = true;
|
|
1529
1539
|
}
|
|
1540
|
+
else if (result.stats.passedFiles > 0) {
|
|
1541
|
+
modeState[i].passed = true;
|
|
1542
|
+
}
|
|
1543
|
+
fileResults.push(result);
|
|
1544
|
+
allResults.push(result);
|
|
1530
1545
|
}
|
|
1531
1546
|
if (reporterSession.reporterKind == "default") {
|
|
1532
1547
|
renderMatrixFileResult(fileName, modeLabels, fileResults, modeTimes, liveMatrix, showPerModeTimes);
|
|
@@ -1611,22 +1626,31 @@ async function runRuntimeSingleParallel(runFlags, configPath, selectors, suiteSe
|
|
|
1611
1626
|
const poolWidth = Math.max(runFlags.buildJobs, runFlags.runJobs);
|
|
1612
1627
|
await runOrderedPool(files, poolWidth, async (file, index) => {
|
|
1613
1628
|
const token = useQueueDisplay
|
|
1614
|
-
? renderQueuedFileStart(queueDisplay,
|
|
1629
|
+
? renderQueuedFileStart(queueDisplay, formatSpecDisplayPath(file))
|
|
1615
1630
|
: null;
|
|
1616
1631
|
const buffered = useQueueDisplay
|
|
1617
1632
|
? await createBufferedReporter(configPath, runFlags.reporterPath, modeName)
|
|
1618
1633
|
: null;
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1634
|
+
let result;
|
|
1635
|
+
try {
|
|
1636
|
+
result = await runLimit(() => run({ ...runFlags, clean: true }, configPath, [file], false, {
|
|
1637
|
+
reporter: buffered?.reporter,
|
|
1638
|
+
reporterKind: buffered?.reporterKind,
|
|
1639
|
+
modeName,
|
|
1640
|
+
suiteSelectors,
|
|
1641
|
+
emitRunComplete: false,
|
|
1642
|
+
fileSummaryTotal: 1,
|
|
1643
|
+
modeSummaryTotal,
|
|
1644
|
+
modeSummaryExecuted: 1,
|
|
1645
|
+
buildCommandsByFile: { [file]: buildCommandsByFile[file] ?? "" },
|
|
1646
|
+
}));
|
|
1647
|
+
}
|
|
1648
|
+
catch (error) {
|
|
1649
|
+
const buildFailure = getBuildFailureErrorLike(error);
|
|
1650
|
+
if (!buildFailure)
|
|
1651
|
+
throw error;
|
|
1652
|
+
result = createBuildFailureRunResult(buildFailure);
|
|
1653
|
+
}
|
|
1630
1654
|
buffered?.reporter.flush?.();
|
|
1631
1655
|
results[index] = result;
|
|
1632
1656
|
if (buffered && token != null) {
|
|
@@ -1677,7 +1701,7 @@ async function runRuntimeMatrixParallel(runFlags, configPath, selectors, suiteSe
|
|
|
1677
1701
|
const buildIntervals = [];
|
|
1678
1702
|
try {
|
|
1679
1703
|
await runOrderedPool(files, poolWidth, async (file, fileIndex) => {
|
|
1680
|
-
const fileName =
|
|
1704
|
+
const fileName = formatSpecDisplayPath(file);
|
|
1681
1705
|
const token = useQueueDisplay
|
|
1682
1706
|
? renderQueuedFileStart(queueDisplay, fileName)
|
|
1683
1707
|
: null;
|
|
@@ -1685,28 +1709,37 @@ async function runRuntimeMatrixParallel(runFlags, configPath, selectors, suiteSe
|
|
|
1685
1709
|
const modeTimes = modes.map(() => "...");
|
|
1686
1710
|
for (let i = 0; i < modes.length; i++) {
|
|
1687
1711
|
const modeName = modes[i];
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1712
|
+
let result;
|
|
1713
|
+
try {
|
|
1714
|
+
const buildStartedAt = Date.now();
|
|
1715
|
+
await buildFileForMode({
|
|
1716
|
+
configPath,
|
|
1717
|
+
file,
|
|
1718
|
+
modeName,
|
|
1719
|
+
buildFeatureToggles: {},
|
|
1720
|
+
buildPool,
|
|
1721
|
+
});
|
|
1722
|
+
buildIntervals.push({ start: buildStartedAt, end: Date.now() });
|
|
1723
|
+
const buildInvocation = await getBuildInvocationPreview(configPath, file, modeName, {});
|
|
1724
|
+
const artifactKey = resolvePerFileArtifactKey(file, duplicateSpecBasenames);
|
|
1725
|
+
result = await run(runFlags, configPath, [file], false, {
|
|
1726
|
+
reporter: silentReporter,
|
|
1727
|
+
reporterKind: "default",
|
|
1728
|
+
suiteSelectors,
|
|
1729
|
+
emitRunStart: false,
|
|
1730
|
+
emitRunComplete: false,
|
|
1731
|
+
logFileName: `run.${artifactKey}.log.json`,
|
|
1732
|
+
coverageFileName: `coverage.${artifactKey}.log.json`,
|
|
1733
|
+
buildCommand: formatBuildInvocation(buildInvocation),
|
|
1734
|
+
modeName,
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1737
|
+
catch (error) {
|
|
1738
|
+
const buildFailure = getBuildFailureErrorLike(error);
|
|
1739
|
+
if (!buildFailure)
|
|
1740
|
+
throw error;
|
|
1741
|
+
result = createBuildFailureRunResult(buildFailure);
|
|
1742
|
+
}
|
|
1710
1743
|
modeTimes[i] = formatMatrixModeTime(result.stats.time);
|
|
1711
1744
|
fileResults.push(result);
|
|
1712
1745
|
}
|
|
@@ -1781,32 +1814,41 @@ async function runTestSingleParallel(runFlags, configPath, selectors, suiteSelec
|
|
|
1781
1814
|
try {
|
|
1782
1815
|
await runOrderedPool(files, poolWidth, async (file, index) => {
|
|
1783
1816
|
const token = useQueueDisplay
|
|
1784
|
-
? renderQueuedFileStart(queueDisplay,
|
|
1817
|
+
? renderQueuedFileStart(queueDisplay, formatSpecDisplayPath(file))
|
|
1785
1818
|
: null;
|
|
1786
|
-
const buildStartedAt = Date.now();
|
|
1787
|
-
await buildFileForMode({
|
|
1788
|
-
configPath,
|
|
1789
|
-
file,
|
|
1790
|
-
modeName,
|
|
1791
|
-
buildFeatureToggles,
|
|
1792
|
-
buildPool,
|
|
1793
|
-
});
|
|
1794
|
-
buildIntervals.push({ start: buildStartedAt, end: Date.now() });
|
|
1795
|
-
const buildInvocation = await getBuildInvocationPreview(configPath, file, modeName, buildFeatureToggles);
|
|
1796
|
-
const artifactKey = resolvePerFileArtifactKey(file, duplicateSpecBasenames);
|
|
1797
1819
|
const buffered = useQueueDisplay
|
|
1798
1820
|
? await createBufferedReporter(configPath, runFlags.reporterPath, modeName)
|
|
1799
1821
|
: null;
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1822
|
+
let result;
|
|
1823
|
+
try {
|
|
1824
|
+
const buildStartedAt = Date.now();
|
|
1825
|
+
await buildFileForMode({
|
|
1826
|
+
configPath,
|
|
1827
|
+
file,
|
|
1828
|
+
modeName,
|
|
1829
|
+
buildFeatureToggles,
|
|
1830
|
+
buildPool,
|
|
1831
|
+
});
|
|
1832
|
+
buildIntervals.push({ start: buildStartedAt, end: Date.now() });
|
|
1833
|
+
const buildInvocation = await getBuildInvocationPreview(configPath, file, modeName, buildFeatureToggles);
|
|
1834
|
+
const artifactKey = resolvePerFileArtifactKey(file, duplicateSpecBasenames);
|
|
1835
|
+
result = await run({ ...runFlags, clean: true }, configPath, [file], false, {
|
|
1836
|
+
reporter: buffered?.reporter,
|
|
1837
|
+
reporterKind: buffered?.reporterKind,
|
|
1838
|
+
suiteSelectors,
|
|
1839
|
+
emitRunComplete: false,
|
|
1840
|
+
logFileName: `test.${artifactKey}.log.json`,
|
|
1841
|
+
coverageFileName: `coverage.${artifactKey}.log.json`,
|
|
1842
|
+
buildCommand: formatBuildInvocation(buildInvocation),
|
|
1843
|
+
modeName,
|
|
1844
|
+
});
|
|
1845
|
+
}
|
|
1846
|
+
catch (error) {
|
|
1847
|
+
const buildFailure = getBuildFailureErrorLike(error);
|
|
1848
|
+
if (!buildFailure)
|
|
1849
|
+
throw error;
|
|
1850
|
+
result = createBuildFailureRunResult(buildFailure);
|
|
1851
|
+
}
|
|
1810
1852
|
buffered?.reporter.flush?.();
|
|
1811
1853
|
results[index] = result;
|
|
1812
1854
|
if (buffered && token != null) {
|
|
@@ -1882,7 +1924,7 @@ async function runTestMatrixParallel(runFlags, configPath, selectors, suiteSelec
|
|
|
1882
1924
|
const buildIntervals = [];
|
|
1883
1925
|
try {
|
|
1884
1926
|
await runOrderedPool(files, poolWidth, async (file, fileIndex) => {
|
|
1885
|
-
const fileName =
|
|
1927
|
+
const fileName = formatSpecDisplayPath(file);
|
|
1886
1928
|
const token = useQueueDisplay
|
|
1887
1929
|
? renderQueuedFileStart(queueDisplay, fileName)
|
|
1888
1930
|
: null;
|
|
@@ -1890,28 +1932,37 @@ async function runTestMatrixParallel(runFlags, configPath, selectors, suiteSelec
|
|
|
1890
1932
|
const modeTimes = modes.map(() => "...");
|
|
1891
1933
|
for (let i = 0; i < modes.length; i++) {
|
|
1892
1934
|
const modeName = modes[i];
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1935
|
+
let result;
|
|
1936
|
+
try {
|
|
1937
|
+
const buildStartedAt = Date.now();
|
|
1938
|
+
await buildFileForMode({
|
|
1939
|
+
configPath,
|
|
1940
|
+
file,
|
|
1941
|
+
modeName,
|
|
1942
|
+
buildFeatureToggles,
|
|
1943
|
+
buildPool,
|
|
1944
|
+
});
|
|
1945
|
+
buildIntervals.push({ start: buildStartedAt, end: Date.now() });
|
|
1946
|
+
const buildInvocation = await getBuildInvocationPreview(configPath, file, modeName, buildFeatureToggles);
|
|
1947
|
+
const artifactKey = resolvePerFileArtifactKey(file, duplicateSpecBasenames);
|
|
1948
|
+
result = await run(runFlags, configPath, [file], false, {
|
|
1949
|
+
reporter: silentReporter,
|
|
1950
|
+
reporterKind: "default",
|
|
1951
|
+
suiteSelectors,
|
|
1952
|
+
emitRunStart: false,
|
|
1953
|
+
emitRunComplete: false,
|
|
1954
|
+
logFileName: `test.${artifactKey}.log.json`,
|
|
1955
|
+
coverageFileName: `coverage.${artifactKey}.log.json`,
|
|
1956
|
+
buildCommand: formatBuildInvocation(buildInvocation),
|
|
1957
|
+
modeName,
|
|
1958
|
+
});
|
|
1959
|
+
}
|
|
1960
|
+
catch (error) {
|
|
1961
|
+
const buildFailure = getBuildFailureErrorLike(error);
|
|
1962
|
+
if (!buildFailure)
|
|
1963
|
+
throw error;
|
|
1964
|
+
result = createBuildFailureRunResult(buildFailure);
|
|
1965
|
+
}
|
|
1915
1966
|
modeTimes[i] = formatMatrixModeTime(result.stats.time);
|
|
1916
1967
|
fileResults.push(result);
|
|
1917
1968
|
}
|
|
@@ -2006,7 +2057,9 @@ async function runFuzzMatrixResultsParallel(configPath, selectors, fuzzerSelecto
|
|
|
2006
2057
|
async function runFuzzMatrixResults(configPath, selectors, fuzzerSelectors, modes, overrides, reporter) {
|
|
2007
2058
|
const results = [];
|
|
2008
2059
|
for (const modeName of modes) {
|
|
2009
|
-
const files = await resolveSelectedFuzzFiles(configPath, selectors, [
|
|
2060
|
+
const files = await resolveSelectedFuzzFiles(configPath, selectors, [
|
|
2061
|
+
modeName,
|
|
2062
|
+
]);
|
|
2010
2063
|
if (!files.length) {
|
|
2011
2064
|
continue;
|
|
2012
2065
|
}
|
|
@@ -2212,6 +2265,133 @@ function buildSingleModeSummary(stats, snapshotSummary, totalModes) {
|
|
|
2212
2265
|
total,
|
|
2213
2266
|
};
|
|
2214
2267
|
}
|
|
2268
|
+
function createBuildFailureRunResult(error) {
|
|
2269
|
+
const message = formatBuildFailureMessage(error);
|
|
2270
|
+
const report = {
|
|
2271
|
+
file: error.file,
|
|
2272
|
+
modeName: error.mode,
|
|
2273
|
+
suites: [
|
|
2274
|
+
{
|
|
2275
|
+
file: error.file,
|
|
2276
|
+
description: formatSpecDisplayPath(error.file),
|
|
2277
|
+
depth: 0,
|
|
2278
|
+
kind: "build-error",
|
|
2279
|
+
verdict: "fail",
|
|
2280
|
+
time: {
|
|
2281
|
+
start: 0,
|
|
2282
|
+
end: 0,
|
|
2283
|
+
},
|
|
2284
|
+
suites: [],
|
|
2285
|
+
logs: [],
|
|
2286
|
+
tests: [
|
|
2287
|
+
{
|
|
2288
|
+
order: 0,
|
|
2289
|
+
type: "build-error",
|
|
2290
|
+
verdict: "fail",
|
|
2291
|
+
left: null,
|
|
2292
|
+
right: null,
|
|
2293
|
+
instr: "build failed before the test could run",
|
|
2294
|
+
message,
|
|
2295
|
+
location: "",
|
|
2296
|
+
},
|
|
2297
|
+
],
|
|
2298
|
+
modeName: error.mode,
|
|
2299
|
+
buildCommand: formatBuildInvocation(error.invocation),
|
|
2300
|
+
runCommand: "",
|
|
2301
|
+
},
|
|
2302
|
+
],
|
|
2303
|
+
coverage: {
|
|
2304
|
+
total: 0,
|
|
2305
|
+
covered: 0,
|
|
2306
|
+
uncovered: 0,
|
|
2307
|
+
percent: 100,
|
|
2308
|
+
points: [],
|
|
2309
|
+
},
|
|
2310
|
+
runCommand: "",
|
|
2311
|
+
buildCommand: formatBuildInvocation(error.invocation),
|
|
2312
|
+
snapshotSummary: {
|
|
2313
|
+
matched: 0,
|
|
2314
|
+
created: 0,
|
|
2315
|
+
updated: 0,
|
|
2316
|
+
failed: 0,
|
|
2317
|
+
},
|
|
2318
|
+
};
|
|
2319
|
+
return {
|
|
2320
|
+
failed: true,
|
|
2321
|
+
buildTime: 0,
|
|
2322
|
+
stats: {
|
|
2323
|
+
passedFiles: 0,
|
|
2324
|
+
failedFiles: 1,
|
|
2325
|
+
skippedFiles: 0,
|
|
2326
|
+
passedSuites: 0,
|
|
2327
|
+
failedSuites: 1,
|
|
2328
|
+
skippedSuites: 0,
|
|
2329
|
+
passedTests: 0,
|
|
2330
|
+
failedTests: 1,
|
|
2331
|
+
skippedTests: 0,
|
|
2332
|
+
time: 0,
|
|
2333
|
+
failedEntries: [
|
|
2334
|
+
{
|
|
2335
|
+
...report.suites[0],
|
|
2336
|
+
file: error.file,
|
|
2337
|
+
modeName: error.mode,
|
|
2338
|
+
buildCommand: report.buildCommand,
|
|
2339
|
+
runCommand: "",
|
|
2340
|
+
},
|
|
2341
|
+
],
|
|
2342
|
+
},
|
|
2343
|
+
snapshotSummary: report.snapshotSummary,
|
|
2344
|
+
coverageSummary: {
|
|
2345
|
+
enabled: false,
|
|
2346
|
+
showPoints: false,
|
|
2347
|
+
total: 0,
|
|
2348
|
+
covered: 0,
|
|
2349
|
+
uncovered: 0,
|
|
2350
|
+
percent: 100,
|
|
2351
|
+
files: [],
|
|
2352
|
+
},
|
|
2353
|
+
reports: [report],
|
|
2354
|
+
};
|
|
2355
|
+
}
|
|
2356
|
+
function formatBuildFailureMessage(error) {
|
|
2357
|
+
const parts = [];
|
|
2358
|
+
const stderr = error.stderr.trim();
|
|
2359
|
+
const stdout = error.stdout.trim();
|
|
2360
|
+
if (stderr.length) {
|
|
2361
|
+
parts.push(`stderr:\n${stderr}`);
|
|
2362
|
+
}
|
|
2363
|
+
if (stdout.length) {
|
|
2364
|
+
parts.push(`stdout:\n${stdout}`);
|
|
2365
|
+
}
|
|
2366
|
+
if (error.crashLogPath.length) {
|
|
2367
|
+
parts.push(`Crash log:\n${error.crashLogPath}`);
|
|
2368
|
+
}
|
|
2369
|
+
return parts.join("\n\n") || "build failed with no compiler output";
|
|
2370
|
+
}
|
|
2371
|
+
function getBuildFailureErrorLike(error) {
|
|
2372
|
+
if (error instanceof BuildFailureError) {
|
|
2373
|
+
return error;
|
|
2374
|
+
}
|
|
2375
|
+
if (!error || typeof error != "object") {
|
|
2376
|
+
return null;
|
|
2377
|
+
}
|
|
2378
|
+
const candidate = error;
|
|
2379
|
+
if (candidate.name != "BuildFailureError") {
|
|
2380
|
+
return null;
|
|
2381
|
+
}
|
|
2382
|
+
if (typeof candidate.file != "string" ||
|
|
2383
|
+
typeof candidate.mode != "string" ||
|
|
2384
|
+
typeof candidate.stdout != "string" ||
|
|
2385
|
+
typeof candidate.stderr != "string" ||
|
|
2386
|
+
typeof candidate.crashLogPath != "string" ||
|
|
2387
|
+
!candidate.invocation ||
|
|
2388
|
+
typeof candidate.invocation != "object" ||
|
|
2389
|
+
typeof candidate.invocation.command != "string" ||
|
|
2390
|
+
!Array.isArray(candidate.invocation.args)) {
|
|
2391
|
+
return null;
|
|
2392
|
+
}
|
|
2393
|
+
return candidate;
|
|
2394
|
+
}
|
|
2215
2395
|
function applyConfiguredFileTotalToStats(stats, fileSummaryTotal) {
|
|
2216
2396
|
const total = Math.max(fileSummaryTotal, 0);
|
|
2217
2397
|
const executed = stats.failedFiles + stats.passedFiles + stats.skippedFiles;
|
|
@@ -2320,7 +2500,7 @@ async function buildNoTestFilesMatchedError(configPath, selectors, includeFuzz =
|
|
|
2320
2500
|
if (configuredFiles.length) {
|
|
2321
2501
|
const sample = configuredFiles
|
|
2322
2502
|
.slice(0, 5)
|
|
2323
|
-
.map((file) =>
|
|
2503
|
+
.map((file) => formatSpecDisplayPath(file))
|
|
2324
2504
|
.join(", ");
|
|
2325
2505
|
lines.push(`Configured specs (${configuredFiles.length}): ${sample}${configuredFiles.length > 5 ? ", ..." : ""}`);
|
|
2326
2506
|
}
|
|
@@ -2628,7 +2808,7 @@ async function handleMissingWebBrowsers(missing) {
|
|
|
2628
2808
|
const details = "no web-capable browser was found in PATH, BROWSER, or Playwright cache";
|
|
2629
2809
|
const selected = choosePreferredBrowserInstall(missing);
|
|
2630
2810
|
const installCommand = selected == "webkit"
|
|
2631
|
-
?
|
|
2811
|
+
? "npx -y playwright install webkit"
|
|
2632
2812
|
: `npx -y playwright install ${selected}`;
|
|
2633
2813
|
if (!canPromptForWebInstall()) {
|
|
2634
2814
|
throw new Error(`web target requires a browser for mode(s) ${scope}; ${details}. Export BROWSER or install one with "${installCommand}".`);
|
|
@@ -2748,10 +2928,10 @@ function isPlaywrightBrowserExecutable(browser) {
|
|
|
2748
2928
|
function extractPlaywrightDepsSummary(result) {
|
|
2749
2929
|
const stdout = typeof result.stdout == "string"
|
|
2750
2930
|
? result.stdout
|
|
2751
|
-
: result.stdout?.toString("utf8") ?? "";
|
|
2931
|
+
: (result.stdout?.toString("utf8") ?? "");
|
|
2752
2932
|
const stderr = typeof result.stderr == "string"
|
|
2753
2933
|
? result.stderr
|
|
2754
|
-
: result.stderr?.toString("utf8") ?? "";
|
|
2934
|
+
: (result.stderr?.toString("utf8") ?? "");
|
|
2755
2935
|
return [stdout.trim(), stderr.trim()].filter(Boolean).join("\n");
|
|
2756
2936
|
}
|
|
2757
2937
|
function canPromptForWebInstall() {
|
|
@@ -2886,9 +3066,7 @@ function resolveSystemBrowserExecutable(browser) {
|
|
|
2886
3066
|
"Firefox.app/Contents/MacOS/firefox",
|
|
2887
3067
|
"Firefox Developer Edition.app/Contents/MacOS/firefox",
|
|
2888
3068
|
],
|
|
2889
|
-
msedge: [
|
|
2890
|
-
"Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
|
2891
|
-
],
|
|
3069
|
+
msedge: ["Microsoft Edge.app/Contents/MacOS/Microsoft Edge"],
|
|
2892
3070
|
webkit: [],
|
|
2893
3071
|
};
|
|
2894
3072
|
for (const root of macSearchRoots) {
|