@empiricalrun/test-run 0.8.4 → 0.9.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/README.md +0 -37
- package/dist/bin/index.js +9 -9
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -49
- package/dist/lib/cmd.d.ts +17 -0
- package/dist/lib/cmd.d.ts.map +1 -0
- package/dist/lib/cmd.js +106 -0
- package/dist/lib/memfs/read-hello-world.d.ts +3 -0
- package/dist/lib/memfs/read-hello-world.d.ts.map +1 -0
- package/dist/lib/memfs/read-hello-world.js +14 -0
- package/dist/lib/run-all-tests.d.ts +10 -4
- package/dist/lib/run-all-tests.d.ts.map +1 -1
- package/dist/lib/run-all-tests.js +18 -18
- package/dist/lib/run-specific-test.d.ts +9 -4
- package/dist/lib/run-specific-test.d.ts.map +1 -1
- package/dist/lib/run-specific-test.js +41 -51
- package/dist/types/index.d.ts +5 -8
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/config-parser.d.ts +0 -1
- package/dist/utils/config-parser.d.ts.map +1 -1
- package/dist/utils/config-parser.js +2 -25
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +43 -0
- package/dist/utils/index.d.ts +5 -22
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +47 -137
- package/package.json +3 -2
- package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @empiricalrun/test-run
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 72f4577: feat: stop marking files as only and move to cmd builder approach
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 97cef16: test: add memfs mocks for fs, remove unused config utils
|
|
12
|
+
- 28682e2: feat: use test-run cmd builder in test-gen, remove test.only marking
|
|
13
|
+
|
|
14
|
+
## 0.8.5
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 0634233: fix: run setup projects when test-run tool call has teardown project
|
|
19
|
+
|
|
3
20
|
## 0.8.4
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -104,26 +104,6 @@ This is useful for omitting teardown steps during certain runs or local developm
|
|
|
104
104
|
|
|
105
105
|
---
|
|
106
106
|
|
|
107
|
-
## 8. Using a “.rc” File or Token
|
|
108
|
-
|
|
109
|
-
You can optionally define a configuration in `empiricalrc.json` or pass the same data as a base64-encoded `--token`. For example:
|
|
110
|
-
|
|
111
|
-
```json
|
|
112
|
-
{
|
|
113
|
-
"tests": [
|
|
114
|
-
{
|
|
115
|
-
"name": "some-test",
|
|
116
|
-
"filePath": "tests/abc.spec.ts",
|
|
117
|
-
"suites": ["suiteA"]
|
|
118
|
-
}
|
|
119
|
-
]
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
If both are missing or do not define tests, the CLI uses command-line parameters (`-n`, `--file`, etc.).
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
107
|
## 9. Environment & Build (Optional)
|
|
128
108
|
|
|
129
109
|
If `TEST_RUN_ENVIRONMENT` is defined:
|
|
@@ -172,23 +152,6 @@ This flow makes sure tests run against the relevant environment or a fresh build
|
|
|
172
152
|
|
|
173
153
|
---
|
|
174
154
|
|
|
175
|
-
## 12. Changelog
|
|
176
|
-
|
|
177
|
-
For version history and patch notes, see [CHANGELOG.md]
|
|
178
|
-
|
|
179
|
-
---
|
|
180
|
-
|
|
181
|
-
## 13. Contributing
|
|
182
|
-
|
|
183
|
-
- **Lint** with `pnpm lint`.
|
|
184
|
-
- **Test** with `pnpm test`.
|
|
185
|
-
- **Build** with `pnpm build`.
|
|
186
|
-
- **Dev** watch mode with `pnpm dev`.
|
|
187
|
-
|
|
188
|
-
Feel free to open issues or pull requests for enhancements or clarifications.
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
155
|
## 14. Conclusion
|
|
193
156
|
|
|
194
157
|
@test-run simplifies orchestrating Playwright tests, especially for:
|
package/dist/bin/index.js
CHANGED
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
9
9
|
const dashboard_1 = require("../dashboard");
|
|
10
|
+
const cmd_1 = require("../lib/cmd");
|
|
10
11
|
const run_all_tests_1 = require("../lib/run-all-tests");
|
|
11
12
|
const run_specific_test_1 = require("../lib/run-specific-test");
|
|
12
13
|
const types_1 = require("../types");
|
|
@@ -16,7 +17,6 @@ dotenv_1.default.config({
|
|
|
16
17
|
path: [".env.local", ".env"],
|
|
17
18
|
});
|
|
18
19
|
(async function main() {
|
|
19
|
-
// TODO: add documentation of the test run
|
|
20
20
|
commander_1.program
|
|
21
21
|
.option("-n, --name <test-name>", "Name of the test to run")
|
|
22
22
|
.option("-s, --suites <suites>", "Suites under which the test is defined")
|
|
@@ -67,8 +67,7 @@ dotenv_1.default.config({
|
|
|
67
67
|
const suites = options.suites && options.suites.trim() !== ""
|
|
68
68
|
? options.suites?.split(",")
|
|
69
69
|
: undefined;
|
|
70
|
-
let tests = (
|
|
71
|
-
(0, config_parser_1.parseToken)(options.payload)?.tests ||
|
|
70
|
+
let tests = (0, config_parser_1.parseToken)(options.payload)?.tests ||
|
|
72
71
|
(options.name
|
|
73
72
|
? [
|
|
74
73
|
{
|
|
@@ -101,23 +100,24 @@ dotenv_1.default.config({
|
|
|
101
100
|
await (0, utils_1.handleTeardownSkipFlag)(directory);
|
|
102
101
|
}
|
|
103
102
|
const hasTestsFilter = tests && tests.length > 0;
|
|
104
|
-
let
|
|
103
|
+
let commandToRun;
|
|
105
104
|
if (hasTestsFilter) {
|
|
106
|
-
|
|
105
|
+
commandToRun = await (0, run_specific_test_1.runSpecificTestsCmd)({
|
|
107
106
|
tests,
|
|
108
107
|
projects: projectFilters,
|
|
109
|
-
|
|
108
|
+
passthroughArgs: pwOptions.join(" "),
|
|
110
109
|
platform,
|
|
111
110
|
});
|
|
112
111
|
}
|
|
113
112
|
else {
|
|
114
|
-
|
|
113
|
+
commandToRun = (0, run_all_tests_1.runAllTestsCmd)({
|
|
115
114
|
projects: projectFilters,
|
|
116
|
-
|
|
115
|
+
passthroughArgs: pwOptions.join(" "),
|
|
117
116
|
platform,
|
|
118
117
|
});
|
|
119
118
|
}
|
|
120
|
-
|
|
119
|
+
const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun);
|
|
120
|
+
if (!hasTestPassed) {
|
|
121
121
|
process.exit(1);
|
|
122
122
|
}
|
|
123
123
|
}
|
package/dist/dashboard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAK7C,eAAO,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAK7C,eAAO,MAAM,wBAAwB,GACnC,aAAa,MAAM,EACnB,iBAAiB,MAAM,KACtB,OAAO,CAAC;IACT,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;CACd,CAuDA,CAAC"}
|
package/dist/dashboard.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { runSpecificTestsCmd } from "./lib/run-specific-test";
|
|
2
|
+
export { runSpecificTestsCmd };
|
|
2
3
|
export declare function runSingleTest({ testName, suites, fileName, projects, envOverrides, }: {
|
|
3
4
|
testName: string;
|
|
4
5
|
suites: string[];
|
|
@@ -9,5 +10,4 @@ export declare function runSingleTest({ testName, suites, fileName, projects, en
|
|
|
9
10
|
hasTestPassed: boolean;
|
|
10
11
|
summaryJson: any;
|
|
11
12
|
}>;
|
|
12
|
-
export declare function listAllTests(cwd?: string): Promise<Record<string, TestCase>>;
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAO9D,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAE/B,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,GACb,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;CACvC;;;GAqBA"}
|
package/dist/index.js
CHANGED
|
@@ -3,74 +3,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.runSpecificTestsCmd = void 0;
|
|
7
|
+
exports.runSingleTest = runSingleTest;
|
|
7
8
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const cmd_1 = require("./lib/cmd");
|
|
9
11
|
const run_specific_test_1 = require("./lib/run-specific-test");
|
|
12
|
+
Object.defineProperty(exports, "runSpecificTestsCmd", { enumerable: true, get: function () { return run_specific_test_1.runSpecificTestsCmd; } });
|
|
10
13
|
const types_1 = require("./types");
|
|
11
|
-
const utils_1 = require("./utils");
|
|
12
14
|
// For test-run package, the library entrypoint, we only support web platform
|
|
13
15
|
// The bin entrypoint has support for mobile also
|
|
14
16
|
const supportedPlatform = types_1.Platform.WEB;
|
|
15
17
|
async function runSingleTest({ testName, suites, fileName, projects, envOverrides, }) {
|
|
16
18
|
const testDir = "tests";
|
|
17
19
|
const filePath = path_1.default.relative(process.cwd(), fileName);
|
|
18
|
-
const
|
|
20
|
+
const commandToRun = await (0, run_specific_test_1.runSpecificTestsCmd)({
|
|
19
21
|
tests: [{ name: testName, dir: testDir, filePath, suites }],
|
|
20
|
-
pwOptions: "",
|
|
21
22
|
projects,
|
|
22
23
|
envOverrides,
|
|
23
24
|
platform: supportedPlatform,
|
|
24
25
|
});
|
|
26
|
+
const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun);
|
|
25
27
|
const jsonFilePath = path_1.default.join(process.cwd(), "playwright-report", `summary.json`);
|
|
26
28
|
const jsonFileContents = await promises_1.default.readFile(jsonFilePath, "utf8");
|
|
27
29
|
const summaryJson = JSON.parse(jsonFileContents);
|
|
28
30
|
return {
|
|
29
|
-
hasTestPassed
|
|
31
|
+
hasTestPassed,
|
|
30
32
|
summaryJson,
|
|
31
33
|
};
|
|
32
34
|
}
|
|
33
|
-
exports.runSingleTest = runSingleTest;
|
|
34
|
-
async function listAllTests(cwd) {
|
|
35
|
-
const testRunner = (0, utils_1.getTestRunner)(types_1.Platform.WEB);
|
|
36
|
-
const env = Object({ ...process.env });
|
|
37
|
-
const command = ["npx", testRunner, "test", "--list"];
|
|
38
|
-
const { output } = await (0, utils_1.cmdWithOutput)(command, {
|
|
39
|
-
env,
|
|
40
|
-
cwd,
|
|
41
|
-
});
|
|
42
|
-
// Parse the output to extract test information
|
|
43
|
-
// Example format: "[chromium] › home.spec.ts:9:9 › describe 1 › describe 2 › has title"
|
|
44
|
-
const result = {};
|
|
45
|
-
output
|
|
46
|
-
.split("\n")
|
|
47
|
-
.filter((line) => line.trim() &&
|
|
48
|
-
line.trim().startsWith("[") &&
|
|
49
|
-
line.includes(".spec.ts:"))
|
|
50
|
-
.forEach((line) => {
|
|
51
|
-
// Extract project, file, line, and test name with suites
|
|
52
|
-
const match = line.match(/\[(.*?)\]\s+›\s+(.*?):(\d+):\d+\s+›\s+(.*)/);
|
|
53
|
-
if (!match || !match[1] || !match[2] || !match[3] || !match[4]) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const file = match[2];
|
|
57
|
-
const testPath = match[4];
|
|
58
|
-
const parts = testPath.split("›").map((p) => p.trim());
|
|
59
|
-
if (parts.length === 0) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const name = parts[parts.length - 1];
|
|
63
|
-
if (!name) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const suites = parts.length > 1 ? parts.slice(0, -1) : undefined;
|
|
67
|
-
const testCase = {
|
|
68
|
-
name,
|
|
69
|
-
filePath: file,
|
|
70
|
-
suites,
|
|
71
|
-
};
|
|
72
|
-
result[line.trim()] = testCase;
|
|
73
|
-
});
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
exports.listAllTests = listAllTests;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CommandToRun } from "../types";
|
|
2
|
+
export declare function getCommandFromString(command: string): {
|
|
3
|
+
command: string;
|
|
4
|
+
args: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function runTestsForCmd({ command, args, env }: CommandToRun): Promise<{
|
|
7
|
+
hasTestPassed: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function spawnCmd(command: string, args: string[], options: {
|
|
10
|
+
env?: Record<string, string>;
|
|
11
|
+
cwd?: string;
|
|
12
|
+
captureOutput?: boolean;
|
|
13
|
+
}): Promise<number | {
|
|
14
|
+
code: number;
|
|
15
|
+
output: string;
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=cmd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../src/lib/cmd.ts"],"names":[],"mappings":"AAEA,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,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,YAAY;;GASxE;AAED,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,OAAO,CAAC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA+CpD"}
|
package/dist/lib/cmd.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCommandFromString = getCommandFromString;
|
|
4
|
+
exports.runTestsForCmd = runTestsForCmd;
|
|
5
|
+
exports.spawnCmd = spawnCmd;
|
|
6
|
+
const child_process_1 = require("child_process");
|
|
7
|
+
function getCommandFromString(command) {
|
|
8
|
+
const regex = /[^\s"']+|"([^"]*)"|'([^']*)'/g;
|
|
9
|
+
const matches = command.match(regex) || [];
|
|
10
|
+
return {
|
|
11
|
+
command: matches[0],
|
|
12
|
+
args: matches.slice(1).map((match) => {
|
|
13
|
+
if ((match.startsWith('"') && match.endsWith('"')) ||
|
|
14
|
+
(match.startsWith("'") && match.endsWith("'"))) {
|
|
15
|
+
return match.slice(1, -1);
|
|
16
|
+
}
|
|
17
|
+
return match;
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
async function runTestsForCmd({ command, args, env }) {
|
|
22
|
+
console.log(`Running cmd: ${command} with args: ${args}`);
|
|
23
|
+
let hasTestPassed = true;
|
|
24
|
+
try {
|
|
25
|
+
await spawnCmd(command, args, { env });
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
hasTestPassed = false;
|
|
29
|
+
}
|
|
30
|
+
return { hasTestPassed };
|
|
31
|
+
}
|
|
32
|
+
async function spawnCmd(command, args, options) {
|
|
33
|
+
let output = options.captureOutput ? "" : undefined;
|
|
34
|
+
let errorLogs = [];
|
|
35
|
+
return new Promise((resolveFunc, rejectFunc) => {
|
|
36
|
+
const p = (0, child_process_1.spawn)(command, args, {
|
|
37
|
+
env: { ...process.env, ...options.env },
|
|
38
|
+
cwd: options.cwd,
|
|
39
|
+
// Ensure child process receives signals
|
|
40
|
+
detached: false,
|
|
41
|
+
});
|
|
42
|
+
// Setup signal handlers and get cleanup function
|
|
43
|
+
const cleanupSignalHandlers = setupProcessSignalHandlers(p);
|
|
44
|
+
p.stdout.on("data", (x) => {
|
|
45
|
+
const log = x.toString();
|
|
46
|
+
if (options.captureOutput) {
|
|
47
|
+
output += log;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
process.stdout.write(log);
|
|
51
|
+
}
|
|
52
|
+
if (log.includes("Error")) {
|
|
53
|
+
errorLogs.push(log);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
p.stderr.on("data", (x) => {
|
|
57
|
+
const log = x.toString();
|
|
58
|
+
process.stderr.write(log);
|
|
59
|
+
errorLogs.push(log);
|
|
60
|
+
});
|
|
61
|
+
p.on("exit", (code) => {
|
|
62
|
+
// Clean up signal handlers when the process exits
|
|
63
|
+
cleanupSignalHandlers();
|
|
64
|
+
if (code != 0) {
|
|
65
|
+
// assuming last log is the error message before exiting
|
|
66
|
+
rejectFunc(errorLogs.slice(-3).join("\n"));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
resolveFunc(options.captureOutput ? { code: code, output: output } : code);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function setupProcessSignalHandlers(proc) {
|
|
75
|
+
const handleSignal = async (signal) => {
|
|
76
|
+
console.log(`\nReceived ${signal}, gracefully shutting down...`);
|
|
77
|
+
if (proc && !proc.killed) {
|
|
78
|
+
// Forward the signal to the child process
|
|
79
|
+
proc.kill(signal);
|
|
80
|
+
// Wait for the child process to exit
|
|
81
|
+
await new Promise((resolve) => {
|
|
82
|
+
proc.once("exit", () => {
|
|
83
|
+
resolve();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
process.exit(0);
|
|
88
|
+
};
|
|
89
|
+
const sigintHandler = async () => await handleSignal("SIGINT");
|
|
90
|
+
const sigtermHandler = async () => await handleSignal("SIGTERM");
|
|
91
|
+
const otherSignalHandlers = ["SIGABRT", "SIGHUP", "SIGQUIT"].map((signal) => {
|
|
92
|
+
const handler = () => console.log(`Received ${signal}, which is a no-op`);
|
|
93
|
+
process.once(signal, handler);
|
|
94
|
+
return { signal, handler };
|
|
95
|
+
});
|
|
96
|
+
process.once("SIGINT", sigintHandler);
|
|
97
|
+
process.once("SIGTERM", sigtermHandler);
|
|
98
|
+
// Return a cleanup function that removes all signal handlers
|
|
99
|
+
return () => {
|
|
100
|
+
process.removeListener("SIGINT", sigintHandler);
|
|
101
|
+
process.removeListener("SIGTERM", sigtermHandler);
|
|
102
|
+
otherSignalHandlers.forEach(({ signal, handler }) => {
|
|
103
|
+
process.removeListener(signal, handler);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-hello-world.d.ts","sourceRoot":"","sources":["../../../src/lib/memfs/read-hello-world.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,UAE1C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,WAE3C"}
|
|
@@ -0,0 +1,14 @@
|
|
|
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.readHelloWorld = readHelloWorld;
|
|
7
|
+
exports.verifyDirectory = verifyDirectory;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
function readHelloWorld(path) {
|
|
10
|
+
return fs_1.default.readFileSync(path, "utf-8");
|
|
11
|
+
}
|
|
12
|
+
function verifyDirectory(path) {
|
|
13
|
+
return fs_1.default.existsSync(path) && fs_1.default.statSync(path).isDirectory();
|
|
14
|
+
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { CommandToRun, Platform, TestCase } from "../types";
|
|
2
|
+
export declare function runAllTestsCmd({ projects, passthroughArgs, patternsToGrep, filesFilter, envOverrides, platform, }: {
|
|
3
|
+
tests?: TestCase[];
|
|
4
|
+
projects: string[];
|
|
5
|
+
passthroughArgs?: string;
|
|
6
|
+
platform: Platform;
|
|
7
|
+
filesFilter?: string;
|
|
8
|
+
envOverrides?: Record<string, string>;
|
|
9
|
+
patternsToGrep?: string[];
|
|
10
|
+
}): CommandToRun;
|
|
5
11
|
//# sourceMappingURL=run-all-tests.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-all-tests.d.ts","sourceRoot":"","sources":["../../src/lib/run-all-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"run-all-tests.d.ts","sourceRoot":"","sources":["../../src/lib/run-all-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAQ5D,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,eAAe,EACf,cAAc,EACd,WAAW,EACX,YAAY,EACZ,QAAQ,GACT,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,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B,GAAG,YAAY,CAmBf"}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.runAllTestsCmd = runAllTestsCmd;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
5
|
+
const cmd_1 = require("./cmd");
|
|
6
|
+
function normalizeSpaces(command) {
|
|
7
|
+
return command.trim().replace(/ +/g, " ");
|
|
8
|
+
}
|
|
9
|
+
function runAllTestsCmd({ projects, passthroughArgs, patternsToGrep, filesFilter, envOverrides, platform, }) {
|
|
10
|
+
const testRunner = (0, utils_1.getTestRunner)(platform);
|
|
11
|
+
const projectsArg = (projects || [])
|
|
12
|
+
.map((project) => `--project ${project}`)
|
|
13
|
+
.join(" ");
|
|
14
|
+
const grepArgs = (patternsToGrep || [])
|
|
15
|
+
.map((pattern) => ` -g "${pattern}"`)
|
|
16
|
+
.join(" ");
|
|
17
|
+
let args = ` ${filesFilter || ""} ${grepArgs} ${projectsArg} ${passthroughArgs || ""}`;
|
|
18
|
+
const env = Object.assign({ ...process.env, PW_TEST_HTML_REPORT_OPEN: "never" }, envOverrides);
|
|
19
|
+
const testRunCmd = normalizeSpaces(`npx ${testRunner} test ${args}`);
|
|
20
20
|
return {
|
|
21
|
-
|
|
21
|
+
...(0, cmd_1.getCommandFromString)(testRunCmd),
|
|
22
|
+
env,
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
|
-
exports.runAllTests = runAllTests;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { CommandToRun, Platform, TestCase } from "../types";
|
|
2
|
+
export declare function runSpecificTestsCmd({ tests, projects, passthroughArgs, platform, envOverrides, }: {
|
|
3
|
+
tests?: TestCase[];
|
|
4
|
+
projects: string[];
|
|
5
|
+
passthroughArgs?: string;
|
|
6
|
+
platform: Platform;
|
|
7
|
+
filesFilter?: string;
|
|
8
|
+
envOverrides?: Record<string, string>;
|
|
9
|
+
}): Promise<CommandToRun>;
|
|
5
10
|
//# sourceMappingURL=run-specific-test.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-specific-test.d.ts","sourceRoot":"","sources":["../../src/lib/run-specific-test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-specific-test.d.ts","sourceRoot":"","sources":["../../src/lib/run-specific-test.ts"],"names":[],"mappings":"AAAA,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,GACb,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;CACvC,GAAG,OAAO,CAAC,YAAY,CAAC,CAiFxB"}
|
|
@@ -1,37 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
3
|
+
exports.runSpecificTestsCmd = runSpecificTestsCmd;
|
|
9
4
|
const utils_1 = require("../utils");
|
|
10
5
|
const run_all_tests_1 = require("./run-all-tests");
|
|
11
|
-
function
|
|
12
|
-
const events = ["beforeExit", "exit", "SIGINT", "SIGTERM"];
|
|
13
|
-
events.forEach((event) => process.on(event, cleanup));
|
|
14
|
-
return () => {
|
|
15
|
-
events.forEach((event) => process.removeListener(event, cleanup));
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
async function runSpecificTests({ tests = [], projects, pwOptions, platform, envOverrides, }) {
|
|
6
|
+
async function runSpecificTestsCmd({ tests = [], projects, passthroughArgs, platform, envOverrides, }) {
|
|
19
7
|
if (!tests || tests.length === 0) {
|
|
20
8
|
throw new Error("No tests found");
|
|
21
9
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// these needs to handle by listening to process exit/kill events
|
|
25
|
-
const revertFileContent = () => {
|
|
26
|
-
try {
|
|
27
|
-
Object.keys(touchedFiles).forEach((filePath) => {
|
|
28
|
-
(0, fs_1.writeFileSync)(filePath, touchedFiles[filePath], "utf-8");
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
console.error("Error while cleaning up test file:", error);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
10
|
+
let patternsToGrep = [];
|
|
11
|
+
let filesToRun = [];
|
|
35
12
|
for (const testCase of tests) {
|
|
36
13
|
const files = await (0, utils_1.getAllFilePaths)(testCase.dir, {
|
|
37
14
|
filePath: testCase.filePath,
|
|
@@ -49,42 +26,55 @@ async function runSpecificTests({ tests = [], projects, pwOptions, platform, env
|
|
|
49
26
|
}
|
|
50
27
|
}
|
|
51
28
|
if (!matchingFilePath) {
|
|
52
|
-
const
|
|
53
|
-
|
|
29
|
+
const suitesPrefix = testCase.suites
|
|
30
|
+
? `${testCase.suites.join(" > ")} > `
|
|
31
|
+
: "";
|
|
32
|
+
const fullTestName = `${suitesPrefix}${testCase.name}`;
|
|
33
|
+
const message = `No test block found for name: "${fullTestName}" in "${testCase.filePath}"`;
|
|
54
34
|
throw Error(message);
|
|
55
35
|
}
|
|
56
|
-
|
|
36
|
+
else {
|
|
37
|
+
filesToRun.push(matchingFilePath);
|
|
38
|
+
}
|
|
39
|
+
const { testCaseNode } = await (0, utils_1.getTestCaseNode)({
|
|
57
40
|
filePath: matchingFilePath,
|
|
58
41
|
scenarioName: testCase.name,
|
|
59
42
|
suites: testCase.suites,
|
|
60
43
|
});
|
|
61
|
-
const parentDescribe = (0, utils_1.findFirstSerialDescribeBlock)(testCaseNode);
|
|
62
44
|
const isFileMarkedSerial = await (0, utils_1.hasTopLevelDescribeConfigureWithSerialMode)(matchingFilePath);
|
|
63
|
-
const currentFileContent = await promises_1.default.readFile(matchingFilePath, "utf-8");
|
|
64
|
-
// if file is not marked as touched, mark it as touched
|
|
65
|
-
if (!touchedFiles[matchingFilePath]) {
|
|
66
|
-
touchedFiles[matchingFilePath] = currentFileContent;
|
|
67
|
-
}
|
|
68
|
-
// if the file is not marked serial, we need to mark the test or describe block as only
|
|
69
45
|
if (!isFileMarkedSerial && testCaseNode) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
46
|
+
const parentDescribe = (0, utils_1.findFirstSerialDescribeBlock)(testCaseNode);
|
|
47
|
+
if (!parentDescribe) {
|
|
48
|
+
patternsToGrep.push(testCase.name);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
const parentDescribeName = (0, utils_1.getDescribeBlockName)(parentDescribe);
|
|
52
|
+
if (parentDescribeName) {
|
|
53
|
+
patternsToGrep.push(parentDescribeName);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
76
56
|
}
|
|
77
57
|
}
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
58
|
+
const teardownLabels = await (0, utils_1.labelTeardownProjects)(projects, platform);
|
|
59
|
+
const isRunningForTeardownProjectOnly = teardownLabels && teardownLabels.every((label) => label.isTeardown);
|
|
60
|
+
if (isRunningForTeardownProjectOnly) {
|
|
61
|
+
// To run teardown projects, we need to run the `setup` project first, and playwright runs
|
|
62
|
+
// teardown automatically, when the corresponding setup project is run.
|
|
63
|
+
projects = teardownLabels
|
|
64
|
+
.map((label) => label.correspondingSetupProject)
|
|
65
|
+
.filter((project) => project !== undefined);
|
|
66
|
+
// We also remove any files or grep filters, because we want setup and teardown to run completely
|
|
67
|
+
// We could add a grep invert flag for other teardown tests to reduce the number of tests that run
|
|
68
|
+
filesToRun = [];
|
|
69
|
+
patternsToGrep = [];
|
|
70
|
+
}
|
|
71
|
+
const commandToRun = (0, run_all_tests_1.runAllTestsCmd)({
|
|
72
|
+
filesFilter: [...new Set(filesToRun)].join(" "),
|
|
73
|
+
passthroughArgs,
|
|
82
74
|
projects,
|
|
83
75
|
envOverrides,
|
|
84
76
|
platform,
|
|
77
|
+
patternsToGrep,
|
|
85
78
|
});
|
|
86
|
-
|
|
87
|
-
revertFileContent();
|
|
88
|
-
return result;
|
|
79
|
+
return commandToRun;
|
|
89
80
|
}
|
|
90
|
-
exports.runSpecificTests = runSpecificTests;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -7,14 +7,6 @@ export type TestCase = {
|
|
|
7
7
|
export type Config = {
|
|
8
8
|
tests: TestCase[];
|
|
9
9
|
} | undefined;
|
|
10
|
-
export type TestRunParameters = {
|
|
11
|
-
tests?: TestCase[];
|
|
12
|
-
projects: string[];
|
|
13
|
-
pwOptions: string;
|
|
14
|
-
platform: Platform;
|
|
15
|
-
filesFilter?: string;
|
|
16
|
-
envOverrides?: Record<string, string>;
|
|
17
|
-
};
|
|
18
10
|
export type Environment = {
|
|
19
11
|
id: number;
|
|
20
12
|
project_id: number;
|
|
@@ -44,4 +36,9 @@ export type PlaywProjectConfig = {
|
|
|
44
36
|
teardown?: string;
|
|
45
37
|
testMatch: string | RegExp;
|
|
46
38
|
};
|
|
39
|
+
export type CommandToRun = {
|
|
40
|
+
command: string;
|
|
41
|
+
args: string[];
|
|
42
|
+
env: Record<string, string>;
|
|
43
|
+
};
|
|
47
44
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC;AAEvD,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,QAAQ,EAAE,QAAQ,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,oBAAY,QAAQ;IAClB,GAAG,QAAQ;IACX,OAAO,YAAY;IACnB,GAAG,QAAQ;CACZ;AAED,oBAAY,aAAa;IACvB,UAAU,eAAe;IACzB,SAAS,cAAc;CACxB;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../../src/utils/config-parser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../../src/utils/config-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAchD;AAED,wBAAgB,sBAAsB,SAAK"}
|
|
@@ -1,28 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
|
|
8
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
|
-
async function parseRcConfig() {
|
|
10
|
-
// check if file exists
|
|
11
|
-
if (!(0, fs_1.existsSync)("empiricalrc.json")) {
|
|
12
|
-
return undefined;
|
|
13
|
-
}
|
|
14
|
-
try {
|
|
15
|
-
const rcConfig = await promises_1.default.readFile("empiricalrc.json", "utf-8");
|
|
16
|
-
const json = JSON.parse(rcConfig);
|
|
17
|
-
// TODO: validate the json
|
|
18
|
-
return json;
|
|
19
|
-
}
|
|
20
|
-
catch (e) {
|
|
21
|
-
console.error("Error parsing rc file:", e);
|
|
22
|
-
}
|
|
23
|
-
return undefined;
|
|
24
|
-
}
|
|
25
|
-
exports.parseRcConfig = parseRcConfig;
|
|
3
|
+
exports.parseToken = parseToken;
|
|
4
|
+
exports.buildConfigFromCliArgs = buildConfigFromCliArgs;
|
|
26
5
|
function parseToken(token) {
|
|
27
6
|
if (!token) {
|
|
28
7
|
return undefined;
|
|
@@ -39,6 +18,4 @@ function parseToken(token) {
|
|
|
39
18
|
}
|
|
40
19
|
return undefined;
|
|
41
20
|
}
|
|
42
|
-
exports.parseToken = parseToken;
|
|
43
21
|
function buildConfigFromCliArgs() { }
|
|
44
|
-
exports.buildConfigFromCliArgs = buildConfigFromCliArgs;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Platform } from "../types";
|
|
2
|
+
type PlaywrightProject = {
|
|
3
|
+
name: string;
|
|
4
|
+
use: any;
|
|
5
|
+
testMatch: string[] | string | undefined;
|
|
6
|
+
testIgnore: string[] | string | undefined;
|
|
7
|
+
teardown: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare function getProjectsFromPlaywrightConfig(platform: Platform): Promise<PlaywrightProject[]>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,GAAG,CAAC;IACT,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAqC9B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
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.getProjectsFromPlaywrightConfig = getProjectsFromPlaywrightConfig;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
// For TypeScript type safety
|
|
9
|
+
let tsxImport = null;
|
|
10
|
+
const types_1 = require("../types");
|
|
11
|
+
async function getProjectsFromPlaywrightConfig(platform) {
|
|
12
|
+
const configName = platform === types_1.Platform.WEB ? "playwright.config.ts" : "appwright.config.ts";
|
|
13
|
+
const directoryPath = ".";
|
|
14
|
+
const pwFile = path_1.default.resolve(directoryPath, configName);
|
|
15
|
+
if (typeof window !== "undefined") {
|
|
16
|
+
throw new Error("readPlaywrightConfig cannot be used in browser environments");
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
// Only initialize on server side
|
|
20
|
+
// This will only execute on the server
|
|
21
|
+
await import("tsx/cjs/api")
|
|
22
|
+
.then((module) => {
|
|
23
|
+
tsxImport = module;
|
|
24
|
+
})
|
|
25
|
+
.catch(() => {
|
|
26
|
+
console.warn("Failed to import tsx: --->");
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (!tsxImport) {
|
|
30
|
+
console.warn("tsx module not available");
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
const repoDir = process.cwd();
|
|
34
|
+
const [lastDir] = repoDir.split("/").reverse();
|
|
35
|
+
try {
|
|
36
|
+
const playwrightConfig = (await tsxImport.require(pwFile, `${repoDir}/${lastDir}`)).default;
|
|
37
|
+
return playwrightConfig.projects;
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.error("Error getting project list from playwright config", err);
|
|
41
|
+
}
|
|
42
|
+
return [];
|
|
43
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,26 +1,5 @@
|
|
|
1
1
|
import { Node, SourceFile } from "ts-morph";
|
|
2
2
|
import { Platform, TestFramework } from "../types";
|
|
3
|
-
export declare function cmd(command: string[], options: {
|
|
4
|
-
env?: Record<string, string>;
|
|
5
|
-
cwd?: string;
|
|
6
|
-
captureOutput?: boolean;
|
|
7
|
-
}): Promise<number | {
|
|
8
|
-
code: number;
|
|
9
|
-
output: string;
|
|
10
|
-
}>;
|
|
11
|
-
export declare function cmdWithOutput(command: string[], options: {
|
|
12
|
-
env?: Record<string, string>;
|
|
13
|
-
cwd?: string;
|
|
14
|
-
}): Promise<{
|
|
15
|
-
code: number;
|
|
16
|
-
output: string;
|
|
17
|
-
}>;
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* @param {string} [directoryPath=""]
|
|
22
|
-
* @return {*} {Promise<string[]>}
|
|
23
|
-
*/
|
|
24
3
|
export declare function getAllFilePaths(directoryPath?: string, filters?: {
|
|
25
4
|
filePath?: string;
|
|
26
5
|
}): Promise<string[]>;
|
|
@@ -38,6 +17,7 @@ export declare function hasTestBlock({ filePath, scenarioName, suites, }: {
|
|
|
38
17
|
scenarioName: string;
|
|
39
18
|
suites?: string[];
|
|
40
19
|
}): Promise<boolean>;
|
|
20
|
+
export declare function getDescribeBlockName(node: Node): string | undefined;
|
|
41
21
|
export declare function findFirstSerialDescribeBlock(node: Node | undefined): Node | undefined;
|
|
42
22
|
export declare function hasTopLevelDescribeConfigureWithSerialMode(filePath: string): Promise<boolean>;
|
|
43
23
|
export declare function markTestAsOnly({ sourceFile, parentDescribeNode, testCaseNode, filePath, }: {
|
|
@@ -46,8 +26,11 @@ export declare function markTestAsOnly({ sourceFile, parentDescribeNode, testCas
|
|
|
46
26
|
testCaseNode: Node;
|
|
47
27
|
filePath: string;
|
|
48
28
|
}): Promise<void>;
|
|
49
|
-
export declare function getProjectsFromPlaywrightConfig(platform: Platform): Promise<any>;
|
|
50
29
|
export declare const filterArrayByGlobMatchersSet: (input: string[], globMatcherSets: string[][]) => string[];
|
|
30
|
+
export declare function labelTeardownProjects(projectNames: string[], platform: Platform): Promise<{
|
|
31
|
+
isTeardown: boolean;
|
|
32
|
+
correspondingSetupProject: string | undefined;
|
|
33
|
+
}[]>;
|
|
51
34
|
export declare const generateProjectFilters: ({ platform, filteringSets, }: {
|
|
52
35
|
platform: Platform;
|
|
53
36
|
filteringSets: string[];
|
|
@@ -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":"AAIA,OAAO,EAAE,IAAI,EAAW,UAAU,EAAc,MAAM,UAAU,CAAC;AAIjE,OAAO,EAAsB,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGvE,wBAAsB,eAAe,CACnC,aAAa,GAAE,MAAgB,EAC/B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BnB;AAED,eAAO,MAAM,gCAAgC,GAC3C,YAAY,UAAU,KACrB,MAgBF,CAAC;AAEF,wBAAsB,eAAe,CAAC,EACpC,QAAQ,EACR,YAAY,EACZ,MAAM,GACP,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,GAAG,OAAO,CAAC;IAAE,YAAY,EAAE,IAAI,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAAC,CAQtE;AAED,wBAAsB,YAAY,CAAC,EACjC,QAAQ,EACR,YAAY,EACZ,MAAM,GACP,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAWnE;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,IAAI,GAAG,SAAS,CA2BlB;AAED,wBAAsB,0CAA0C,CAC9D,QAAQ,EAAE,MAAM,oBA+BjB;AAED,wBAAsB,cAAc,CAAC,EACnC,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,UAAU,EAAE,UAAU,CAAC;IACvB,kBAAkB,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACtC,YAAY,EAAE,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,iBAgBA;AAED,eAAO,MAAM,4BAA4B,GAEvC,OAAO,MAAM,EAAE,EAGf,iBAAiB,MAAM,EAAE,EAAE,KAC1B,MAAM,EAUR,CAAC;AAEF,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EAAE,EACtB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CACR;IACE,UAAU,EAAE,OAAO,CAAC;IACpB,yBAAyB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/C,EAAE,CACJ,CAkBA;AAED,eAAO,MAAM,sBAAsB,GAAU,8BAG1C;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,KAAG,OAAO,CAAC,MAAM,EAAE,CAgBnB,CAAC;AAEF,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,eAAO,MAAM,uBAAuB,QAAa,OAAO,CACtD,MAAM,GAAG,SAAS,CAMnB,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,IAAI,CAWlE,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,UAAU,QAAQ,KAAG,aAIlD,CAAC;AA4DF,eAAO,MAAM,sBAAsB,GAAU,WAAW,MAAM,kBAkB7D,CAAC;AA0BF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,MAAM,EACN,OAAO,GACR,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG;IACF,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;CACxB,CA8CA"}
|
package/dist/utils/index.js
CHANGED
|
@@ -3,104 +3,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
|
|
6
|
+
exports.handleTeardownSkipFlag = exports.getTestRunner = exports.downloadBuild = exports.pickNameFromPackageJson = exports.generateProjectFilters = exports.filterArrayByGlobMatchersSet = exports.getTestModuleAliasFromSourceFile = void 0;
|
|
7
|
+
exports.getAllFilePaths = getAllFilePaths;
|
|
8
|
+
exports.getTestCaseNode = getTestCaseNode;
|
|
9
|
+
exports.hasTestBlock = hasTestBlock;
|
|
10
|
+
exports.getDescribeBlockName = getDescribeBlockName;
|
|
11
|
+
exports.findFirstSerialDescribeBlock = findFirstSerialDescribeBlock;
|
|
12
|
+
exports.hasTopLevelDescribeConfigureWithSerialMode = hasTopLevelDescribeConfigureWithSerialMode;
|
|
13
|
+
exports.markTestAsOnly = markTestAsOnly;
|
|
14
|
+
exports.labelTeardownProjects = labelTeardownProjects;
|
|
15
|
+
exports.buildRepoName = buildRepoName;
|
|
16
|
+
exports.getTypescriptTestBlock = getTypescriptTestBlock;
|
|
8
17
|
const fs_1 = require("fs");
|
|
9
18
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
10
19
|
const minimatch_1 = require("minimatch");
|
|
11
20
|
const path_1 = __importDefault(require("path"));
|
|
12
21
|
const ts_morph_1 = require("ts-morph");
|
|
13
|
-
// For TypeScript type safety
|
|
14
|
-
let tsxImport = null;
|
|
15
22
|
const util_1 = require("util");
|
|
23
|
+
const cmd_1 = require("../lib/cmd");
|
|
16
24
|
const types_1 = require("../types");
|
|
17
|
-
|
|
18
|
-
const handleSignal = async (signal) => {
|
|
19
|
-
console.log(`\nReceived ${signal}, gracefully shutting down...`);
|
|
20
|
-
if (proc && !proc.killed) {
|
|
21
|
-
// Forward the signal to the child process
|
|
22
|
-
proc.kill(signal);
|
|
23
|
-
// Wait for the child process to exit
|
|
24
|
-
await new Promise((resolve) => {
|
|
25
|
-
proc.once("exit", () => {
|
|
26
|
-
resolve();
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
process.exit(0);
|
|
31
|
-
};
|
|
32
|
-
const sigintHandler = async () => await handleSignal("SIGINT");
|
|
33
|
-
const sigtermHandler = async () => await handleSignal("SIGTERM");
|
|
34
|
-
const otherSignalHandlers = ["SIGABRT", "SIGHUP", "SIGQUIT"].map((signal) => {
|
|
35
|
-
const handler = () => console.log(`Received ${signal}, which is a no-op`);
|
|
36
|
-
process.once(signal, handler);
|
|
37
|
-
return { signal, handler };
|
|
38
|
-
});
|
|
39
|
-
process.once("SIGINT", sigintHandler);
|
|
40
|
-
process.once("SIGTERM", sigtermHandler);
|
|
41
|
-
// Return a cleanup function that removes all signal handlers
|
|
42
|
-
return () => {
|
|
43
|
-
process.removeListener("SIGINT", sigintHandler);
|
|
44
|
-
process.removeListener("SIGTERM", sigtermHandler);
|
|
45
|
-
otherSignalHandlers.forEach(({ signal, handler }) => {
|
|
46
|
-
process.removeListener(signal, handler);
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
async function cmd(command, options) {
|
|
51
|
-
let output = options.captureOutput ? "" : undefined;
|
|
52
|
-
let errorLogs = [];
|
|
53
|
-
return new Promise((resolveFunc, rejectFunc) => {
|
|
54
|
-
const p = (0, child_process_1.spawn)(command[0], command.slice(1), {
|
|
55
|
-
env: { ...process.env, ...options.env },
|
|
56
|
-
cwd: options.cwd,
|
|
57
|
-
// Ensure child process receives signals
|
|
58
|
-
detached: false,
|
|
59
|
-
});
|
|
60
|
-
// Setup signal handlers and get cleanup function
|
|
61
|
-
const cleanupSignalHandlers = setupProcessSignalHandlers(p);
|
|
62
|
-
p.stdout.on("data", (x) => {
|
|
63
|
-
const log = x.toString();
|
|
64
|
-
if (options.captureOutput) {
|
|
65
|
-
output += log;
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
process.stdout.write(log);
|
|
69
|
-
}
|
|
70
|
-
if (log.includes("Error")) {
|
|
71
|
-
errorLogs.push(log);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
p.stderr.on("data", (x) => {
|
|
75
|
-
const log = x.toString();
|
|
76
|
-
process.stderr.write(log);
|
|
77
|
-
errorLogs.push(log);
|
|
78
|
-
});
|
|
79
|
-
p.on("exit", (code) => {
|
|
80
|
-
// Clean up signal handlers when the process exits
|
|
81
|
-
cleanupSignalHandlers();
|
|
82
|
-
if (code != 0) {
|
|
83
|
-
// assuming last log is the error message before exiting
|
|
84
|
-
rejectFunc(errorLogs.slice(-3).join("\n"));
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
resolveFunc(options.captureOutput ? { code: code, output: output } : code);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
exports.cmd = cmd;
|
|
93
|
-
async function cmdWithOutput(command, options) {
|
|
94
|
-
const result = await cmd(command, { ...options, captureOutput: true });
|
|
95
|
-
return result;
|
|
96
|
-
}
|
|
97
|
-
exports.cmdWithOutput = cmdWithOutput;
|
|
98
|
-
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* @param {string} [directoryPath=""]
|
|
102
|
-
* @return {*} {Promise<string[]>}
|
|
103
|
-
*/
|
|
25
|
+
const config_1 = require("./config");
|
|
104
26
|
async function getAllFilePaths(directoryPath = "tests", filters = {}) {
|
|
105
27
|
let filePaths = [];
|
|
106
28
|
try {
|
|
@@ -131,7 +53,6 @@ async function getAllFilePaths(directoryPath = "tests", filters = {}) {
|
|
|
131
53
|
}
|
|
132
54
|
return filePaths;
|
|
133
55
|
}
|
|
134
|
-
exports.getAllFilePaths = getAllFilePaths;
|
|
135
56
|
const getTestModuleAliasFromSourceFile = (sourceFile) => {
|
|
136
57
|
return (sourceFile
|
|
137
58
|
.getImportDeclarations()
|
|
@@ -155,7 +76,6 @@ async function getTestCaseNode({ filePath, scenarioName, suites, }) {
|
|
|
155
76
|
});
|
|
156
77
|
return { testCaseNode: testNode, sourceFile };
|
|
157
78
|
}
|
|
158
|
-
exports.getTestCaseNode = getTestCaseNode;
|
|
159
79
|
async function hasTestBlock({ filePath, scenarioName, suites, }) {
|
|
160
80
|
const { testCaseNode } = await getTestCaseNode({
|
|
161
81
|
filePath,
|
|
@@ -164,7 +84,18 @@ async function hasTestBlock({ filePath, scenarioName, suites, }) {
|
|
|
164
84
|
});
|
|
165
85
|
return !!testCaseNode;
|
|
166
86
|
}
|
|
167
|
-
|
|
87
|
+
function getDescribeBlockName(node) {
|
|
88
|
+
if (ts_morph_1.Node.isCallExpression(node)) {
|
|
89
|
+
const expression = node.getExpression();
|
|
90
|
+
if (expression.getText().includes("test.describe")) {
|
|
91
|
+
const [firstArg] = node.getArguments();
|
|
92
|
+
if (firstArg && ts_morph_1.Node.isStringLiteral(firstArg)) {
|
|
93
|
+
return firstArg.getLiteralValue();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
168
99
|
function findFirstSerialDescribeBlock(node) {
|
|
169
100
|
let currentNode = node;
|
|
170
101
|
// Traverse upwards until we find a 'describe' block with 'serial: true'
|
|
@@ -189,7 +120,6 @@ function findFirstSerialDescribeBlock(node) {
|
|
|
189
120
|
}
|
|
190
121
|
return undefined; // Return undefined if no 'describe' with serial: true is found
|
|
191
122
|
}
|
|
192
|
-
exports.findFirstSerialDescribeBlock = findFirstSerialDescribeBlock;
|
|
193
123
|
async function hasTopLevelDescribeConfigureWithSerialMode(filePath) {
|
|
194
124
|
const project = new ts_morph_1.Project();
|
|
195
125
|
const content = await promises_1.default.readFile(filePath, "utf-8");
|
|
@@ -217,7 +147,6 @@ async function hasTopLevelDescribeConfigureWithSerialMode(filePath) {
|
|
|
217
147
|
}
|
|
218
148
|
return false;
|
|
219
149
|
}
|
|
220
|
-
exports.hasTopLevelDescribeConfigureWithSerialMode = hasTopLevelDescribeConfigureWithSerialMode;
|
|
221
150
|
async function markTestAsOnly({ sourceFile, parentDescribeNode, testCaseNode, filePath, }) {
|
|
222
151
|
let updatedTestFileContent = sourceFile.getFullText();
|
|
223
152
|
if (!parentDescribeNode) {
|
|
@@ -236,42 +165,6 @@ async function markTestAsOnly({ sourceFile, parentDescribeNode, testCaseNode, fi
|
|
|
236
165
|
}
|
|
237
166
|
await promises_1.default.writeFile(filePath, updatedTestFileContent, "utf-8");
|
|
238
167
|
}
|
|
239
|
-
exports.markTestAsOnly = markTestAsOnly;
|
|
240
|
-
async function getProjectsFromPlaywrightConfig(platform) {
|
|
241
|
-
const configName = platform === types_1.Platform.WEB ? "playwright.config.ts" : "appwright.config.ts";
|
|
242
|
-
const directoryPath = ".";
|
|
243
|
-
const pwFile = path_1.default.resolve(directoryPath, configName);
|
|
244
|
-
if (typeof window !== "undefined") {
|
|
245
|
-
throw new Error("readPlaywrightConfig cannot be used in browser environments");
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
// Only initialize on server side
|
|
249
|
-
// This will only execute on the server
|
|
250
|
-
await import("tsx/cjs/api")
|
|
251
|
-
.then((module) => {
|
|
252
|
-
tsxImport = module;
|
|
253
|
-
})
|
|
254
|
-
.catch(() => {
|
|
255
|
-
console.warn("Failed to import tsx: --->");
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
if (!tsxImport) {
|
|
259
|
-
console.warn("tsx module not available");
|
|
260
|
-
return [];
|
|
261
|
-
}
|
|
262
|
-
const repoDir = process.cwd();
|
|
263
|
-
const [lastDir] = repoDir.split("/").reverse();
|
|
264
|
-
try {
|
|
265
|
-
const playwrightConfig = (await tsxImport.require(pwFile, `${repoDir}/${lastDir}`)).default;
|
|
266
|
-
const projectConfig = playwrightConfig.projects;
|
|
267
|
-
return projectConfig.map((projectConfig) => projectConfig.name);
|
|
268
|
-
}
|
|
269
|
-
catch (err) {
|
|
270
|
-
console.error("Error getting project list from playwright config", err);
|
|
271
|
-
}
|
|
272
|
-
return [];
|
|
273
|
-
}
|
|
274
|
-
exports.getProjectsFromPlaywrightConfig = getProjectsFromPlaywrightConfig;
|
|
275
168
|
const filterArrayByGlobMatchersSet = (
|
|
276
169
|
// array that needs to be filtered
|
|
277
170
|
input,
|
|
@@ -286,10 +179,29 @@ globMatcherSets) => {
|
|
|
286
179
|
return filteredList;
|
|
287
180
|
};
|
|
288
181
|
exports.filterArrayByGlobMatchersSet = filterArrayByGlobMatchersSet;
|
|
182
|
+
async function labelTeardownProjects(projectNames, platform) {
|
|
183
|
+
const allProjects = await (0, config_1.getProjectsFromPlaywrightConfig)(platform);
|
|
184
|
+
return projectNames.map((projectName) => {
|
|
185
|
+
const setupForTeardown = allProjects.find((p) => p.teardown === projectName);
|
|
186
|
+
if (setupForTeardown) {
|
|
187
|
+
return {
|
|
188
|
+
isTeardown: true,
|
|
189
|
+
correspondingSetupProject: setupForTeardown.name,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
return {
|
|
194
|
+
isTeardown: false,
|
|
195
|
+
correspondingSetupProject: undefined,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
289
200
|
const generateProjectFilters = async ({ platform, filteringSets, }) => {
|
|
290
|
-
const
|
|
201
|
+
const allProjects = await (0, config_1.getProjectsFromPlaywrightConfig)(platform);
|
|
202
|
+
const allProjectNames = allProjects.map((project) => project.name);
|
|
291
203
|
const filters = filteringSets.map((matchingString) => matchingString.split(","));
|
|
292
|
-
const filteredProjects = (0, exports.filterArrayByGlobMatchersSet)(
|
|
204
|
+
const filteredProjects = (0, exports.filterArrayByGlobMatchersSet)(allProjectNames, filters);
|
|
293
205
|
if (filteredProjects.length === 0) {
|
|
294
206
|
throw new Error("No projects found in playwright config that matches the filtering criteria");
|
|
295
207
|
}
|
|
@@ -299,7 +211,6 @@ exports.generateProjectFilters = generateProjectFilters;
|
|
|
299
211
|
function buildRepoName(projectName) {
|
|
300
212
|
return `${projectName}-tests`;
|
|
301
213
|
}
|
|
302
|
-
exports.buildRepoName = buildRepoName;
|
|
303
214
|
const pickNameFromPackageJson = async () => {
|
|
304
215
|
const packageJSONPath = "package.json";
|
|
305
216
|
const packageJsonStr = await promises_1.default.readFile(packageJSONPath, "utf-8");
|
|
@@ -314,7 +225,7 @@ const downloadBuild = async (buildUrl) => {
|
|
|
314
225
|
const buildDownloadScript = packageJSONData.scripts["download"];
|
|
315
226
|
if (buildDownloadScript && buildUrl) {
|
|
316
227
|
console.log(`Downloading build from ${buildUrl}`);
|
|
317
|
-
await
|
|
228
|
+
await (0, cmd_1.spawnCmd)(`npm`, ["run", "download", buildUrl], {
|
|
318
229
|
env: { ...Object(process.env) },
|
|
319
230
|
});
|
|
320
231
|
}
|
|
@@ -459,4 +370,3 @@ function getTypescriptTestBlock({ scenarioName, suites, content, }) {
|
|
|
459
370
|
sourceFile,
|
|
460
371
|
};
|
|
461
372
|
}
|
|
462
|
-
exports.getTypescriptTestBlock = getTypescriptTestBlock;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-run",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/async-retry": "^1.4.8",
|
|
27
|
-
"@types/node": "^22.5.5"
|
|
27
|
+
"@types/node": "^22.5.5",
|
|
28
|
+
"memfs": "^4.17.1"
|
|
28
29
|
},
|
|
29
30
|
"scripts": {
|
|
30
31
|
"dev": "tsc --build --watch",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/dashboard.ts","./src/index.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/types/index.ts","./src/utils/config-parser.ts","./src/utils/config.ts","./src/utils/index.ts"],"version":"5.8.3"}
|