@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 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;
@@ -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,GACb,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;;;GAqBA;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"}
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(process.cwd(), "playwright-report", `summary.json`);
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
- env?: Record<string, string>;
11
- cwd?: string;
12
- captureOutput?: boolean;
13
- throwOnError?: boolean;
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;
@@ -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,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,YAAY;;GASxE;AAED,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CAIxB,GACA,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6C5C"}
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, { env });
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.env },
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":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAY5D,wBAAsB,mBAAmB,CAAC,EACxC,KAAU,EACV,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,YAAY,GACb,EAAE;IACD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC,GAAG,OAAO,CAAC,YAAY,CAAC,CAiFxB"}
1
+ {"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
- const files = await (0, utils_1.getAllFilePaths)(testCase.dir, {
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
@@ -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":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,GAAG,CAAC;IACT,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAqC9B"}
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"}
@@ -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 playwrightConfig = (await tsxImport.require(pwFile, `${repoDir}/${lastDir}`)).default;
37
- return playwrightConfig.projects;
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 (err) {
40
- console.error("Error getting project list from playwright config", err);
35
+ catch (error) {
36
+ console.error("Error extracting Playwright projects:", error);
41
37
  }
42
38
  return [];
43
39
  }
@@ -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?: string, filters?: {
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":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
@@ -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
- env: { ...Object(process.env) },
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
- constructor(directory) {
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.2",
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",