@empiricalrun/test-run 0.11.0 → 0.12.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/CHANGELOG.md +17 -0
- package/dist/bin/merge-reports.d.ts +3 -0
- package/dist/bin/merge-reports.d.ts.map +1 -0
- package/dist/bin/merge-reports.js +26 -0
- package/dist/glob-matcher.d.ts +17 -0
- package/dist/glob-matcher.d.ts.map +1 -0
- package/dist/glob-matcher.js +37 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -6
- package/dist/lib/cmd.d.ts +6 -1
- package/dist/lib/cmd.d.ts.map +1 -1
- package/dist/lib/cmd.js +7 -3
- package/dist/lib/merge-reports.d.ts +26 -0
- package/dist/lib/merge-reports.d.ts.map +1 -0
- package/dist/lib/merge-reports.js +231 -0
- package/dist/lib/run-specific-test.d.ts.map +1 -1
- package/dist/lib/run-specific-test.js +1 -1
- package/dist/stdout-parser/index.d.ts.map +1 -0
- package/dist/utils/config.d.ts +1 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -16
- package/package.json +20 -6
- package/test-data/blob-report/report-1.zip +0 -0
- package/test-data/blob-report/report-2.zip +0 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/parser/index.d.ts.map +0 -1
- package/eslint.config.mjs +0 -16
- /package/dist/{parser → stdout-parser}/index.d.ts +0 -0
- /package/dist/{parser → stdout-parser}/index.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @empiricalrun/test-run
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 79a4e0f: feat: add blob reporters for sharding
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [79a4e0f]
|
|
12
|
+
- @empiricalrun/r2-uploader@0.6.0
|
|
13
|
+
|
|
14
|
+
## 0.11.1
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 9fb0ba1: feat: reuse glob matcher for envs to show on dash
|
|
19
|
+
|
|
3
20
|
## 0.11.0
|
|
4
21
|
|
|
5
22
|
### Minor Changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-reports.d.ts","sourceRoot":"","sources":["../../src/bin/merge-reports.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
9
|
+
const merge_reports_1 = require("../lib/merge-reports");
|
|
10
|
+
dotenv_1.default.config({
|
|
11
|
+
path: [".env.local", ".env"],
|
|
12
|
+
});
|
|
13
|
+
(async function main() {
|
|
14
|
+
commander_1.program
|
|
15
|
+
.option("-b, --blob-dir <blob-dir>", "Path to the blob-report directory")
|
|
16
|
+
.option("-c, --cwd <cwd>", "Working directory")
|
|
17
|
+
.parse(process.argv);
|
|
18
|
+
const options = commander_1.program.opts();
|
|
19
|
+
const { success } = await (0, merge_reports_1.mergeReports)({
|
|
20
|
+
blobDir: options.blobDir,
|
|
21
|
+
cwd: options.cwd,
|
|
22
|
+
});
|
|
23
|
+
if (!success) {
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filters an array using glob pattern matchers.
|
|
3
|
+
*
|
|
4
|
+
* @param input - Array that needs to be filtered
|
|
5
|
+
* @param globMatcherSets - Set of glob patterns to filter the array sequentially (takes the intersection of all sets)
|
|
6
|
+
* @returns Filtered array containing only items that match all glob pattern sets
|
|
7
|
+
*/
|
|
8
|
+
export declare const filterArrayByGlobMatchersSet: (input: string[], globMatcherSets: string[][]) => string[];
|
|
9
|
+
/**
|
|
10
|
+
* Filters playwright project names using glob patterns.
|
|
11
|
+
*
|
|
12
|
+
* @param allProjectNames - Array of all available project names
|
|
13
|
+
* @param patterns - Array of glob patterns to match against
|
|
14
|
+
* @returns Array of project names that match the patterns
|
|
15
|
+
*/
|
|
16
|
+
export declare const filterProjectsByGlobPatterns: (allProjectNames: string[], patterns: string[]) => string[];
|
|
17
|
+
//# sourceMappingURL=glob-matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob-matcher.d.ts","sourceRoot":"","sources":["../src/glob-matcher.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACvC,OAAO,MAAM,EAAE,EACf,iBAAiB,MAAM,EAAE,EAAE,KAC1B,MAAM,EAUR,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACvC,iBAAiB,MAAM,EAAE,EACzB,UAAU,MAAM,EAAE,KACjB,MAAM,EASR,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterProjectsByGlobPatterns = exports.filterArrayByGlobMatchersSet = void 0;
|
|
4
|
+
const minimatch_1 = require("minimatch");
|
|
5
|
+
/**
|
|
6
|
+
* Filters an array using glob pattern matchers.
|
|
7
|
+
*
|
|
8
|
+
* @param input - Array that needs to be filtered
|
|
9
|
+
* @param globMatcherSets - Set of glob patterns to filter the array sequentially (takes the intersection of all sets)
|
|
10
|
+
* @returns Filtered array containing only items that match all glob pattern sets
|
|
11
|
+
*/
|
|
12
|
+
const filterArrayByGlobMatchersSet = (input, globMatcherSets) => {
|
|
13
|
+
let filteredList = input;
|
|
14
|
+
globMatcherSets.forEach((matcherSet) => {
|
|
15
|
+
filteredList = filteredList.filter((item) => {
|
|
16
|
+
return matcherSet.some((matcherGlob) => (0, minimatch_1.minimatch)(item, matcherGlob));
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
return filteredList;
|
|
20
|
+
};
|
|
21
|
+
exports.filterArrayByGlobMatchersSet = filterArrayByGlobMatchersSet;
|
|
22
|
+
/**
|
|
23
|
+
* Filters playwright project names using glob patterns.
|
|
24
|
+
*
|
|
25
|
+
* @param allProjectNames - Array of all available project names
|
|
26
|
+
* @param patterns - Array of glob patterns to match against
|
|
27
|
+
* @returns Array of project names that match the patterns
|
|
28
|
+
*/
|
|
29
|
+
const filterProjectsByGlobPatterns = (allProjectNames, patterns) => {
|
|
30
|
+
if (!patterns || patterns.length === 0) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
// Convert patterns to the format expected by filterArrayByGlobMatchersSet
|
|
34
|
+
const globMatcherSets = patterns.map((pattern) => [pattern]);
|
|
35
|
+
return (0, exports.filterArrayByGlobMatchersSet)(allProjectNames, globMatcherSets);
|
|
36
|
+
};
|
|
37
|
+
exports.filterProjectsByGlobPatterns = filterProjectsByGlobPatterns;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { JSONReport as PlaywrightJSONReport } from "@playwright/test/reporter";
|
|
2
2
|
import { spawnCmd } from "./lib/cmd";
|
|
3
3
|
import { runSpecificTestsCmd } from "./lib/run-specific-test";
|
|
4
|
+
import { parseTestListOutput } from "./stdout-parser";
|
|
4
5
|
import { Platform, TestCase } from "./types";
|
|
5
6
|
import { getProjectsFromPlaywrightConfig } from "./utils/config";
|
|
6
|
-
export { getProjectsFromPlaywrightConfig, Platform, runSpecificTestsCmd, spawnCmd, };
|
|
7
|
+
export { getProjectsFromPlaywrightConfig, parseTestListOutput, Platform, runSpecificTestsCmd, spawnCmd, };
|
|
8
|
+
export * from "./glob-matcher";
|
|
7
9
|
export { filterArrayByGlobMatchersSet, generateProjectFilters } from "./utils";
|
|
8
|
-
export declare function runSingleTest({ testName, suites, filePath, projects, envOverrides, repoDir, }: {
|
|
10
|
+
export declare function runSingleTest({ testName, suites, filePath, projects, envOverrides, repoDir, stdout, stderr, }: {
|
|
9
11
|
testName: string;
|
|
10
12
|
suites: string[];
|
|
11
13
|
filePath: string;
|
|
12
14
|
projects: string[];
|
|
13
15
|
envOverrides?: Record<string, string>;
|
|
14
16
|
repoDir: string;
|
|
17
|
+
stdout?: NodeJS.WritableStream;
|
|
18
|
+
stderr?: NodeJS.WritableStream;
|
|
15
19
|
}): Promise<{
|
|
16
20
|
hasTestPassed: boolean;
|
|
17
21
|
summaryJson: PlaywrightJSONReport;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAI/E,OAAO,EAAkB,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAI/E,OAAO,EAAkB,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AAMjE,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,EACnB,QAAQ,EACR,mBAAmB,EACnB,QAAQ,GACT,CAAC;AACF,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAc/E,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,MAAM,EACN,MAAM,GACP,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC,GAAG,OAAO,CAAC;IACV,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,oBAAoB,CAAC;CACnC,CAAC,CAoBD;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CACjD,CAAC,CAeD"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
18
|
};
|
|
5
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.generateProjectFilters = exports.filterArrayByGlobMatchersSet = exports.spawnCmd = exports.runSpecificTestsCmd = exports.Platform = exports.getProjectsFromPlaywrightConfig = void 0;
|
|
20
|
+
exports.generateProjectFilters = exports.filterArrayByGlobMatchersSet = exports.spawnCmd = exports.runSpecificTestsCmd = exports.Platform = exports.parseTestListOutput = exports.getProjectsFromPlaywrightConfig = void 0;
|
|
7
21
|
exports.runSingleTest = runSingleTest;
|
|
8
22
|
exports.listProjectsAndTests = listProjectsAndTests;
|
|
9
23
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -12,7 +26,8 @@ const cmd_1 = require("./lib/cmd");
|
|
|
12
26
|
Object.defineProperty(exports, "spawnCmd", { enumerable: true, get: function () { return cmd_1.spawnCmd; } });
|
|
13
27
|
const run_specific_test_1 = require("./lib/run-specific-test");
|
|
14
28
|
Object.defineProperty(exports, "runSpecificTestsCmd", { enumerable: true, get: function () { return run_specific_test_1.runSpecificTestsCmd; } });
|
|
15
|
-
const
|
|
29
|
+
const stdout_parser_1 = require("./stdout-parser");
|
|
30
|
+
Object.defineProperty(exports, "parseTestListOutput", { enumerable: true, get: function () { return stdout_parser_1.parseTestListOutput; } });
|
|
16
31
|
const types_1 = require("./types");
|
|
17
32
|
Object.defineProperty(exports, "Platform", { enumerable: true, get: function () { return types_1.Platform; } });
|
|
18
33
|
const utils_1 = require("./utils");
|
|
@@ -21,6 +36,7 @@ Object.defineProperty(exports, "getProjectsFromPlaywrightConfig", { enumerable:
|
|
|
21
36
|
// For test-run package, the library entrypoint, we only support web platform
|
|
22
37
|
// The bin entrypoint has support for mobile also
|
|
23
38
|
const supportedPlatform = types_1.Platform.WEB;
|
|
39
|
+
__exportStar(require("./glob-matcher"), exports);
|
|
24
40
|
var utils_2 = require("./utils");
|
|
25
41
|
Object.defineProperty(exports, "filterArrayByGlobMatchersSet", { enumerable: true, get: function () { return utils_2.filterArrayByGlobMatchersSet; } });
|
|
26
42
|
Object.defineProperty(exports, "generateProjectFilters", { enumerable: true, get: function () { return utils_2.generateProjectFilters; } });
|
|
@@ -31,7 +47,7 @@ function getSummaryJsonPath(repoDir) {
|
|
|
31
47
|
? pathForPlaywright147
|
|
32
48
|
: pathForOtherPlaywrightVersions;
|
|
33
49
|
}
|
|
34
|
-
async function runSingleTest({ testName, suites, filePath, projects, envOverrides, repoDir, }) {
|
|
50
|
+
async function runSingleTest({ testName, suites, filePath, projects, envOverrides, repoDir, stdout, stderr, }) {
|
|
35
51
|
const testDir = "tests";
|
|
36
52
|
const commandToRun = await (0, run_specific_test_1.runSpecificTestsCmd)({
|
|
37
53
|
tests: [{ name: testName, dir: testDir, filePath, suites }],
|
|
@@ -40,7 +56,10 @@ async function runSingleTest({ testName, suites, filePath, projects, envOverride
|
|
|
40
56
|
platform: supportedPlatform,
|
|
41
57
|
repoDir,
|
|
42
58
|
});
|
|
43
|
-
const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun, repoDir
|
|
59
|
+
const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun, repoDir, {
|
|
60
|
+
stdout,
|
|
61
|
+
stderr,
|
|
62
|
+
});
|
|
44
63
|
const jsonFilePath = getSummaryJsonPath(repoDir);
|
|
45
64
|
const jsonFileContents = fs_1.default.readFileSync(jsonFilePath, "utf8");
|
|
46
65
|
const summaryJson = JSON.parse(jsonFileContents);
|
|
@@ -54,12 +73,14 @@ async function listProjectsAndTests(repoDir) {
|
|
|
54
73
|
const args = [testRunner, "test", "--list"];
|
|
55
74
|
const { output, code } = await (0, cmd_1.spawnCmd)("npx", args, {
|
|
56
75
|
cwd: repoDir,
|
|
57
|
-
envOverrides: {
|
|
76
|
+
envOverrides: {
|
|
77
|
+
NODE_PATH: path_1.default.join(repoDir, "node_modules"),
|
|
78
|
+
},
|
|
58
79
|
captureOutput: true,
|
|
59
80
|
throwOnError: true,
|
|
60
81
|
});
|
|
61
82
|
if (!output) {
|
|
62
83
|
throw new Error(`Failed to run list command; exit code: ${code}`);
|
|
63
84
|
}
|
|
64
|
-
return (0,
|
|
85
|
+
return (0, stdout_parser_1.parseTestListOutput)(output);
|
|
65
86
|
}
|
package/dist/lib/cmd.d.ts
CHANGED
|
@@ -3,7 +3,10 @@ export declare function getCommandFromString(command: string): {
|
|
|
3
3
|
command: string;
|
|
4
4
|
args: string[];
|
|
5
5
|
};
|
|
6
|
-
export declare function runTestsForCmd({ command, args, env }: CommandToRun, cwd: string
|
|
6
|
+
export declare function runTestsForCmd({ command, args, env }: CommandToRun, cwd: string, options?: {
|
|
7
|
+
stdout?: NodeJS.WritableStream;
|
|
8
|
+
stderr?: NodeJS.WritableStream;
|
|
9
|
+
}): Promise<{
|
|
7
10
|
hasTestPassed: boolean;
|
|
8
11
|
}>;
|
|
9
12
|
export declare function spawnCmd(command: string, args: string[], options: {
|
|
@@ -11,6 +14,8 @@ export declare function spawnCmd(command: string, args: string[], options: {
|
|
|
11
14
|
envOverrides: Record<string, string>;
|
|
12
15
|
captureOutput: boolean;
|
|
13
16
|
throwOnError: boolean;
|
|
17
|
+
stdout?: NodeJS.WritableStream;
|
|
18
|
+
stderr?: NodeJS.WritableStream;
|
|
14
19
|
}): Promise<{
|
|
15
20
|
code: number;
|
|
16
21
|
output?: string;
|
package/dist/lib/cmd.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../src/lib/cmd.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAeA;AAED,wBAAsB,cAAc,CAClC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,YAAY,EACpC,GAAG,EAAE,MAAM;;
|
|
1
|
+
{"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../src/lib/cmd.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAeA;AAED,wBAAsB,cAAc,CAClC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,YAAY,EACpC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC;;GAiBF;AAED,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;IACP,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC,GACA,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA+C5C"}
|
package/dist/lib/cmd.js
CHANGED
|
@@ -19,7 +19,7 @@ function getCommandFromString(command) {
|
|
|
19
19
|
}),
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
-
async function runTestsForCmd({ command, args, env }, cwd) {
|
|
22
|
+
async function runTestsForCmd({ command, args, env }, cwd, options) {
|
|
23
23
|
logger_1.logger.debug(`Running cmd: ${command} with args: ${args}`);
|
|
24
24
|
let hasTestPassed = true;
|
|
25
25
|
try {
|
|
@@ -28,6 +28,8 @@ async function runTestsForCmd({ command, args, env }, cwd) {
|
|
|
28
28
|
envOverrides: env,
|
|
29
29
|
captureOutput: false,
|
|
30
30
|
throwOnError: true,
|
|
31
|
+
stdout: options?.stdout,
|
|
32
|
+
stderr: options?.stderr,
|
|
31
33
|
});
|
|
32
34
|
}
|
|
33
35
|
catch {
|
|
@@ -53,7 +55,8 @@ async function spawnCmd(command, args, options) {
|
|
|
53
55
|
output += log;
|
|
54
56
|
}
|
|
55
57
|
else {
|
|
56
|
-
process.stdout
|
|
58
|
+
const stdout = options.stdout || process.stdout;
|
|
59
|
+
stdout.write(log);
|
|
57
60
|
}
|
|
58
61
|
if (log.includes("Error")) {
|
|
59
62
|
errorLogs.push(log);
|
|
@@ -61,7 +64,8 @@ async function spawnCmd(command, args, options) {
|
|
|
61
64
|
});
|
|
62
65
|
p.stderr.on("data", (x) => {
|
|
63
66
|
const log = x.toString();
|
|
64
|
-
process.stderr
|
|
67
|
+
const stderr = options.stderr || process.stderr;
|
|
68
|
+
stderr.write(log);
|
|
65
69
|
errorLogs.push(log);
|
|
66
70
|
});
|
|
67
71
|
p.on("exit", (code) => {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface MergeReportsOptions {
|
|
2
|
+
blobDir: string;
|
|
3
|
+
outputDir: string;
|
|
4
|
+
cwd: string;
|
|
5
|
+
}
|
|
6
|
+
interface UploadOptions {
|
|
7
|
+
projectName: string;
|
|
8
|
+
runId: string;
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
uploadBucket: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function runPlaywrightMergeReports(options: MergeReportsOptions): Promise<{
|
|
13
|
+
success: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function extractUrlMappingsFromBlobs(blobDir: string): Record<string, string>;
|
|
16
|
+
export declare function patchMergedHtmlReport(htmlFilePath: string, urlMappings: Record<string, string>): Promise<void>;
|
|
17
|
+
export declare function patchSummaryJson(jsonFilePath: string, urlMappings: Record<string, string>): Promise<void>;
|
|
18
|
+
export declare function uploadMergedReports(cwd: string, outputDir: string, uploadOptions: UploadOptions): Promise<void>;
|
|
19
|
+
export declare function mergeReports(options: {
|
|
20
|
+
blobDir?: string;
|
|
21
|
+
cwd?: string;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=merge-reports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-reports.d.ts","sourceRoot":"","sources":["../../src/lib/merge-reports.ts"],"names":[],"mappings":"AAYA,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,aAAa;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA2B/B;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA4BxB;AAED,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,IAAI,CAAC,CAqFf;AAED,wBAAsB,gBAAgB,CACpC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,IAAI,CAAC,CAkDf;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAuDhC"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runPlaywrightMergeReports = runPlaywrightMergeReports;
|
|
7
|
+
exports.extractUrlMappingsFromBlobs = extractUrlMappingsFromBlobs;
|
|
8
|
+
exports.patchMergedHtmlReport = patchMergedHtmlReport;
|
|
9
|
+
exports.patchSummaryJson = patchSummaryJson;
|
|
10
|
+
exports.uploadMergedReports = uploadMergedReports;
|
|
11
|
+
exports.mergeReports = mergeReports;
|
|
12
|
+
const r2_uploader_1 = require("@empiricalrun/r2-uploader");
|
|
13
|
+
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
14
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const logger_1 = require("../logger");
|
|
17
|
+
const cmd_1 = require("./cmd");
|
|
18
|
+
async function runPlaywrightMergeReports(options) {
|
|
19
|
+
const { blobDir, outputDir, cwd } = options;
|
|
20
|
+
logger_1.logger.debug(`[Merge Reports] Running playwright merge-reports`);
|
|
21
|
+
logger_1.logger.debug(`[Merge Reports] Blob dir: ${blobDir}`);
|
|
22
|
+
logger_1.logger.debug(`[Merge Reports] Output dir: ${outputDir}`);
|
|
23
|
+
try {
|
|
24
|
+
await (0, cmd_1.spawnCmd)("npx", ["playwright", "merge-reports", blobDir, "--reporter", "html,json"], {
|
|
25
|
+
cwd,
|
|
26
|
+
envOverrides: {
|
|
27
|
+
PLAYWRIGHT_HTML_OPEN: "never",
|
|
28
|
+
PLAYWRIGHT_HTML_OUTPUT_DIR: outputDir,
|
|
29
|
+
PLAYWRIGHT_JSON_OUTPUT_NAME: path_1.default.join(cwd, "summary.json"),
|
|
30
|
+
},
|
|
31
|
+
captureOutput: false,
|
|
32
|
+
throwOnError: true,
|
|
33
|
+
});
|
|
34
|
+
return { success: true };
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
logger_1.logger.error(`[Merge Reports] Failed to merge reports:`, error);
|
|
38
|
+
return { success: false };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function extractUrlMappingsFromBlobs(blobDir) {
|
|
42
|
+
const combinedMap = {};
|
|
43
|
+
const files = fs_1.default.readdirSync(blobDir);
|
|
44
|
+
for (const fileName of files.filter((f) => f.endsWith(".zip"))) {
|
|
45
|
+
const zipPath = path_1.default.join(blobDir, fileName);
|
|
46
|
+
try {
|
|
47
|
+
const zip = new adm_zip_1.default(zipPath);
|
|
48
|
+
const urlsEntry = zip.getEntry("_empirical_urls.json");
|
|
49
|
+
if (urlsEntry) {
|
|
50
|
+
const content = JSON.parse(urlsEntry.getData().toString("utf8"));
|
|
51
|
+
Object.assign(combinedMap, content);
|
|
52
|
+
logger_1.logger.debug(`[Merge Reports] Extracted ${Object.keys(content).length} URL mappings from ${fileName}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
logger_1.logger.error(`[Merge Reports] Failed to extract URL mappings from ${fileName}:`, error);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
logger_1.logger.info(`[Merge Reports] Total URL mappings: ${Object.keys(combinedMap).length}`);
|
|
60
|
+
return combinedMap;
|
|
61
|
+
}
|
|
62
|
+
async function patchMergedHtmlReport(htmlFilePath, urlMappings) {
|
|
63
|
+
if (Object.keys(urlMappings).length === 0) {
|
|
64
|
+
logger_1.logger.debug(`[Merge Reports] No URL mappings to apply`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
let htmlContent;
|
|
68
|
+
try {
|
|
69
|
+
htmlContent = await fs_1.default.promises.readFile(htmlFilePath, "utf8");
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
logger_1.logger.error(`[Merge Reports] Failed to read HTML file:`, error);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const oldFormatMatch = htmlContent.match(/window\.playwrightReportBase64\s*=\s*"(?:data:application\/zip;base64,)?([^"]+)"/);
|
|
76
|
+
const newFormatMatch = htmlContent.match(/<script\s+id="playwrightReportBase64"[^>]*>(?:data:application\/zip;base64,)?([^<]+)<\/script>/);
|
|
77
|
+
const base64 = oldFormatMatch?.[1] || newFormatMatch?.[1];
|
|
78
|
+
if (!base64) {
|
|
79
|
+
logger_1.logger.error(`[Merge Reports] Base64 zip data not found in HTML`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const htmlDir = path_1.default.dirname(path_1.default.resolve(htmlFilePath));
|
|
83
|
+
const tempDir = fs_1.default.mkdtempSync(path_1.default.join(htmlDir, "merge-patch-"));
|
|
84
|
+
const zipPath = path_1.default.join(tempDir, "archive.zip");
|
|
85
|
+
try {
|
|
86
|
+
await fs_1.default.promises.writeFile(zipPath, Buffer.from(base64, "base64"));
|
|
87
|
+
const zip = new adm_zip_1.default(zipPath);
|
|
88
|
+
zip.extractAllTo(tempDir, true);
|
|
89
|
+
await fs_1.default.promises.unlink(zipPath);
|
|
90
|
+
const jsonFiles = (await fs_1.default.promises.readdir(tempDir)).filter((f) => f.endsWith(".json"));
|
|
91
|
+
for (const file of jsonFiles) {
|
|
92
|
+
const filePath = path_1.default.join(tempDir, file);
|
|
93
|
+
const content = await fs_1.default.promises.readFile(filePath, "utf8");
|
|
94
|
+
let modified = content;
|
|
95
|
+
for (const [resourcePath, url] of Object.entries(urlMappings)) {
|
|
96
|
+
const resourceFileName = resourcePath.replace(/^resources\//, "");
|
|
97
|
+
const regex = new RegExp(`[^"]*${resourceFileName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "g");
|
|
98
|
+
modified = modified.replace(regex, url);
|
|
99
|
+
}
|
|
100
|
+
if (modified !== content) {
|
|
101
|
+
await fs_1.default.promises.writeFile(filePath, modified, "utf8");
|
|
102
|
+
logger_1.logger.debug(`[Merge Reports] Patched ${file}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const newZip = new adm_zip_1.default();
|
|
106
|
+
newZip.addLocalFolder(tempDir);
|
|
107
|
+
const newBase64 = newZip.toBuffer().toString("base64");
|
|
108
|
+
let updatedHtml;
|
|
109
|
+
if (oldFormatMatch) {
|
|
110
|
+
updatedHtml = htmlContent.replace(/(window\.playwrightReportBase64\s*=\s*")(?:data:application\/zip;base64,)?[^"]*(")/, `$1data:application/zip;base64,${newBase64}$2`);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
updatedHtml = htmlContent.replace(/(<script\s+id="playwrightReportBase64"[^>]*>)(?:data:application\/zip;base64,)?[^<]*(<\/script>)/, `$1data:application/zip;base64,${newBase64}$2`);
|
|
114
|
+
}
|
|
115
|
+
await fs_1.default.promises.writeFile(htmlFilePath, updatedHtml, "utf8");
|
|
116
|
+
logger_1.logger.info(`[Merge Reports] HTML file patched successfully`);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
logger_1.logger.error(`[Merge Reports] Failed to patch HTML:`, error);
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
await fs_1.default.promises.rm(tempDir, { recursive: true, force: true });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function patchSummaryJson(jsonFilePath, urlMappings) {
|
|
126
|
+
if (Object.keys(urlMappings).length === 0) {
|
|
127
|
+
logger_1.logger.debug(`[Merge Reports] No URL mappings to apply to summary.json`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
let content = await fs_1.default.promises.readFile(jsonFilePath, "utf8");
|
|
132
|
+
for (const [resourcePath, url] of Object.entries(urlMappings)) {
|
|
133
|
+
const resourceFileName = resourcePath.replace(/^resources\//, "");
|
|
134
|
+
const regex = new RegExp(`[^"]*${resourceFileName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "g");
|
|
135
|
+
content = content.replace(regex, url);
|
|
136
|
+
}
|
|
137
|
+
await fs_1.default.promises.writeFile(jsonFilePath, content, "utf8");
|
|
138
|
+
logger_1.logger.info(`[Merge Reports] summary.json patched successfully`);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
logger_1.logger.error(`[Merge Reports] Failed to patch summary.json:`, error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function uploadMergedReports(cwd, outputDir, uploadOptions) {
|
|
145
|
+
const { projectName, runId, baseUrl, uploadBucket } = uploadOptions;
|
|
146
|
+
const destinationDir = path_1.default.join(projectName, runId);
|
|
147
|
+
const htmlFilePath = path_1.default.join(outputDir, "index.html");
|
|
148
|
+
const jsonFilePath = path_1.default.join(cwd, "summary.json");
|
|
149
|
+
if (fs_1.default.existsSync(htmlFilePath)) {
|
|
150
|
+
logger_1.logger.debug(`[Merge Reports] Uploading HTML report`);
|
|
151
|
+
const task = (0, r2_uploader_1.createUploadTask)({
|
|
152
|
+
sourceDir: outputDir,
|
|
153
|
+
fileList: [htmlFilePath],
|
|
154
|
+
destinationDir,
|
|
155
|
+
uploadBucket,
|
|
156
|
+
baseUrl,
|
|
157
|
+
});
|
|
158
|
+
void (0, r2_uploader_1.sendTaskToQueue)(task);
|
|
159
|
+
}
|
|
160
|
+
if (fs_1.default.existsSync(jsonFilePath)) {
|
|
161
|
+
logger_1.logger.debug(`[Merge Reports] Uploading summary.json`);
|
|
162
|
+
const task = (0, r2_uploader_1.createUploadTask)({
|
|
163
|
+
sourceDir: cwd,
|
|
164
|
+
fileList: [jsonFilePath],
|
|
165
|
+
destinationDir,
|
|
166
|
+
uploadBucket,
|
|
167
|
+
baseUrl,
|
|
168
|
+
});
|
|
169
|
+
void (0, r2_uploader_1.sendTaskToQueue)(task);
|
|
170
|
+
}
|
|
171
|
+
const traceDir = path_1.default.join(outputDir, "trace");
|
|
172
|
+
if (fs_1.default.existsSync(traceDir)) {
|
|
173
|
+
logger_1.logger.debug(`[Merge Reports] Uploading trace folder`);
|
|
174
|
+
const task = (0, r2_uploader_1.createUploadTask)({
|
|
175
|
+
sourceDir: traceDir,
|
|
176
|
+
destinationDir: path_1.default.join(destinationDir, "trace"),
|
|
177
|
+
uploadBucket,
|
|
178
|
+
baseUrl,
|
|
179
|
+
});
|
|
180
|
+
void (0, r2_uploader_1.sendTaskToQueue)(task);
|
|
181
|
+
}
|
|
182
|
+
await (0, r2_uploader_1.waitForTaskQueueToFinish)();
|
|
183
|
+
const reportUrl = `${baseUrl}/${destinationDir}/index.html`;
|
|
184
|
+
const jsonUrl = `${baseUrl}/${destinationDir}/summary.json`;
|
|
185
|
+
logger_1.logger.info(`[Merge Reports] All uploads completed`);
|
|
186
|
+
logger_1.logger.info(`[Merge Reports] HTML Report: ${reportUrl}`);
|
|
187
|
+
logger_1.logger.info(`[Merge Reports] Summary JSON: ${jsonUrl}`);
|
|
188
|
+
}
|
|
189
|
+
async function mergeReports(options) {
|
|
190
|
+
const cwd = options.cwd || process.cwd();
|
|
191
|
+
const blobDir = options.blobDir || path_1.default.join(cwd, "blob-report");
|
|
192
|
+
const outputDir = path_1.default.join(cwd, "playwright-report");
|
|
193
|
+
const projectName = process.env.PROJECT_NAME;
|
|
194
|
+
const runId = process.env.TEST_RUN_GITHUB_ACTION_ID;
|
|
195
|
+
if (!projectName || !runId) {
|
|
196
|
+
logger_1.logger.error(`[Merge Reports] PROJECT_NAME and TEST_RUN_GITHUB_ACTION_ID must be set`);
|
|
197
|
+
return { success: false };
|
|
198
|
+
}
|
|
199
|
+
if (!fs_1.default.existsSync(blobDir)) {
|
|
200
|
+
logger_1.logger.error(`[Merge Reports] Blob directory does not exist: ${blobDir}`);
|
|
201
|
+
return { success: false };
|
|
202
|
+
}
|
|
203
|
+
const urlMappings = extractUrlMappingsFromBlobs(blobDir);
|
|
204
|
+
const { success } = await runPlaywrightMergeReports({
|
|
205
|
+
blobDir,
|
|
206
|
+
outputDir,
|
|
207
|
+
cwd,
|
|
208
|
+
});
|
|
209
|
+
if (!success) {
|
|
210
|
+
return { success: false };
|
|
211
|
+
}
|
|
212
|
+
const htmlFilePath = path_1.default.join(outputDir, "index.html");
|
|
213
|
+
const jsonFilePath = path_1.default.join(cwd, "summary.json");
|
|
214
|
+
await patchMergedHtmlReport(htmlFilePath, urlMappings);
|
|
215
|
+
await patchSummaryJson(jsonFilePath, urlMappings);
|
|
216
|
+
const hasR2Creds = process.env.R2_ACCOUNT_ID &&
|
|
217
|
+
process.env.R2_ACCESS_KEY_ID &&
|
|
218
|
+
process.env.R2_SECRET_ACCESS_KEY;
|
|
219
|
+
if (hasR2Creds) {
|
|
220
|
+
await uploadMergedReports(cwd, outputDir, {
|
|
221
|
+
projectName,
|
|
222
|
+
runId,
|
|
223
|
+
baseUrl: "https://reports.empirical.run",
|
|
224
|
+
uploadBucket: "test-report",
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
logger_1.logger.info(`[Merge Reports] R2 credentials not found, skipping upload`);
|
|
229
|
+
}
|
|
230
|
+
return { success: true };
|
|
231
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-specific-test.d.ts","sourceRoot":"","sources":["../../src/lib/run-specific-test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAY5D,wBAAsB,mBAAmB,CAAC,EACxC,KAAU,EACV,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,OAAO,GACR,EAAE;IACD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"run-specific-test.d.ts","sourceRoot":"","sources":["../../src/lib/run-specific-test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAY5D,wBAAsB,mBAAmB,CAAC,EACxC,KAAU,EACV,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,OAAO,GACR,EAAE;IACD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,YAAY,CAAC,CA2FxB"}
|
|
@@ -33,7 +33,7 @@ async function runSpecificTestsCmd({ tests = [], projects, passthroughArgs, plat
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
if (!matchingFilePath) {
|
|
36
|
-
const suitesPrefix = testCase.suites
|
|
36
|
+
const suitesPrefix = testCase.suites && testCase.suites.length > 0
|
|
37
37
|
? `${testCase.suites.join(" > ")} > `
|
|
38
38
|
: "";
|
|
39
39
|
const fullTestName = `${suitesPrefix}${testCase.name}`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stdout-parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;IACnD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CACjD,CA0CA"}
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlaywrightProject } from "@empiricalrun/shared-types";
|
|
1
|
+
import { PlaywrightProject } from "@empiricalrun/shared-types/tool-results";
|
|
2
2
|
import { Platform } from "../types";
|
|
3
3
|
export declare function getProjectsFromPlaywrightConfig(platform: Platform, repoDir: string): Promise<PlaywrightProject[]>;
|
|
4
4
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAK5E,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAyE9B"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export declare function markTestAsOnly({ sourceFile, parentDescribeNode, testCas
|
|
|
28
28
|
testCaseNode: Node;
|
|
29
29
|
filePath: string;
|
|
30
30
|
}): Promise<void>;
|
|
31
|
-
export
|
|
31
|
+
export { filterArrayByGlobMatchersSet } from "../glob-matcher";
|
|
32
32
|
export declare function labelTeardownProjects(projectNames: string[], platform: Platform, repoDir: string): Promise<{
|
|
33
33
|
isTeardown: boolean;
|
|
34
34
|
correspondingSetupProject: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/index.js
CHANGED
|
@@ -16,10 +16,10 @@ exports.buildRepoName = buildRepoName;
|
|
|
16
16
|
exports.getTypescriptTestBlock = getTypescriptTestBlock;
|
|
17
17
|
const fs_1 = require("fs");
|
|
18
18
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
19
|
-
const minimatch_1 = require("minimatch");
|
|
20
19
|
const path_1 = __importDefault(require("path"));
|
|
21
20
|
const ts_morph_1 = require("ts-morph");
|
|
22
21
|
const util_1 = require("util");
|
|
22
|
+
const glob_matcher_1 = require("../glob-matcher");
|
|
23
23
|
const cmd_1 = require("../lib/cmd");
|
|
24
24
|
const types_1 = require("../types");
|
|
25
25
|
const config_1 = require("./config");
|
|
@@ -167,20 +167,8 @@ async function markTestAsOnly({ sourceFile, parentDescribeNode, testCaseNode, fi
|
|
|
167
167
|
}
|
|
168
168
|
await promises_1.default.writeFile(filePath, updatedTestFileContent, "utf-8");
|
|
169
169
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
input,
|
|
173
|
-
// set of glob patterns to filter the array sequentially (takes the intersection of all sets)
|
|
174
|
-
globMatcherSets) => {
|
|
175
|
-
let filteredList = input;
|
|
176
|
-
globMatcherSets.forEach((matcherSet) => {
|
|
177
|
-
filteredList = filteredList.filter((item) => {
|
|
178
|
-
return matcherSet.some((matcherGlob) => (0, minimatch_1.minimatch)(item, matcherGlob));
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
return filteredList;
|
|
182
|
-
};
|
|
183
|
-
exports.filterArrayByGlobMatchersSet = filterArrayByGlobMatchersSet;
|
|
170
|
+
var glob_matcher_2 = require("../glob-matcher");
|
|
171
|
+
Object.defineProperty(exports, "filterArrayByGlobMatchersSet", { enumerable: true, get: function () { return glob_matcher_2.filterArrayByGlobMatchersSet; } });
|
|
184
172
|
async function labelTeardownProjects(projectNames, platform, repoDir) {
|
|
185
173
|
const allProjects = await (0, config_1.getProjectsFromPlaywrightConfig)(platform, repoDir);
|
|
186
174
|
return projectNames.map((projectName) => {
|
|
@@ -203,7 +191,7 @@ const generateProjectFilters = async ({ platform, filteringSets, repoDir, }) =>
|
|
|
203
191
|
const allProjects = await (0, config_1.getProjectsFromPlaywrightConfig)(platform, repoDir);
|
|
204
192
|
const allProjectNames = allProjects.map((project) => project.name);
|
|
205
193
|
const filters = filteringSets.map((matchingString) => matchingString.split(","));
|
|
206
|
-
const filteredProjects = (0,
|
|
194
|
+
const filteredProjects = (0, glob_matcher_1.filterArrayByGlobMatchersSet)(allProjectNames, filters);
|
|
207
195
|
if (filteredProjects.length === 0) {
|
|
208
196
|
throw new Error("No projects found in playwright config that matches the filtering criteria");
|
|
209
197
|
}
|
package/package.json
CHANGED
|
@@ -1,40 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-run",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"bin": {
|
|
9
|
-
"@empiricalrun/test-run": "dist/bin/index.js"
|
|
9
|
+
"@empiricalrun/test-run": "dist/bin/index.js",
|
|
10
|
+
"@empiricalrun/merge-reports": "dist/bin/merge-reports.js"
|
|
10
11
|
},
|
|
11
12
|
"main": "dist/index.js",
|
|
13
|
+
"exports": {
|
|
14
|
+
"./glob-matcher": {
|
|
15
|
+
"types": "./dist/glob-matcher.d.ts",
|
|
16
|
+
"default": "./dist/glob-matcher.js"
|
|
17
|
+
},
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
12
23
|
"repository": {
|
|
13
24
|
"type": "git",
|
|
14
25
|
"url": "https://github.com/empirical-run/empirical.git"
|
|
15
26
|
},
|
|
16
27
|
"author": "Empirical Team <hey@empirical.run>",
|
|
17
28
|
"dependencies": {
|
|
29
|
+
"adm-zip": "^0.5.16",
|
|
18
30
|
"async-retry": "^1.3.3",
|
|
19
31
|
"commander": "^12.1.0",
|
|
20
32
|
"console-log-level": "^1.4.1",
|
|
21
33
|
"dotenv": "^16.4.5",
|
|
22
34
|
"minimatch": "^10.0.1",
|
|
23
|
-
"ts-morph": "^23.0.0"
|
|
35
|
+
"ts-morph": "^23.0.0",
|
|
36
|
+
"@empiricalrun/r2-uploader": "^0.6.0"
|
|
24
37
|
},
|
|
25
38
|
"devDependencies": {
|
|
39
|
+
"@playwright/test": "1.53.2",
|
|
40
|
+
"@types/adm-zip": "^0.5.7",
|
|
26
41
|
"@types/async-retry": "^1.4.8",
|
|
27
42
|
"@types/console-log-level": "^1.4.5",
|
|
28
43
|
"@types/node": "^22.5.5",
|
|
29
|
-
"@playwright/test": "1.53.2",
|
|
30
44
|
"memfs": "^4.17.1",
|
|
31
|
-
"@empiricalrun/shared-types": "0.
|
|
45
|
+
"@empiricalrun/shared-types": "0.12.0"
|
|
32
46
|
},
|
|
33
47
|
"scripts": {
|
|
34
48
|
"dev": "tsc --build --watch",
|
|
35
49
|
"build": "tsc --build",
|
|
36
50
|
"clean": "tsc --build --clean",
|
|
37
|
-
"lint": "
|
|
51
|
+
"lint": "biome check --unsafe",
|
|
38
52
|
"test": "vitest run",
|
|
39
53
|
"test:watch": "vitest"
|
|
40
54
|
}
|
|
Binary file
|
|
Binary file
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/dashboard.ts","./src/index.ts","./src/logger.ts","./src/bin/index.ts","./src/lib/cmd.ts","./src/lib/run-all-tests.ts","./src/lib/run-specific-test.ts","./src/lib/memfs/read-hello-world.ts","./src/parser/index.ts","./src/types/index.ts","./src/utils/config-parser.ts","./src/utils/config.ts","./src/utils/index.ts"],"version":"5.8.3"}
|
|
1
|
+
{"root":["./src/dashboard.ts","./src/glob-matcher.ts","./src/index.ts","./src/logger.ts","./src/bin/index.ts","./src/bin/merge-reports.ts","./src/lib/cmd.ts","./src/lib/merge-reports.ts","./src/lib/run-all-tests.ts","./src/lib/run-specific-test.ts","./src/lib/memfs/read-hello-world.ts","./src/stdout-parser/index.ts","./src/types/index.ts","./src/utils/config-parser.ts","./src/utils/config.ts","./src/utils/index.ts"],"version":"5.8.3"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;IACnD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CACjD,CA0CA"}
|
package/eslint.config.mjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import libraryConfig from "../eslint-config/library.mjs";
|
|
2
|
-
import tsParser from "@typescript-eslint/parser";
|
|
3
|
-
|
|
4
|
-
export default [
|
|
5
|
-
...libraryConfig,
|
|
6
|
-
{
|
|
7
|
-
files: ["src/**/*.ts", "src/**/*.tsx"],
|
|
8
|
-
languageOptions: {
|
|
9
|
-
parser: tsParser,
|
|
10
|
-
parserOptions: {
|
|
11
|
-
project: "./tsconfig.lint.json",
|
|
12
|
-
tsconfigRootDir: import.meta.dirname,
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
];
|
|
File without changes
|
|
File without changes
|