@empiricalrun/test-run 0.5.2 → 0.6.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 +12 -0
- package/README.md +189 -9
- package/dist/bin/index.js +25 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -7
- package/dist/run-specific-test.d.ts +1 -1
- package/dist/run-specific-test.d.ts.map +1 -1
- package/dist/run-specific-test.js +59 -46
- package/dist/types/index.d.ts +9 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/config-parser.d.ts +5 -0
- package/dist/utils/config-parser.d.ts.map +1 -0
- package/dist/utils/config-parser.js +44 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +20 -13
- package/package.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @empiricalrun/test-run
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 5fbc669: feat: support for token and run config file
|
|
8
|
+
|
|
9
|
+
## 0.5.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- b9f53be: fix: logs for other signals to catch github actions behavior
|
|
14
|
+
|
|
3
15
|
## 0.5.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,21 +1,201 @@
|
|
|
1
1
|
# test-run
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 1. Introduction
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**@empiricalrun/test-run** is a CLI tool (and library) designed to facilitate running Playwright (or Appwright) tests in a project. It allows you to:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- Run all tests or a specific test.
|
|
8
|
+
- Filter tests by name, file, or suites.
|
|
9
|
+
- Filter Playwright projects to run.
|
|
10
|
+
- Skip teardown test blocks.
|
|
11
|
+
- Integrate with an external dashboard for environment and build management.
|
|
12
|
+
- Forward additional arguments directly to the underlying Playwright/Appwright test runner.
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 2. Installation
|
|
17
|
+
|
|
18
|
+
Install from npm (usually as part of an Empirical-run monorepo, but can be done standalone):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -D @empiricalrun/test-run
|
|
11
22
|
```
|
|
12
23
|
|
|
13
|
-
|
|
24
|
+
You can also use the CLI directly with `npx`.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 3. Basic Usage
|
|
29
|
+
|
|
30
|
+
The CLI entry point is defined in `package.json` under `"bin"`. You can invoke it using:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx @empiricalrun/test-run [flags] [Playwright/test arguments]
|
|
34
|
+
```
|
|
14
35
|
|
|
15
|
-
|
|
36
|
+
### Example (running a test named "foo"):
|
|
16
37
|
|
|
17
|
-
```
|
|
38
|
+
```bash
|
|
18
39
|
npx @empiricalrun/test-run -n "foo" --retries 0
|
|
19
40
|
```
|
|
20
41
|
|
|
21
|
-
|
|
42
|
+
Here, `--retries 0` (and any unrecognized options) get passed on to the underlying Playwright command.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 4. CLI Flags
|
|
47
|
+
|
|
48
|
+
Below are the main CLI options implemented in `src/bin/index.ts`:
|
|
49
|
+
| Flag/Option | Description |
|
|
50
|
+
|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
|
51
|
+
| `-n, --name <test-name>` | The scenario name (title) of the specific test to run. If provided, only that particular test/scenario is run instead of all tests. |
|
|
52
|
+
| `-d, --dir <test-dir>` | Directory containing tests. Defaults to `tests`. |
|
|
53
|
+
| `-f, --file <test-file-path>` | Specific test file path. If provided along with `--name`, it targets that file for the named test. |
|
|
54
|
+
| `-p, --project <project-name...>` | One or more (space-delimited) project names/patterns used to filter the test run. Examples: `--project web` or `--project ios desktop`. |
|
|
55
|
+
| `-s, --suites <suites>` | A comma-separated list of suite or describe-block names. Example: `--suites "suiteA,suiteB"`. |
|
|
56
|
+
| `--skip-teardown` | Skips teardown tests by marking them as “skipped.” Reverts changes when the process exits. |
|
|
57
|
+
| `--token <token>` | A base64-encoded token that, when decoded, can define test configuration (such as a test list). |
|
|
58
|
+
| `--forbid-only` | Fails the run if there are any `.only` blocks in the code. |
|
|
59
|
+
|
|
60
|
+
Other unrecognized flags on the command line will be appended as **Playwright arguments**.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 5. Environment Variables
|
|
65
|
+
|
|
66
|
+
The following environment variables can further customize behavior:
|
|
67
|
+
|
|
68
|
+
- **`PROJECT_NAME`**
|
|
69
|
+
Overrides project name detection from `package.json`.
|
|
70
|
+
|
|
71
|
+
- **`TEST_RUN_ENVIRONMENT`**
|
|
72
|
+
This helps fetch playwright projects, environment details and potential build artifacts before tests start.
|
|
73
|
+
|
|
74
|
+
- **`BUILD_URL`**
|
|
75
|
+
Overrides the build URL for downloading any build artifacts.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 6. Running group of tests vs. All Tests
|
|
80
|
+
|
|
81
|
+
- **Group Test**:
|
|
82
|
+
Use `--name` to identify one tests with the specfied name, optionally adding `--file` or `--suites` if needed.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx @empiricalrun/test-run --name "my test" --file tests/example.spec.ts
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- **All Tests**:
|
|
89
|
+
Omit `--name`. This runs all tests.
|
|
90
|
+
```bash
|
|
91
|
+
npx @empiricalrun/test-run --reporter=list
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 7. Skipping Teardown Tests
|
|
97
|
+
|
|
98
|
+
If you pass `--skip-teardown`, the CLI will:
|
|
99
|
+
|
|
100
|
+
1. Temporarily annotate `*.teardown.ts` files so that they are skipped (for example, converting `teardown` calls to `teardown.skip`).
|
|
101
|
+
2. After the run, it automatically reverts the code changes, triggered by process exit signals.
|
|
102
|
+
|
|
103
|
+
This is useful for omitting teardown steps during certain runs or local development.
|
|
104
|
+
|
|
105
|
+
---
|
|
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
|
+
## 9. Environment & Build (Optional)
|
|
128
|
+
|
|
129
|
+
If `TEST_RUN_ENVIRONMENT` is defined:
|
|
130
|
+
|
|
131
|
+
1. The CLI fetches environment details (and optionally a build artifact) via the remote “dashboard” (see `dashboard.ts`).
|
|
132
|
+
2. If no custom `BUILD_URL` is set, it uses the environment’s latest build.
|
|
133
|
+
3. It runs an npm script named `download` to grab the build.
|
|
134
|
+
|
|
135
|
+
This flow makes sure tests run against the relevant environment or a fresh build artifact.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 10. Examples
|
|
140
|
+
|
|
141
|
+
1. **Run a single named test**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npx @empiricalrun/test-run -n "login test"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
2. **Use specific test file and name**
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx @empiricalrun/test-run -n "logout test" -f tests/logout.spec.ts
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
3. **Run multiple projects and skip teardown**
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npx @empiricalrun/test-run -n "mobile login" --project android --project ios --skip-teardown
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
4. **Run all tests with Playwright arguments**
|
|
160
|
+
```bash
|
|
161
|
+
npx @empiricalrun/test-run -- --worker=2 --reporter=line
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 11. Troubleshooting & Notes
|
|
167
|
+
|
|
168
|
+
- The CLI automatically appends unrecognized flags to the underlying `playwright test` (or `appwright test`) command.
|
|
169
|
+
- Errors like “No test block found” often mean the CLI did not locate your test name or file. Double-check `--name`, `--file`, etc.
|
|
170
|
+
- The teardown skip logic modifies files but reverts them on exit. If a process is forcibly killed, you may need to manually restore.
|
|
171
|
+
- If environment fetching or build downloading fails, confirm your environment slug and project name match those recognized by your dashboard.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
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
|
+
## 14. Conclusion
|
|
193
|
+
|
|
194
|
+
@test-run simplifies orchestrating Playwright tests, especially for:
|
|
195
|
+
|
|
196
|
+
- Filtering or focusing on specific test scenarios.
|
|
197
|
+
- Managing environment-based test runs.
|
|
198
|
+
- Skipping teardown blocks.
|
|
199
|
+
- Working with multiple or specialized Playwright projects.
|
|
200
|
+
|
|
201
|
+
Explore the source (particularly `src/bin/index.ts` and `src/utils`) for deeper technical insights and advanced customization.
|
package/dist/bin/index.js
CHANGED
|
@@ -6,14 +6,16 @@ const __1 = require("..");
|
|
|
6
6
|
const dashboard_1 = require("../dashboard");
|
|
7
7
|
const types_1 = require("../types");
|
|
8
8
|
const utils_1 = require("../utils");
|
|
9
|
+
const config_parser_1 = require("../utils/config-parser");
|
|
9
10
|
(async function main() {
|
|
10
|
-
// TODO: add
|
|
11
|
+
// TODO: add documentation of the test run
|
|
11
12
|
commander_1.program
|
|
12
13
|
.option("-n, --name <test-name>", "Name of the test to run")
|
|
13
14
|
.option("-d, --dir <test-dir>", "Path to the test directory")
|
|
14
15
|
.option("-f, --file <test-file-path>", "Path to the test file")
|
|
15
16
|
.option("-p, --project <project-name...>", "Test projects to run")
|
|
16
17
|
.option("-s, --suites <suites>", "suites under which the test is defined")
|
|
18
|
+
.option("--payload <payload>", "Payload to run tests")
|
|
17
19
|
.option("--skip-teardown", "This options skips running teardown tests")
|
|
18
20
|
.option("--forbid-only", `This options forbids the use of ".only" in the test files`)
|
|
19
21
|
.allowUnknownOption();
|
|
@@ -37,11 +39,13 @@ const utils_1 = require("../utils");
|
|
|
37
39
|
"--project",
|
|
38
40
|
"-s",
|
|
39
41
|
"--suites",
|
|
42
|
+
"--payload",
|
|
40
43
|
options.skipTeardown,
|
|
41
44
|
options.name,
|
|
42
45
|
options.dir,
|
|
43
46
|
options.file,
|
|
44
47
|
options.suites,
|
|
48
|
+
options.payload,
|
|
45
49
|
...options.project, // an array of comma separated project names/pattern matching globs *,premium-*,super-premium-*,safari
|
|
46
50
|
];
|
|
47
51
|
const pwOptions = process.argv
|
|
@@ -51,11 +55,28 @@ const utils_1 = require("../utils");
|
|
|
51
55
|
if (!projectName) {
|
|
52
56
|
throw new Error("Project name is required");
|
|
53
57
|
}
|
|
58
|
+
const directory = options.dir || "tests";
|
|
59
|
+
const suites = options.suites && options.suites.trim() !== ""
|
|
60
|
+
? options.suites?.split(",")
|
|
61
|
+
: undefined;
|
|
62
|
+
let tests = (await (0, config_parser_1.parseRcConfig)())?.tests ||
|
|
63
|
+
(0, config_parser_1.parseToken)(options.payload)?.tests ||
|
|
64
|
+
(options.name
|
|
65
|
+
? [
|
|
66
|
+
{
|
|
67
|
+
name: options.name,
|
|
68
|
+
dir: directory,
|
|
69
|
+
filePath: options.file,
|
|
70
|
+
suites,
|
|
71
|
+
},
|
|
72
|
+
]
|
|
73
|
+
: undefined);
|
|
74
|
+
const environmentSlug = process.env.TEST_RUN_ENVIRONMENT || "";
|
|
54
75
|
let environmentSpecificProjects = [];
|
|
55
76
|
let platform = types_1.Platform.WEB;
|
|
56
77
|
try {
|
|
57
|
-
if (
|
|
58
|
-
const { environment, build: latestBuild } = await (0, dashboard_1.fetchEnvironmentAndBuild)(projectName,
|
|
78
|
+
if (environmentSlug) {
|
|
79
|
+
const { environment, build: latestBuild } = await (0, dashboard_1.fetchEnvironmentAndBuild)(projectName, environmentSlug);
|
|
59
80
|
platform = environment.platform;
|
|
60
81
|
environmentSpecificProjects = environment.playwright_projects;
|
|
61
82
|
if (!process.env.BUILD_URL) {
|
|
@@ -69,20 +90,13 @@ const utils_1 = require("../utils");
|
|
|
69
90
|
filteringSets: [...options.project, ...environmentSpecificProjects],
|
|
70
91
|
});
|
|
71
92
|
pwOptions.push(...projectFilters);
|
|
72
|
-
const directory = options.dir || "tests";
|
|
73
93
|
if (options.skipTeardown) {
|
|
74
94
|
await (0, utils_1.handleTeardownSkipFlag)(directory);
|
|
75
95
|
}
|
|
76
|
-
const suites = options.suites && options.suites.trim() !== ""
|
|
77
|
-
? options.suites?.split(",")
|
|
78
|
-
: undefined;
|
|
79
96
|
const { hasTestPassed } = await (0, __1.runTest)({
|
|
80
|
-
|
|
81
|
-
filePath: options.file,
|
|
82
|
-
dir: directory,
|
|
97
|
+
tests,
|
|
83
98
|
pwOptions: pwOptions.join(" "),
|
|
84
99
|
platform,
|
|
85
|
-
suites,
|
|
86
100
|
});
|
|
87
101
|
if (!hasTestPassed) {
|
|
88
102
|
process.exit(1);
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { TestRunParameters } from "./types";
|
|
|
4
4
|
* @export
|
|
5
5
|
* @param {TestRunParameters} { name, dir, pwOptions }
|
|
6
6
|
*/
|
|
7
|
-
export declare function runTest({
|
|
7
|
+
export declare function runTest({ tests, pwOptions, platform, }: TestRunParameters): Promise<{
|
|
8
8
|
hasTestPassed: boolean;
|
|
9
9
|
}>;
|
|
10
10
|
//# 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":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,EAC5B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,EAC5B,KAAK,EACL,SAAS,EACT,QAAQ,GACT,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CAUD"}
|
package/dist/index.js
CHANGED
|
@@ -8,15 +8,12 @@ const run_specific_test_1 = require("./run-specific-test");
|
|
|
8
8
|
* @export
|
|
9
9
|
* @param {TestRunParameters} { name, dir, pwOptions }
|
|
10
10
|
*/
|
|
11
|
-
async function runTest({
|
|
12
|
-
if (
|
|
13
|
-
return await (0, run_specific_test_1.
|
|
14
|
-
|
|
15
|
-
dir,
|
|
16
|
-
filePath,
|
|
11
|
+
async function runTest({ tests, pwOptions, platform, }) {
|
|
12
|
+
if (tests && tests.length > 0) {
|
|
13
|
+
return await (0, run_specific_test_1.runSpecificTests)({
|
|
14
|
+
tests,
|
|
17
15
|
pwOptions,
|
|
18
16
|
platform,
|
|
19
|
-
suites,
|
|
20
17
|
});
|
|
21
18
|
}
|
|
22
19
|
return await (0, run_all_tests_1.runAllTests)({ pwOptions, platform });
|
|
@@ -4,7 +4,7 @@ import { TestRunParameters } from "./types";
|
|
|
4
4
|
* @export
|
|
5
5
|
* @param {TestRunParameters} { name, dir, pwOptions }
|
|
6
6
|
*/
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function runSpecificTests({ tests, pwOptions, platform, }: TestRunParameters): Promise<{
|
|
8
8
|
hasTestPassed: boolean;
|
|
9
9
|
}>;
|
|
10
10
|
//# sourceMappingURL=run-specific-test.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-specific-test.d.ts","sourceRoot":"","sources":["../src/run-specific-test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-specific-test.d.ts","sourceRoot":"","sources":["../src/run-specific-test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAY5C;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,KAAU,EACV,SAAS,EACT,QAAQ,GACT,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CA4FD"}
|
|
@@ -3,75 +3,88 @@ 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
|
-
const
|
|
6
|
+
exports.runSpecificTests = void 0;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
9
|
const utils_1 = require("./utils");
|
|
9
10
|
/**
|
|
10
11
|
*
|
|
11
12
|
* @export
|
|
12
13
|
* @param {TestRunParameters} { name, dir, pwOptions }
|
|
13
14
|
*/
|
|
14
|
-
async function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
});
|
|
18
|
-
let matchingFilePath = "";
|
|
19
|
-
// find the first file that contains the test block
|
|
20
|
-
// TODO: add suites support
|
|
21
|
-
for (const file of files) {
|
|
22
|
-
const match = await (0, utils_1.hasTestBlock)({
|
|
23
|
-
filePath: file,
|
|
24
|
-
scenarioName: name,
|
|
25
|
-
suites,
|
|
26
|
-
});
|
|
27
|
-
if (match) {
|
|
28
|
-
matchingFilePath = file;
|
|
29
|
-
break;
|
|
30
|
-
}
|
|
15
|
+
async function runSpecificTests({ tests = [], pwOptions, platform, }) {
|
|
16
|
+
if (!tests || tests.length === 0) {
|
|
17
|
+
throw new Error("No tests found");
|
|
31
18
|
}
|
|
32
|
-
|
|
33
|
-
const message = `No test block found for the given test name: ${name}`;
|
|
34
|
-
throw Error(message);
|
|
35
|
-
}
|
|
36
|
-
const { testCaseNode, sourceFile } = await (0, utils_1.getTestCaseNode)({
|
|
37
|
-
filePath: matchingFilePath,
|
|
38
|
-
scenarioName: name,
|
|
39
|
-
suites,
|
|
40
|
-
});
|
|
41
|
-
const parentDescribe = (0, utils_1.findFirstSerialDescribeBlock)(testCaseNode);
|
|
42
|
-
const isFileMarkedSerial = await (0, utils_1.hasTopLevelDescribeConfigureWithSerialMode)(matchingFilePath);
|
|
43
|
-
console.log("Identified test block:", !!testCaseNode);
|
|
44
|
-
console.log("Is parent describe block marked serial:", !!parentDescribe);
|
|
45
|
-
console.log("Is file marked serial:", isFileMarkedSerial);
|
|
46
|
-
const currentFileContent = await fs_extra_1.default.readFile(matchingFilePath, "utf-8");
|
|
19
|
+
const touchedFiles = {};
|
|
47
20
|
// revert the changes made to the file to mark tests as only
|
|
48
21
|
// these needs to handle by listening to process exit/kill events
|
|
49
22
|
const revertFileContent = () => {
|
|
50
23
|
try {
|
|
51
|
-
|
|
24
|
+
Object.keys(touchedFiles).forEach((filePath) => {
|
|
25
|
+
(0, fs_1.writeFileSync)(filePath, touchedFiles[filePath], "utf-8");
|
|
26
|
+
});
|
|
52
27
|
}
|
|
53
28
|
catch (error) {
|
|
54
29
|
console.error("Error while cleaning up test file:", error);
|
|
55
30
|
}
|
|
56
31
|
};
|
|
32
|
+
for (const testCase of tests) {
|
|
33
|
+
const files = await (0, utils_1.getAllFilePaths)(testCase.dir, {
|
|
34
|
+
filePath: testCase.filePath,
|
|
35
|
+
});
|
|
36
|
+
let matchingFilePath = "";
|
|
37
|
+
for (const file of files) {
|
|
38
|
+
const match = await (0, utils_1.hasTestBlock)({
|
|
39
|
+
filePath: file,
|
|
40
|
+
scenarioName: testCase.name,
|
|
41
|
+
suites: testCase.suites,
|
|
42
|
+
});
|
|
43
|
+
if (match) {
|
|
44
|
+
matchingFilePath = file;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (!matchingFilePath) {
|
|
49
|
+
const message = `No test block found for the given test name: ${testCase.name} in file ${testCase.filePath} with suites: ${testCase.suites}`;
|
|
50
|
+
revertFileContent();
|
|
51
|
+
throw Error(message);
|
|
52
|
+
}
|
|
53
|
+
const { testCaseNode, sourceFile } = await (0, utils_1.getTestCaseNode)({
|
|
54
|
+
filePath: matchingFilePath,
|
|
55
|
+
scenarioName: testCase.name,
|
|
56
|
+
suites: testCase.suites,
|
|
57
|
+
});
|
|
58
|
+
const parentDescribe = (0, utils_1.findFirstSerialDescribeBlock)(testCaseNode);
|
|
59
|
+
const isFileMarkedSerial = await (0, utils_1.hasTopLevelDescribeConfigureWithSerialMode)(matchingFilePath);
|
|
60
|
+
console.log("Identified test block:", !!testCaseNode);
|
|
61
|
+
console.log("Is parent describe block marked serial:", !!parentDescribe);
|
|
62
|
+
console.log("Is file marked serial:", isFileMarkedSerial);
|
|
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
|
+
if (!isFileMarkedSerial && testCaseNode) {
|
|
70
|
+
await (0, utils_1.markTestAsOnly)({
|
|
71
|
+
sourceFile,
|
|
72
|
+
parentDescribeNode: parentDescribe,
|
|
73
|
+
testCaseNode: testCaseNode,
|
|
74
|
+
filePath: matchingFilePath,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// TODO: check if this works for multiple listeners
|
|
57
79
|
process.on("beforeExit", revertFileContent);
|
|
58
80
|
process.on("exit", revertFileContent);
|
|
59
81
|
process.on("SIGINT", revertFileContent);
|
|
60
82
|
process.on("SIGTERM", revertFileContent);
|
|
61
|
-
// if the file is not marked serial, we need to mark the test or describe block as only
|
|
62
|
-
if (!isFileMarkedSerial && testCaseNode) {
|
|
63
|
-
await (0, utils_1.markTestAsOnly)({
|
|
64
|
-
sourceFile,
|
|
65
|
-
parentDescribeNode: parentDescribe,
|
|
66
|
-
testCaseNode: testCaseNode,
|
|
67
|
-
filePath: matchingFilePath,
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
83
|
let hasTestPassed = true;
|
|
71
84
|
try {
|
|
72
85
|
const testRunner = (0, utils_1.getTestRunner)(platform);
|
|
73
86
|
const env = Object({ ...process.env });
|
|
74
|
-
const testRunCmd = `npx ${testRunner} test ${
|
|
87
|
+
const testRunCmd = `npx ${testRunner} test ${Object.keys(touchedFiles).join(" ")} ${pwOptions}`;
|
|
75
88
|
console.log(`${testRunner} test command:`, testRunCmd);
|
|
76
89
|
await (0, utils_1.cmd)(testRunCmd.split(" "), {
|
|
77
90
|
env,
|
|
@@ -84,4 +97,4 @@ async function runSpecificTest({ name, filePath, dir, pwOptions, platform, suite
|
|
|
84
97
|
hasTestPassed,
|
|
85
98
|
};
|
|
86
99
|
}
|
|
87
|
-
exports.
|
|
100
|
+
exports.runSpecificTests = runSpecificTests;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type TestCase = {
|
|
2
2
|
name: string;
|
|
3
|
-
filePath
|
|
3
|
+
filePath: string;
|
|
4
4
|
dir?: string;
|
|
5
|
+
suites?: string[];
|
|
6
|
+
};
|
|
7
|
+
export type Config = {
|
|
8
|
+
tests: TestCase[];
|
|
9
|
+
} | undefined;
|
|
10
|
+
export type TestRunParameters = {
|
|
11
|
+
tests?: TestCase[];
|
|
5
12
|
pwOptions?: string;
|
|
6
13
|
platform: Platform;
|
|
7
|
-
suites?: string[];
|
|
8
14
|
};
|
|
9
15
|
export type Environment = {
|
|
10
16
|
id: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,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,GACd;IACE,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,GACD,SAAS,CAAC;AAEd,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;CACpB,CAAC;AAEF,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../../src/utils/config-parser.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAerD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAchD;AAED,wBAAgB,sBAAsB,SAAK"}
|
|
@@ -0,0 +1,44 @@
|
|
|
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.buildConfigFromCliArgs = exports.parseToken = exports.parseRcConfig = void 0;
|
|
7
|
+
const fs_1 = require("fs");
|
|
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;
|
|
26
|
+
function parseToken(token) {
|
|
27
|
+
if (!token) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const str = atob(token);
|
|
32
|
+
const decodedStr = decodeURIComponent(str);
|
|
33
|
+
const json = JSON.parse(decodedStr);
|
|
34
|
+
// TODO: validate the json
|
|
35
|
+
return json;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error("Error parsing token:", error);
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
exports.parseToken = parseToken;
|
|
43
|
+
function buildConfigFromCliArgs() { }
|
|
44
|
+
exports.buildConfigFromCliArgs = buildConfigFromCliArgs;
|
|
@@ -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":"AAMA,OAAO,EAAE,IAAI,EAAW,UAAU,EAAc,MAAM,UAAU,CAAC;AAGjE,OAAO,EAEL,QAAQ,EAER,aAAa,EACd,MAAM,UAAU,CAAC;AA6BlB,wBAAgB,GAAG,CACjB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,CAAC,CAiCjB;AAED;;;;;GAKG;AACH,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,eAC/B,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,4BAA4B,CAC1C,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,IAAI,GAAG,SAAS,CA4BlB;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,wBAAsB,+BAA+B,CAAC,QAAQ,EAAE,QAAQ,gBAevE;AAED,eAAO,MAAM,4BAA4B,UAEhC,MAAM,EAAE,mBAGE,MAAM,EAAE,EAAE,KAC1B,MAAM,EAUR,CAAC;AAEF,eAAO,MAAM,sBAAsB;cAIvB,QAAQ;mBACH,MAAM,EAAE;MACrB,QAAQ,MAAM,EAAE,CAmBnB,CAAC;AAEF,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,eAAO,MAAM,uBAAuB,QAAa,QAC/C,MAAM,GAAG,SAAS,CAMnB,CAAC;AAEF,eAAO,MAAM,aAAa,aAAoB,MAAM,KAAG,QAAQ,IAAI,CAWlE,CAAC;AAEF,eAAO,MAAM,aAAa,aAAc,QAAQ,KAAG,aAIlD,CAAC;AA4DF,eAAO,MAAM,sBAAsB,cAAqB,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
|
@@ -5,7 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getTypescriptTestBlock = exports.handleTeardownSkipFlag = exports.getTestRunner = exports.downloadBuild = exports.pickNameFromPackageJson = exports.buildRepoName = exports.generateProjectFilters = exports.filterArrayByGlobMatchersSet = exports.getProjectsFromPlaywrightConfig = exports.markTestAsOnly = exports.hasTopLevelDescribeConfigureWithSerialMode = exports.findFirstSerialDescribeBlock = exports.hasTestBlock = exports.getTestCaseNode = exports.getTestModuleAliasFromSourceFile = exports.getAllFilePaths = exports.cmd = void 0;
|
|
7
7
|
const child_process_1 = require("child_process");
|
|
8
|
-
const
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
10
|
const lodash_isequal_1 = __importDefault(require("lodash.isequal"));
|
|
10
11
|
const minimatch_1 = require("minimatch");
|
|
11
12
|
const path_1 = __importDefault(require("path"));
|
|
@@ -29,6 +30,10 @@ function setupProcessSignalHandlers(proc) {
|
|
|
29
30
|
};
|
|
30
31
|
process.once("SIGINT", async () => await handleSignal("SIGINT"));
|
|
31
32
|
process.once("SIGTERM", async () => await handleSignal("SIGTERM"));
|
|
33
|
+
// Handler for other signals to catch GitHub Actions behaviors
|
|
34
|
+
["SIGABRT", "SIGHUP", "SIGQUIT"].forEach((signal) => {
|
|
35
|
+
process.once(signal, () => console.log(`Received ${signal}, which is a no-op`));
|
|
36
|
+
});
|
|
32
37
|
}
|
|
33
38
|
function cmd(command, options) {
|
|
34
39
|
let errorLogs = [];
|
|
@@ -70,14 +75,14 @@ exports.cmd = cmd;
|
|
|
70
75
|
* @param {string} [directoryPath=""]
|
|
71
76
|
* @return {*} {Promise<string[]>}
|
|
72
77
|
*/
|
|
73
|
-
async function getAllFilePaths(directoryPath = "", filters = {}) {
|
|
78
|
+
async function getAllFilePaths(directoryPath = "tests", filters = {}) {
|
|
74
79
|
let filePaths = [];
|
|
75
80
|
try {
|
|
76
|
-
const files = await
|
|
81
|
+
const files = await promises_1.default.readdir(directoryPath);
|
|
77
82
|
let allFilePaths = [];
|
|
78
83
|
for (const file of files) {
|
|
79
84
|
const filePath = path_1.default.join(directoryPath, file);
|
|
80
|
-
const stat = await
|
|
85
|
+
const stat = await promises_1.default.lstat(filePath);
|
|
81
86
|
if (stat.isDirectory()) {
|
|
82
87
|
// If it's a directory, recursively get file paths from the directory
|
|
83
88
|
const nestedFiles = await getAllFilePaths(filePath, filters);
|
|
@@ -116,7 +121,7 @@ const getTestModuleAliasFromSourceFile = (sourceFile) => {
|
|
|
116
121
|
};
|
|
117
122
|
exports.getTestModuleAliasFromSourceFile = getTestModuleAliasFromSourceFile;
|
|
118
123
|
async function getTestCaseNode({ filePath, scenarioName, suites, }) {
|
|
119
|
-
const content = await
|
|
124
|
+
const content = await promises_1.default.readFile(filePath, "utf-8");
|
|
120
125
|
const { testNode, sourceFile } = getTypescriptTestBlock({
|
|
121
126
|
scenarioName,
|
|
122
127
|
content,
|
|
@@ -140,7 +145,8 @@ function findFirstSerialDescribeBlock(node) {
|
|
|
140
145
|
while (currentNode) {
|
|
141
146
|
const parentDescribe = currentNode.getFirstAncestorByKind(ts_morph_1.SyntaxKind.CallExpression);
|
|
142
147
|
if (parentDescribe) {
|
|
143
|
-
const isDescribe = parentDescribe.getFirstChild()?.getText() === "test.describe"
|
|
148
|
+
const isDescribe = parentDescribe.getFirstChild()?.getText() === "test.describe" ||
|
|
149
|
+
parentDescribe.getFirstChild()?.getText() === "test.describe.only";
|
|
144
150
|
if (isDescribe) {
|
|
145
151
|
const configureCall = parentDescribe
|
|
146
152
|
.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression)
|
|
@@ -160,7 +166,7 @@ function findFirstSerialDescribeBlock(node) {
|
|
|
160
166
|
exports.findFirstSerialDescribeBlock = findFirstSerialDescribeBlock;
|
|
161
167
|
async function hasTopLevelDescribeConfigureWithSerialMode(filePath) {
|
|
162
168
|
const project = new ts_morph_1.Project();
|
|
163
|
-
const content = await
|
|
169
|
+
const content = await promises_1.default.readFile(filePath, "utf-8");
|
|
164
170
|
const sourceFile = project.createSourceFile("test.ts", content);
|
|
165
171
|
const statements = sourceFile.getStatements();
|
|
166
172
|
for (const statement of statements) {
|
|
@@ -202,7 +208,7 @@ async function markTestAsOnly({ sourceFile, parentDescribeNode, testCaseNode, fi
|
|
|
202
208
|
parentDescribeNode.replaceWithText(describeMarkedAsOnly);
|
|
203
209
|
updatedTestFileContent = sourceFile.getFullText();
|
|
204
210
|
}
|
|
205
|
-
await
|
|
211
|
+
await promises_1.default.writeFile(filePath, updatedTestFileContent, "utf-8");
|
|
206
212
|
}
|
|
207
213
|
exports.markTestAsOnly = markTestAsOnly;
|
|
208
214
|
async function getProjectsFromPlaywrightConfig(platform) {
|
|
@@ -249,14 +255,14 @@ function buildRepoName(projectName) {
|
|
|
249
255
|
exports.buildRepoName = buildRepoName;
|
|
250
256
|
const pickNameFromPackageJson = async () => {
|
|
251
257
|
const packageJSONPath = "package.json";
|
|
252
|
-
const packageJsonStr = await
|
|
258
|
+
const packageJsonStr = await promises_1.default.readFile(packageJSONPath, "utf-8");
|
|
253
259
|
const packageJSONData = JSON.parse(packageJsonStr);
|
|
254
260
|
return packageJSONData.name && packageJSONData.name.replace("-tests", "");
|
|
255
261
|
};
|
|
256
262
|
exports.pickNameFromPackageJson = pickNameFromPackageJson;
|
|
257
263
|
const downloadBuild = async (buildUrl) => {
|
|
258
264
|
const packageJSONPath = "package.json";
|
|
259
|
-
const packageJsonStr = await
|
|
265
|
+
const packageJsonStr = await promises_1.default.readFile(packageJSONPath, "utf-8");
|
|
260
266
|
const packageJSONData = JSON.parse(packageJsonStr);
|
|
261
267
|
const buildDownloadScript = packageJSONData.scripts["download"];
|
|
262
268
|
if (buildDownloadScript && buildUrl) {
|
|
@@ -307,14 +313,14 @@ class TeardownManager {
|
|
|
307
313
|
async skip() {
|
|
308
314
|
this.teardownFiles = await getAllTeardownFiles(this.directory);
|
|
309
315
|
this.teardownFileContents = await Promise.all(this.teardownFiles.map(async (filePath) => {
|
|
310
|
-
const content = await
|
|
316
|
+
const content = await promises_1.default.readFile(filePath, "utf-8");
|
|
311
317
|
return { filePath, content };
|
|
312
318
|
}));
|
|
313
319
|
await Promise.all(this.teardownFiles.map(async (filePath) => await skipTeardownFile(filePath)));
|
|
314
320
|
}
|
|
315
321
|
unskip() {
|
|
316
322
|
this.teardownFileContents.forEach(({ filePath, content }) => {
|
|
317
|
-
|
|
323
|
+
(0, fs_1.writeFileSync)(filePath, content, "utf-8");
|
|
318
324
|
});
|
|
319
325
|
}
|
|
320
326
|
}
|
|
@@ -343,7 +349,8 @@ const getParentDescribeNames = (node) => {
|
|
|
343
349
|
while (current) {
|
|
344
350
|
if (ts_morph_1.Node.isCallExpression(current)) {
|
|
345
351
|
const expr = current.getExpression();
|
|
346
|
-
if (expr.getText() === "test.describe"
|
|
352
|
+
if (expr.getText() === "test.describe" ||
|
|
353
|
+
expr.getText() === "test.describe.only") {
|
|
347
354
|
const describeBlockArguments = current.getArguments();
|
|
348
355
|
if (describeBlockArguments.length > 0) {
|
|
349
356
|
const describeBlockName = describeBlockArguments[0];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-run",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"@types/lodash.isequal": "^4.5.8",
|
|
19
19
|
"async-retry": "^1.3.3",
|
|
20
20
|
"commander": "^12.1.0",
|
|
21
|
-
"fs-extra": "^11.2.0",
|
|
22
21
|
"lodash.isequal": "^4.5.0",
|
|
23
22
|
"minimatch": "^10.0.1",
|
|
24
23
|
"ts-morph": "^23.0.0",
|