@empiricalrun/test-run 0.9.2 → 0.9.4
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 +13 -0
- package/dist/bin/index.js +5 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -7
- package/dist/lib/cmd.d.ts +6 -6
- package/dist/lib/cmd.d.ts.map +1 -1
- package/dist/lib/cmd.js +9 -7
- package/dist/lib/run-specific-test.d.ts +2 -1
- package/dist/lib/run-specific-test.d.ts.map +1 -1
- package/dist/lib/run-specific-test.js +12 -4
- package/dist/utils/config.d.ts +1 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +25 -29
- package/dist/utils/index.d.ts +11 -7
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +27 -20
- package/package.json +2 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @empiricalrun/test-run
|
|
2
2
|
|
|
3
|
+
## 0.9.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f926e40: feat: consume repoPath in test run tool
|
|
8
|
+
|
|
9
|
+
## 0.9.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 333b99f: fix: test run tool should report correct status
|
|
14
|
+
- 3739bc0: fix: replace tsx with an execSync call to fetch playwright projects
|
|
15
|
+
|
|
3
16
|
## 0.9.2
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/dist/bin/index.js
CHANGED
|
@@ -16,6 +16,7 @@ const config_parser_1 = require("../utils/config-parser");
|
|
|
16
16
|
dotenv_1.default.config({
|
|
17
17
|
path: [".env.local", ".env"],
|
|
18
18
|
});
|
|
19
|
+
const repoDir = process.cwd();
|
|
19
20
|
(async function main() {
|
|
20
21
|
commander_1.program
|
|
21
22
|
.option("-n, --name <test-name>", "Name of the test to run")
|
|
@@ -95,9 +96,10 @@ dotenv_1.default.config({
|
|
|
95
96
|
const projectFilters = await (0, utils_1.generateProjectFilters)({
|
|
96
97
|
platform,
|
|
97
98
|
filteringSets: [...options.project, ...environmentSpecificProjects],
|
|
99
|
+
repoDir,
|
|
98
100
|
});
|
|
99
101
|
if (options.skipTeardown) {
|
|
100
|
-
await (0, utils_1.handleTeardownSkipFlag)(directory);
|
|
102
|
+
await (0, utils_1.handleTeardownSkipFlag)(directory, repoDir);
|
|
101
103
|
}
|
|
102
104
|
const hasTestsFilter = tests && tests.length > 0;
|
|
103
105
|
let commandToRun;
|
|
@@ -107,6 +109,7 @@ dotenv_1.default.config({
|
|
|
107
109
|
projects: projectFilters,
|
|
108
110
|
passthroughArgs: pwOptions.join(" "),
|
|
109
111
|
platform,
|
|
112
|
+
repoDir,
|
|
110
113
|
});
|
|
111
114
|
}
|
|
112
115
|
else {
|
|
@@ -116,7 +119,7 @@ dotenv_1.default.config({
|
|
|
116
119
|
platform,
|
|
117
120
|
});
|
|
118
121
|
}
|
|
119
|
-
const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun);
|
|
122
|
+
const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun, repoDir);
|
|
120
123
|
if (!hasTestPassed) {
|
|
121
124
|
process.exit(1);
|
|
122
125
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,12 +2,13 @@ import { spawnCmd } from "./lib/cmd";
|
|
|
2
2
|
import { runSpecificTestsCmd } from "./lib/run-specific-test";
|
|
3
3
|
import { TestCase } from "./types";
|
|
4
4
|
export { runSpecificTestsCmd, spawnCmd };
|
|
5
|
-
export declare function runSingleTest({ testName, suites, fileName, projects, envOverrides, }: {
|
|
5
|
+
export declare function runSingleTest({ testName, suites, fileName, projects, envOverrides, repoDir, }: {
|
|
6
6
|
testName: string;
|
|
7
7
|
suites: string[];
|
|
8
8
|
fileName: string;
|
|
9
9
|
projects: string[];
|
|
10
10
|
envOverrides?: Record<string, string>;
|
|
11
|
+
repoDir: string;
|
|
11
12
|
}): Promise<{
|
|
12
13
|
hasTestPassed: boolean;
|
|
13
14
|
summaryJson: any;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAY,QAAQ,EAAE,MAAM,SAAS,CAAC;AAO7C,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC;AAEzC,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAY,QAAQ,EAAE,MAAM,SAAS,CAAC;AAO7C,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC;AAEzC,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;;;GAiBA;AAED,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACvE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CACjD,CAAC,CAaD"}
|
package/dist/index.js
CHANGED
|
@@ -18,17 +18,17 @@ const utils_1 = require("./utils");
|
|
|
18
18
|
// For test-run package, the library entrypoint, we only support web platform
|
|
19
19
|
// The bin entrypoint has support for mobile also
|
|
20
20
|
const supportedPlatform = types_1.Platform.WEB;
|
|
21
|
-
async function runSingleTest({ testName, suites, fileName, projects, envOverrides, }) {
|
|
21
|
+
async function runSingleTest({ testName, suites, fileName, projects, envOverrides, repoDir, }) {
|
|
22
22
|
const testDir = "tests";
|
|
23
|
-
const filePath = path_1.default.relative(process.cwd(), fileName);
|
|
24
23
|
const commandToRun = await (0, run_specific_test_1.runSpecificTestsCmd)({
|
|
25
|
-
tests: [{ name: testName, dir: testDir, filePath, suites }],
|
|
24
|
+
tests: [{ name: testName, dir: testDir, filePath: fileName, suites }],
|
|
26
25
|
projects,
|
|
27
26
|
envOverrides,
|
|
28
27
|
platform: supportedPlatform,
|
|
28
|
+
repoDir,
|
|
29
29
|
});
|
|
30
|
-
const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun);
|
|
31
|
-
const jsonFilePath = path_1.default.join(
|
|
30
|
+
const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun, repoDir);
|
|
31
|
+
const jsonFilePath = path_1.default.join(repoDir, "playwright-report", `summary.json`);
|
|
32
32
|
const jsonFileContents = await promises_1.default.readFile(jsonFilePath, "utf8");
|
|
33
33
|
const summaryJson = JSON.parse(jsonFileContents);
|
|
34
34
|
return {
|
|
@@ -38,12 +38,12 @@ async function runSingleTest({ testName, suites, fileName, projects, envOverride
|
|
|
38
38
|
}
|
|
39
39
|
async function getAllPlaywrightProjects(repoDir) {
|
|
40
40
|
const testRunner = (0, utils_1.getTestRunner)(types_1.Platform.WEB);
|
|
41
|
-
const env = Object({ ...process.env });
|
|
42
41
|
const args = [testRunner, "test", "--list"];
|
|
43
42
|
const { output, code } = await (0, cmd_1.spawnCmd)("npx", args, {
|
|
44
|
-
env,
|
|
45
43
|
cwd: repoDir,
|
|
44
|
+
envOverrides: {},
|
|
46
45
|
captureOutput: true,
|
|
46
|
+
throwOnError: true,
|
|
47
47
|
});
|
|
48
48
|
if (!output) {
|
|
49
49
|
throw new Error(`Failed to run list command; exit code: ${code}`);
|
package/dist/lib/cmd.d.ts
CHANGED
|
@@ -3,14 +3,14 @@ export declare function getCommandFromString(command: string): {
|
|
|
3
3
|
command: string;
|
|
4
4
|
args: string[];
|
|
5
5
|
};
|
|
6
|
-
export declare function runTestsForCmd({ command, args, env }: CommandToRun): Promise<{
|
|
6
|
+
export declare function runTestsForCmd({ command, args, env }: CommandToRun, cwd: string): Promise<{
|
|
7
7
|
hasTestPassed: boolean;
|
|
8
8
|
}>;
|
|
9
|
-
export declare function spawnCmd(command: string, args: string[], options
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
captureOutput
|
|
13
|
-
throwOnError
|
|
9
|
+
export declare function spawnCmd(command: string, args: string[], options: {
|
|
10
|
+
cwd: string;
|
|
11
|
+
envOverrides: Record<string, string>;
|
|
12
|
+
captureOutput: boolean;
|
|
13
|
+
throwOnError: boolean;
|
|
14
14
|
}): Promise<{
|
|
15
15
|
code: number;
|
|
16
16
|
output?: string;
|
package/dist/lib/cmd.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../src/lib/cmd.ts"],"names":[],"mappings":"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,
|
|
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,CAClC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,YAAY,EACpC,GAAG,EAAE,MAAM;;GAeZ;AAED,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;IACP,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB,GACA,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6C5C"}
|
package/dist/lib/cmd.js
CHANGED
|
@@ -18,26 +18,28 @@ function getCommandFromString(command) {
|
|
|
18
18
|
}),
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
async function runTestsForCmd({ command, args, env }) {
|
|
21
|
+
async function runTestsForCmd({ command, args, env }, cwd) {
|
|
22
22
|
console.log(`Running cmd: ${command} with args: ${args}`);
|
|
23
23
|
let hasTestPassed = true;
|
|
24
24
|
try {
|
|
25
|
-
await spawnCmd(command, args, {
|
|
25
|
+
await spawnCmd(command, args, {
|
|
26
|
+
cwd,
|
|
27
|
+
envOverrides: env,
|
|
28
|
+
captureOutput: false,
|
|
29
|
+
throwOnError: true,
|
|
30
|
+
});
|
|
26
31
|
}
|
|
27
32
|
catch (e) {
|
|
28
33
|
hasTestPassed = false;
|
|
29
34
|
}
|
|
30
35
|
return { hasTestPassed };
|
|
31
36
|
}
|
|
32
|
-
async function spawnCmd(command, args, options
|
|
33
|
-
captureOutput: false,
|
|
34
|
-
throwOnError: true,
|
|
35
|
-
}) {
|
|
37
|
+
async function spawnCmd(command, args, options) {
|
|
36
38
|
let output = options.captureOutput ? "" : undefined;
|
|
37
39
|
let errorLogs = [];
|
|
38
40
|
return new Promise((resolveFunc, rejectFunc) => {
|
|
39
41
|
const p = (0, child_process_1.spawn)(command, args, {
|
|
40
|
-
env: { ...process.env, ...options.
|
|
42
|
+
env: { ...process.env, ...options.envOverrides },
|
|
41
43
|
cwd: options.cwd,
|
|
42
44
|
// Ensure child process receives signals
|
|
43
45
|
detached: false,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CommandToRun, Platform, TestCase } from "../types";
|
|
2
|
-
export declare function runSpecificTestsCmd({ tests, projects, passthroughArgs, platform, envOverrides, }: {
|
|
2
|
+
export declare function runSpecificTestsCmd({ tests, projects, passthroughArgs, platform, envOverrides, repoDir, }: {
|
|
3
3
|
tests?: TestCase[];
|
|
4
4
|
projects: string[];
|
|
5
5
|
passthroughArgs?: string;
|
|
6
6
|
platform: Platform;
|
|
7
7
|
filesFilter?: string;
|
|
8
8
|
envOverrides?: Record<string, string>;
|
|
9
|
+
repoDir: string;
|
|
9
10
|
}): Promise<CommandToRun>;
|
|
10
11
|
//# 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":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAY5D,wBAAsB,mBAAmB,CAAC,EACxC,KAAU,EACV,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,OAAO,GACR,EAAE;IACD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,YAAY,CAAC,CA0FxB"}
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.runSpecificTestsCmd = runSpecificTestsCmd;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
4
8
|
const utils_1 = require("../utils");
|
|
5
9
|
const run_all_tests_1 = require("./run-all-tests");
|
|
6
|
-
async function runSpecificTestsCmd({ tests = [], projects, passthroughArgs, platform, envOverrides, }) {
|
|
10
|
+
async function runSpecificTestsCmd({ tests = [], projects, passthroughArgs, platform, envOverrides, repoDir, }) {
|
|
7
11
|
if (!tests || tests.length === 0) {
|
|
8
12
|
throw new Error("No tests found");
|
|
9
13
|
}
|
|
10
14
|
let patternsToGrep = [];
|
|
11
15
|
let filesToRun = [];
|
|
12
16
|
for (const testCase of tests) {
|
|
13
|
-
|
|
17
|
+
// TODO: Why do we have this getAllFilePaths call?
|
|
18
|
+
// TODO: Can we remove `dir` from the test case entity?
|
|
19
|
+
const files = await (0, utils_1.getAllFilePaths)(testCase.dir, repoDir, {
|
|
14
20
|
filePath: testCase.filePath,
|
|
15
21
|
});
|
|
16
22
|
let matchingFilePath = "";
|
|
@@ -19,6 +25,7 @@ async function runSpecificTestsCmd({ tests = [], projects, passthroughArgs, plat
|
|
|
19
25
|
filePath: file,
|
|
20
26
|
scenarioName: testCase.name,
|
|
21
27
|
suites: testCase.suites,
|
|
28
|
+
repoDir,
|
|
22
29
|
});
|
|
23
30
|
if (match) {
|
|
24
31
|
matchingFilePath = file;
|
|
@@ -40,8 +47,9 @@ async function runSpecificTestsCmd({ tests = [], projects, passthroughArgs, plat
|
|
|
40
47
|
filePath: matchingFilePath,
|
|
41
48
|
scenarioName: testCase.name,
|
|
42
49
|
suites: testCase.suites,
|
|
50
|
+
repoDir,
|
|
43
51
|
});
|
|
44
|
-
const isFileMarkedSerial = await (0, utils_1.hasTopLevelDescribeConfigureWithSerialMode)(matchingFilePath);
|
|
52
|
+
const isFileMarkedSerial = await (0, utils_1.hasTopLevelDescribeConfigureWithSerialMode)(path_1.default.join(repoDir, matchingFilePath));
|
|
45
53
|
if (!isFileMarkedSerial && testCaseNode) {
|
|
46
54
|
const parentDescribe = (0, utils_1.findFirstSerialDescribeBlock)(testCaseNode);
|
|
47
55
|
if (!parentDescribe) {
|
|
@@ -55,7 +63,7 @@ async function runSpecificTestsCmd({ tests = [], projects, passthroughArgs, plat
|
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
65
|
}
|
|
58
|
-
const teardownLabels = await (0, utils_1.labelTeardownProjects)(projects, platform);
|
|
66
|
+
const teardownLabels = await (0, utils_1.labelTeardownProjects)(projects, platform, repoDir);
|
|
59
67
|
const isRunningForTeardownProjectOnly = teardownLabels && teardownLabels.every((label) => label.isTeardown);
|
|
60
68
|
if (isRunningForTeardownProjectOnly) {
|
|
61
69
|
// To run teardown projects, we need to run the `setup` project first, and playwright runs
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ type PlaywrightProject = {
|
|
|
6
6
|
testIgnore: string[] | string | undefined;
|
|
7
7
|
teardown: string | undefined;
|
|
8
8
|
};
|
|
9
|
-
export declare function getProjectsFromPlaywrightConfig(platform: Platform): Promise<PlaywrightProject[]>;
|
|
9
|
+
export declare function getProjectsFromPlaywrightConfig(platform: Platform, repoDir: string): Promise<PlaywrightProject[]>;
|
|
10
10
|
export {};
|
|
11
11
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAIA,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,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA+B9B"}
|
package/dist/utils/config.js
CHANGED
|
@@ -4,40 +4,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getProjectsFromPlaywrightConfig = getProjectsFromPlaywrightConfig;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
9
|
const path_1 = __importDefault(require("path"));
|
|
8
|
-
// For TypeScript type safety
|
|
9
|
-
let tsxImport = null;
|
|
10
10
|
const types_1 = require("../types");
|
|
11
|
-
async function getProjectsFromPlaywrightConfig(platform) {
|
|
11
|
+
async function getProjectsFromPlaywrightConfig(platform, repoDir) {
|
|
12
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
13
|
try {
|
|
36
|
-
const
|
|
37
|
-
|
|
14
|
+
const configPath = path_1.default.join(repoDir, configName);
|
|
15
|
+
const tmpScriptPath = path_1.default.join(repoDir, "temp-extract-projects.js");
|
|
16
|
+
fs_1.default.writeFileSync(tmpScriptPath, `
|
|
17
|
+
// Import the config directly with the full path
|
|
18
|
+
const configModule = require('${configPath.replace(/\\/g, "\\\\")}');
|
|
19
|
+
const projects = configModule.default.projects;
|
|
20
|
+
console.log(JSON.stringify(projects));
|
|
21
|
+
`);
|
|
22
|
+
const result = (0, child_process_1.execSync)(`npx -y ts-node ${tmpScriptPath}`, {
|
|
23
|
+
encoding: "utf8",
|
|
24
|
+
env: {
|
|
25
|
+
...process.env,
|
|
26
|
+
TS_NODE_PROJECT: path_1.default.join(repoDir, "tsconfig.json"),
|
|
27
|
+
NODE_PATH: path_1.default.join(repoDir, "node_modules"),
|
|
28
|
+
},
|
|
29
|
+
cwd: repoDir,
|
|
30
|
+
});
|
|
31
|
+
fs_1.default.unlinkSync(tmpScriptPath);
|
|
32
|
+
const projects = JSON.parse(result);
|
|
33
|
+
return projects;
|
|
38
34
|
}
|
|
39
|
-
catch (
|
|
40
|
-
console.error("Error
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error("Error extracting Playwright projects:", error);
|
|
41
37
|
}
|
|
42
38
|
return [];
|
|
43
39
|
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { Node, SourceFile } from "ts-morph";
|
|
2
2
|
import { Platform, TestFramework } from "../types";
|
|
3
|
-
export declare function getAllFilePaths(directoryPath
|
|
3
|
+
export declare function getAllFilePaths(directoryPath: string | undefined, repoDir: string, filters?: {
|
|
4
4
|
filePath?: string;
|
|
5
5
|
}): Promise<string[]>;
|
|
6
6
|
export declare const getTestModuleAliasFromSourceFile: (sourceFile: SourceFile) => string;
|
|
7
|
-
export declare function getTestCaseNode({ filePath, scenarioName, suites, }: {
|
|
7
|
+
export declare function getTestCaseNode({ filePath, scenarioName, suites, repoDir, }: {
|
|
8
8
|
filePath: string;
|
|
9
9
|
scenarioName: string;
|
|
10
10
|
suites?: string[];
|
|
11
|
+
repoDir: string;
|
|
11
12
|
}): Promise<{
|
|
12
13
|
testCaseNode: Node | undefined;
|
|
13
14
|
sourceFile: SourceFile;
|
|
14
15
|
}>;
|
|
15
|
-
export declare function hasTestBlock({ filePath, scenarioName, suites, }: {
|
|
16
|
+
export declare function hasTestBlock({ filePath, scenarioName, suites, repoDir, }: {
|
|
16
17
|
filePath: string;
|
|
17
18
|
scenarioName: string;
|
|
18
19
|
suites?: string[];
|
|
20
|
+
repoDir: string;
|
|
19
21
|
}): Promise<boolean>;
|
|
20
22
|
export declare function getDescribeBlockName(node: Node): string | undefined;
|
|
21
23
|
export declare function findFirstSerialDescribeBlock(node: Node | undefined): Node | undefined;
|
|
@@ -27,19 +29,20 @@ export declare function markTestAsOnly({ sourceFile, parentDescribeNode, testCas
|
|
|
27
29
|
filePath: string;
|
|
28
30
|
}): Promise<void>;
|
|
29
31
|
export declare const filterArrayByGlobMatchersSet: (input: string[], globMatcherSets: string[][]) => string[];
|
|
30
|
-
export declare function labelTeardownProjects(projectNames: string[], platform: Platform): Promise<{
|
|
32
|
+
export declare function labelTeardownProjects(projectNames: string[], platform: Platform, repoDir: string): Promise<{
|
|
31
33
|
isTeardown: boolean;
|
|
32
34
|
correspondingSetupProject: string | undefined;
|
|
33
35
|
}[]>;
|
|
34
|
-
export declare const generateProjectFilters: ({ platform, filteringSets, }: {
|
|
36
|
+
export declare const generateProjectFilters: ({ platform, filteringSets, repoDir, }: {
|
|
35
37
|
platform: Platform;
|
|
36
38
|
filteringSets: string[];
|
|
39
|
+
repoDir: string;
|
|
37
40
|
}) => Promise<string[]>;
|
|
38
41
|
export declare function buildRepoName(projectName: string): string;
|
|
39
42
|
export declare const pickNameFromPackageJson: () => Promise<string | undefined>;
|
|
40
43
|
export declare const downloadBuild: (buildUrl: string) => Promise<void>;
|
|
41
44
|
export declare const getTestRunner: (platform: Platform) => TestFramework;
|
|
42
|
-
export declare const handleTeardownSkipFlag: (directory: string) => Promise<void>;
|
|
45
|
+
export declare const handleTeardownSkipFlag: (directory: string, repoDir: string) => Promise<void>;
|
|
43
46
|
/**
|
|
44
47
|
* function to get the test block and test node for the scenario
|
|
45
48
|
* @export
|
|
@@ -47,10 +50,11 @@ export declare const handleTeardownSkipFlag: (directory: string) => Promise<void
|
|
|
47
50
|
* @param {string} content
|
|
48
51
|
* @return { testBlock: string; parentDescribe: string; } testBlock - the test block content, testNode - the test function node
|
|
49
52
|
*/
|
|
50
|
-
export declare function getTypescriptTestBlock({ scenarioName, suites, content, }: {
|
|
53
|
+
export declare function getTypescriptTestBlock({ scenarioName, suites, content, repoDir, }: {
|
|
51
54
|
scenarioName: string;
|
|
52
55
|
suites?: string[];
|
|
53
56
|
content: string;
|
|
57
|
+
repoDir: string;
|
|
54
58
|
}): {
|
|
55
59
|
testBlock: string | undefined;
|
|
56
60
|
testNode: Node | undefined;
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/index.js
CHANGED
|
@@ -23,17 +23,17 @@ const util_1 = require("util");
|
|
|
23
23
|
const cmd_1 = require("../lib/cmd");
|
|
24
24
|
const types_1 = require("../types");
|
|
25
25
|
const config_1 = require("./config");
|
|
26
|
-
async function getAllFilePaths(directoryPath = "tests", filters = {}) {
|
|
26
|
+
async function getAllFilePaths(directoryPath = "tests", repoDir, filters = {}) {
|
|
27
27
|
let filePaths = [];
|
|
28
28
|
try {
|
|
29
|
-
const files = await promises_1.default.readdir(directoryPath);
|
|
29
|
+
const files = await promises_1.default.readdir(path_1.default.join(repoDir, directoryPath));
|
|
30
30
|
let allFilePaths = [];
|
|
31
31
|
for (const file of files) {
|
|
32
32
|
const filePath = path_1.default.join(directoryPath, file);
|
|
33
|
-
const stat = await promises_1.default.lstat(filePath);
|
|
33
|
+
const stat = await promises_1.default.lstat(path_1.default.join(repoDir, filePath));
|
|
34
34
|
if (stat.isDirectory()) {
|
|
35
35
|
// If it's a directory, recursively get file paths from the directory
|
|
36
|
-
const nestedFiles = await getAllFilePaths(filePath, filters);
|
|
36
|
+
const nestedFiles = await getAllFilePaths(filePath, repoDir, filters);
|
|
37
37
|
allFilePaths = allFilePaths.concat(nestedFiles);
|
|
38
38
|
}
|
|
39
39
|
else {
|
|
@@ -67,20 +67,22 @@ const getTestModuleAliasFromSourceFile = (sourceFile) => {
|
|
|
67
67
|
?.getText() || "test");
|
|
68
68
|
};
|
|
69
69
|
exports.getTestModuleAliasFromSourceFile = getTestModuleAliasFromSourceFile;
|
|
70
|
-
async function getTestCaseNode({ filePath, scenarioName, suites, }) {
|
|
71
|
-
const content = await promises_1.default.readFile(filePath, "utf-8");
|
|
70
|
+
async function getTestCaseNode({ filePath, scenarioName, suites, repoDir, }) {
|
|
71
|
+
const content = await promises_1.default.readFile(path_1.default.join(repoDir, filePath), "utf-8");
|
|
72
72
|
const { testNode, sourceFile } = getTypescriptTestBlock({
|
|
73
73
|
scenarioName,
|
|
74
74
|
content,
|
|
75
75
|
suites, // since this method is called on the generated content, not the whole file
|
|
76
|
+
repoDir,
|
|
76
77
|
});
|
|
77
78
|
return { testCaseNode: testNode, sourceFile };
|
|
78
79
|
}
|
|
79
|
-
async function hasTestBlock({ filePath, scenarioName, suites, }) {
|
|
80
|
+
async function hasTestBlock({ filePath, scenarioName, suites, repoDir, }) {
|
|
80
81
|
const { testCaseNode } = await getTestCaseNode({
|
|
81
82
|
filePath,
|
|
82
83
|
scenarioName,
|
|
83
84
|
suites,
|
|
85
|
+
repoDir,
|
|
84
86
|
});
|
|
85
87
|
return !!testCaseNode;
|
|
86
88
|
}
|
|
@@ -179,8 +181,8 @@ globMatcherSets) => {
|
|
|
179
181
|
return filteredList;
|
|
180
182
|
};
|
|
181
183
|
exports.filterArrayByGlobMatchersSet = filterArrayByGlobMatchersSet;
|
|
182
|
-
async function labelTeardownProjects(projectNames, platform) {
|
|
183
|
-
const allProjects = await (0, config_1.getProjectsFromPlaywrightConfig)(platform);
|
|
184
|
+
async function labelTeardownProjects(projectNames, platform, repoDir) {
|
|
185
|
+
const allProjects = await (0, config_1.getProjectsFromPlaywrightConfig)(platform, repoDir);
|
|
184
186
|
return projectNames.map((projectName) => {
|
|
185
187
|
const setupForTeardown = allProjects.find((p) => p.teardown === projectName);
|
|
186
188
|
if (setupForTeardown) {
|
|
@@ -197,8 +199,8 @@ async function labelTeardownProjects(projectNames, platform) {
|
|
|
197
199
|
}
|
|
198
200
|
});
|
|
199
201
|
}
|
|
200
|
-
const generateProjectFilters = async ({ platform, filteringSets, }) => {
|
|
201
|
-
const allProjects = await (0, config_1.getProjectsFromPlaywrightConfig)(platform);
|
|
202
|
+
const generateProjectFilters = async ({ platform, filteringSets, repoDir, }) => {
|
|
203
|
+
const allProjects = await (0, config_1.getProjectsFromPlaywrightConfig)(platform, repoDir);
|
|
202
204
|
const allProjectNames = allProjects.map((project) => project.name);
|
|
203
205
|
const filters = filteringSets.map((matchingString) => matchingString.split(","));
|
|
204
206
|
const filteredProjects = (0, exports.filterArrayByGlobMatchersSet)(allProjectNames, filters);
|
|
@@ -226,7 +228,10 @@ const downloadBuild = async (buildUrl) => {
|
|
|
226
228
|
if (buildDownloadScript && buildUrl) {
|
|
227
229
|
console.log(`Downloading build from ${buildUrl}`);
|
|
228
230
|
await (0, cmd_1.spawnCmd)(`npm`, ["run", "download", buildUrl], {
|
|
229
|
-
|
|
231
|
+
cwd: process.cwd(),
|
|
232
|
+
envOverrides: {},
|
|
233
|
+
captureOutput: false,
|
|
234
|
+
throwOnError: true,
|
|
230
235
|
});
|
|
231
236
|
}
|
|
232
237
|
};
|
|
@@ -237,9 +242,9 @@ const getTestRunner = (platform) => {
|
|
|
237
242
|
: types_1.TestFramework.APPWRIGHT;
|
|
238
243
|
};
|
|
239
244
|
exports.getTestRunner = getTestRunner;
|
|
240
|
-
const getAllTeardownFiles = async (directory) => {
|
|
245
|
+
const getAllTeardownFiles = async (directory, repoDir) => {
|
|
241
246
|
const teardownFileRegex = /.*\.teardown\.ts/;
|
|
242
|
-
const files = await getAllFilePaths(directory);
|
|
247
|
+
const files = await getAllFilePaths(directory, repoDir);
|
|
243
248
|
return files.filter((file) => teardownFileRegex.test(file));
|
|
244
249
|
};
|
|
245
250
|
const skipTeardownFile = async (filePath) => {
|
|
@@ -263,13 +268,15 @@ const skipTeardownFile = async (filePath) => {
|
|
|
263
268
|
};
|
|
264
269
|
class TeardownManager {
|
|
265
270
|
directory;
|
|
266
|
-
|
|
271
|
+
repoDir;
|
|
272
|
+
constructor(directory, repoDir) {
|
|
267
273
|
this.directory = directory;
|
|
274
|
+
this.repoDir = repoDir;
|
|
268
275
|
}
|
|
269
276
|
teardownFiles = [];
|
|
270
277
|
teardownFileContents = [];
|
|
271
278
|
async skip() {
|
|
272
|
-
this.teardownFiles = await getAllTeardownFiles(this.directory);
|
|
279
|
+
this.teardownFiles = await getAllTeardownFiles(this.directory, this.repoDir);
|
|
273
280
|
this.teardownFileContents = await Promise.all(this.teardownFiles.map(async (filePath) => {
|
|
274
281
|
const content = await promises_1.default.readFile(filePath, "utf-8");
|
|
275
282
|
return { filePath, content };
|
|
@@ -282,9 +289,9 @@ class TeardownManager {
|
|
|
282
289
|
});
|
|
283
290
|
}
|
|
284
291
|
}
|
|
285
|
-
const handleTeardownSkipFlag = async (directory) => {
|
|
292
|
+
const handleTeardownSkipFlag = async (directory, repoDir) => {
|
|
286
293
|
console.log("Skipping teardown tests ...");
|
|
287
|
-
const teardowns = new TeardownManager(directory);
|
|
294
|
+
const teardowns = new TeardownManager(directory, repoDir);
|
|
288
295
|
await teardowns.skip();
|
|
289
296
|
// revert teardown changes on exit
|
|
290
297
|
process.on("beforeExit", () => {
|
|
@@ -329,9 +336,9 @@ const getParentDescribeNames = (node) => {
|
|
|
329
336
|
* @param {string} content
|
|
330
337
|
* @return { testBlock: string; parentDescribe: string; } testBlock - the test block content, testNode - the test function node
|
|
331
338
|
*/
|
|
332
|
-
function getTypescriptTestBlock({ scenarioName, suites, content, }) {
|
|
339
|
+
function getTypescriptTestBlock({ scenarioName, suites, content, repoDir, }) {
|
|
333
340
|
const project = new ts_morph_1.Project();
|
|
334
|
-
const sourceFile = project.createSourceFile("test.ts", content);
|
|
341
|
+
const sourceFile = project.createSourceFile(path_1.default.join(repoDir, "test.ts"), content);
|
|
335
342
|
const testAlias = (0, exports.getTestModuleAliasFromSourceFile)(sourceFile);
|
|
336
343
|
// Get all test function nodes that match the scenario name
|
|
337
344
|
const matchingTestFunctionNodes = sourceFile
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-run",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
"commander": "^12.1.0",
|
|
20
20
|
"dotenv": "^16.4.5",
|
|
21
21
|
"minimatch": "^10.0.1",
|
|
22
|
-
"ts-morph": "^23.0.0"
|
|
23
|
-
"tsx": "^4.16.2"
|
|
22
|
+
"ts-morph": "^23.0.0"
|
|
24
23
|
},
|
|
25
24
|
"devDependencies": {
|
|
26
25
|
"@types/async-retry": "^1.4.8",
|