@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 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
- Library to run playwright tests.
3
+ ## 1. Introduction
4
4
 
5
- This package helps to run all the dependent tests for a particular test case.
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
- ## Usage
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
- ```ts
10
- npx @empiricalrun/test-run -n "<test-name>" "<playwright-options>"
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
- The playwright options are passed as is to the playwright test command.
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
- ## Example
36
+ ### Example (running a test named "foo"):
16
37
 
17
- ```ts
38
+ ```bash
18
39
  npx @empiricalrun/test-run -n "foo" --retries 0
19
40
  ```
20
41
 
21
- This will run the test named "foo" in the `tests` directory.
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 support for suites
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 (process.env.TEST_RUN_ENVIRONMENT) {
58
- const { environment, build: latestBuild } = await (0, dashboard_1.fetchEnvironmentAndBuild)(projectName, process.env.TEST_RUN_ENVIRONMENT);
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
- name: options.name,
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({ name, filePath, dir, pwOptions, platform, suites, }: TestRunParameters): Promise<{
7
+ export declare function runTest({ tests, pwOptions, platform, }: TestRunParameters): Promise<{
8
8
  hasTestPassed: boolean;
9
9
  }>;
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -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,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,SAAS,EACT,QAAQ,EACR,MAAM,GACP,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CAaD"}
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({ name, filePath, dir, pwOptions, platform, suites, }) {
12
- if (name) {
13
- return await (0, run_specific_test_1.runSpecificTest)({
14
- name,
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 runSpecificTest({ name, filePath, dir, pwOptions, platform, suites, }: TestRunParameters): Promise<{
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":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAY5C;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EACpC,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,SAAS,EACT,QAAQ,EACR,MAAM,GACP,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CA2ED"}
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.runSpecificTest = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
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 runSpecificTest({ name, filePath, dir, pwOptions, platform, suites, }) {
15
- const files = await (0, utils_1.getAllFilePaths)(dir, {
16
- filePath,
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
- if (!matchingFilePath) {
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
- fs_extra_1.default.writeFileSync(matchingFilePath, currentFileContent);
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 ${matchingFilePath} ${pwOptions}`;
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.runSpecificTest = runSpecificTest;
100
+ exports.runSpecificTests = runSpecificTests;
@@ -1,10 +1,16 @@
1
- export type TestRunParameters = {
1
+ export type TestCase = {
2
2
  name: string;
3
- filePath?: string;
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,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,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"}
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,5 @@
1
+ import { Config } from "../types";
2
+ export declare function parseRcConfig(): Promise<Config>;
3
+ export declare function parseToken(token: string): Config;
4
+ export declare function buildConfigFromCliArgs(): void;
5
+ //# sourceMappingURL=config-parser.d.ts.map
@@ -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":"AAKA,OAAO,EAAE,IAAI,EAAW,UAAU,EAAc,MAAM,UAAU,CAAC;AAGjE,OAAO,EAEL,QAAQ,EAER,aAAa,EACd,MAAM,UAAU,CAAC;AAuBlB,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,MAAW,EAC1B,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,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,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;AAuBF;;;;;;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"}
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"}
@@ -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 fs_extra_1 = __importDefault(require("fs-extra"));
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 fs_extra_1.default.readdir(directoryPath);
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 fs_extra_1.default.lstat(filePath);
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 fs_extra_1.default.readFile(filePath, "utf-8");
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 fs_extra_1.default.readFile(filePath, "utf-8");
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 fs_extra_1.default.writeFile(filePath, updatedTestFileContent, "utf-8");
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 fs_extra_1.default.readFile(packageJSONPath, "utf-8");
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 fs_extra_1.default.readFile(packageJSONPath, "utf-8");
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 fs_extra_1.default.readFile(filePath, "utf-8");
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
- fs_extra_1.default.writeFileSync(filePath, content, "utf-8");
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.5.2",
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",