@empiricalrun/test-run 0.16.1 → 0.17.1

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/bin/commands/run.d.ts.map +1 -1
  3. package/dist/bin/commands/run.js +13 -14
  4. package/dist/bin/index.js +0 -4
  5. package/dist/dashboard.d.ts +1 -1
  6. package/dist/dashboard.d.ts.map +1 -1
  7. package/dist/dashboard.js +4 -6
  8. package/dist/index.d.ts +0 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -3
  11. package/dist/lib/cmd.d.ts.map +1 -1
  12. package/dist/lib/cmd.js +0 -36
  13. package/dist/lib/merge-reports/html.d.ts.map +1 -1
  14. package/dist/lib/merge-reports/html.js +2 -11
  15. package/dist/lib/merge-reports/index.d.ts +6 -1
  16. package/dist/lib/merge-reports/index.d.ts.map +1 -1
  17. package/dist/lib/merge-reports/index.js +85 -9
  18. package/dist/lib/merge-reports/types.d.ts +1 -1
  19. package/dist/lib/run-all-tests.d.ts.map +1 -1
  20. package/dist/lib/run-all-tests.js +11 -5
  21. package/dist/utils/index.d.ts +0 -2
  22. package/dist/utils/index.d.ts.map +1 -1
  23. package/dist/utils/index.js +1 -12
  24. package/package.json +5 -5
  25. package/tsconfig.tsbuildinfo +1 -1
  26. package/dist/bin/commands/estimate-time-shard.d.ts +0 -3
  27. package/dist/bin/commands/estimate-time-shard.d.ts.map +0 -1
  28. package/dist/bin/commands/estimate-time-shard.js +0 -122
  29. package/dist/bin/commands/optimize-shards.d.ts +0 -3
  30. package/dist/bin/commands/optimize-shards.d.ts.map +0 -1
  31. package/dist/bin/commands/optimize-shards.js +0 -544
  32. package/dist/lib/cancellation-watcher.d.ts +0 -5
  33. package/dist/lib/cancellation-watcher.d.ts.map +0 -1
  34. package/dist/lib/cancellation-watcher.js +0 -49
  35. package/test-data/blob-report/report-1.zip +0 -0
  36. package/test-data/blob-report/report-2.zip +0 -0
  37. package/test-data/expand-serial-fixture/playwright.config.ts +0 -6
  38. package/test-data/expand-serial-fixture/serial.spec.ts +0 -17
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @empiricalrun/test-run
2
2
 
3
+ ## 0.17.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 8b1be9e: fix: html report attachment urls for pw 1.60.0
8
+ - Updated dependencies [8b1be9e]
9
+ - @empiricalrun/reporter@0.29.1
10
+
11
+ ## 0.17.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 6fb8170: feat: playwright utils upgraded to use new core
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [6fb8170]
20
+ - @empiricalrun/reporter@0.29.0
21
+
3
22
  ## 0.16.1
4
23
 
5
24
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,QAsLlD"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,QAiLlD"}
@@ -50,10 +50,6 @@ function registerRunCommand(program) {
50
50
  ...options.project,
51
51
  ];
52
52
  const pwOptions = command.args.filter((arg) => !optionsToStrip.includes(arg));
53
- const projectName = process.env.PROJECT_NAME || (await (0, utils_1.pickNameFromPackageJson)());
54
- if (!projectName) {
55
- throw new Error("Project name is required");
56
- }
57
53
  const directory = options.dir || "tests";
58
54
  const suites = options.suites && options.suites.trim() !== ""
59
55
  ? options.suites?.split(",")
@@ -70,16 +66,13 @@ function registerRunCommand(program) {
70
66
  ]
71
67
  : undefined);
72
68
  const environmentSlug = process.env.TEST_RUN_ENVIRONMENT || "";
73
- const useEnvFilePrecedence = process.env.ENV_FILE_PRECEDENCE === "true";
74
69
  const envOverrides = {};
75
- if (!useEnvFilePrecedence) {
76
- const environmentVariables = await (0, dashboard_1.fetchEnvironmentVariables)();
77
- environmentVariables.forEach((envVar) => {
78
- envOverrides[envVar.name] = envVar.value;
79
- });
80
- if (Object.keys(envOverrides).length > 0) {
81
- console.log(`Loaded environment variables: ${Object.keys(envOverrides).join(", ")}`);
82
- }
70
+ const environmentVariables = await (0, dashboard_1.fetchEnvironmentVariables)();
71
+ environmentVariables.forEach((envVar) => {
72
+ envOverrides[envVar.name] = envVar.value;
73
+ });
74
+ if (Object.keys(envOverrides).length > 0) {
75
+ console.log(`Loaded environment variables: ${Object.keys(envOverrides).join(", ")}`);
83
76
  }
84
77
  if (environmentSlug) {
85
78
  (0, env_files_1.writeEnvFiles)({
@@ -100,7 +93,7 @@ function registerRunCommand(program) {
100
93
  let environmentIgnore = [];
101
94
  try {
102
95
  if (environmentSlug) {
103
- const environment = await (0, dashboard_1.fetchEnvironment)(projectName, environmentSlug);
96
+ const environment = await (0, dashboard_1.fetchEnvironment)(environmentSlug);
104
97
  if (environment.playwright_projects_match &&
105
98
  environment.playwright_projects_match.length > 0) {
106
99
  environmentMatch = environment.playwright_projects_match;
@@ -124,6 +117,11 @@ function registerRunCommand(program) {
124
117
  if (options.skipTeardown) {
125
118
  await (0, utils_1.handleTeardownSkipFlag)(directory, repoDir);
126
119
  }
120
+ const grepTags = process.env.GREP_TAGS
121
+ ? process.env.GREP_TAGS.split(",")
122
+ .filter(Boolean)
123
+ .map((tag) => (tag.startsWith("@") ? tag : `@${tag}`))
124
+ : [];
127
125
  const hasTestsFilter = tests && tests.length > 0;
128
126
  let commandToRun;
129
127
  if (hasTestsFilter) {
@@ -140,6 +138,7 @@ function registerRunCommand(program) {
140
138
  projects: projectFilters,
141
139
  passthroughArgs: pwOptions.join(" "),
142
140
  envOverrides,
141
+ patternsToGrep: grepTags.length > 0 ? grepTags : undefined,
143
142
  });
144
143
  }
145
144
  const { hasTestPassed } = await (0, cmd_1.runTestsForCmd)(commandToRun, repoDir);
package/dist/bin/index.js CHANGED
@@ -6,10 +6,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const commander_1 = require("commander");
8
8
  const dotenv_1 = __importDefault(require("dotenv"));
9
- const estimate_time_shard_1 = require("./commands/estimate-time-shard");
10
9
  const failed_list_1 = require("./commands/failed-list");
11
10
  const merge_1 = require("./commands/merge");
12
- const optimize_shards_1 = require("./commands/optimize-shards");
13
11
  const run_1 = require("./commands/run");
14
12
  dotenv_1.default.config({
15
13
  path: [".env.local", ".env"],
@@ -21,6 +19,4 @@ commander_1.program
21
19
  (0, run_1.registerRunCommand)(commander_1.program);
22
20
  (0, merge_1.registerMergeCommand)(commander_1.program);
23
21
  (0, failed_list_1.registerFailedListCommand)(commander_1.program);
24
- (0, estimate_time_shard_1.registerEstimateTimeShardCommand)(commander_1.program);
25
- (0, optimize_shards_1.registerOptimizeShardsCommand)(commander_1.program);
26
22
  commander_1.program.parse(process.argv);
@@ -7,6 +7,6 @@ export type EnvironmentVariable = {
7
7
  created_at: string;
8
8
  updated_at: string;
9
9
  };
10
- export declare const fetchEnvironment: (projectName: string, environmentSlug: string) => Promise<Environment>;
10
+ export declare const fetchEnvironment: (environmentSlug: string) => Promise<Environment>;
11
11
  export declare const fetchEnvironmentVariables: () => Promise<EnvironmentVariable[]>;
12
12
  //# sourceMappingURL=dashboard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF,eAAO,MAAM,gBAAgB,GAC3B,aAAa,MAAM,EACnB,iBAAiB,MAAM,KACtB,OAAO,CAAC,WAAW,CAyDrB,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAa,OAAO,CACxD,mBAAmB,EAAE,CAkDtB,CAAC"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,MAAM,KACtB,OAAO,CAAC,WAAW,CAwDrB,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAa,OAAO,CACxD,mBAAmB,EAAE,CAkDtB,CAAC"}
package/dist/dashboard.js CHANGED
@@ -5,16 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.fetchEnvironmentVariables = exports.fetchEnvironment = void 0;
7
7
  const async_retry_1 = __importDefault(require("async-retry"));
8
- const utils_1 = require("./utils");
9
8
  const DOMAIN = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
10
- const fetchEnvironment = async (projectName, environmentSlug) => {
11
- const projectRepo = (0, utils_1.buildRepoName)(projectName);
9
+ const fetchEnvironment = async (environmentSlug) => {
12
10
  const data = await (0, async_retry_1.default)(async (bail) => {
13
11
  if (!process.env.EMPIRICALRUN_API_KEY) {
14
12
  console.error("No API token found. Skipping fetch environment from dashboard.");
15
13
  return;
16
14
  }
17
- const resp = await fetch(`${DOMAIN}/api/environments/list?project_repo_name=${projectRepo}&environment_slug=${environmentSlug}&is_disabled=false`, {
15
+ const resp = await fetch(`${DOMAIN}/api/environments/list?environment_slug=${environmentSlug}&is_disabled=false`, {
18
16
  method: "GET",
19
17
  headers: {
20
18
  "Content-Type": "application/json",
@@ -27,7 +25,7 @@ const fetchEnvironment = async (projectName, environmentSlug) => {
27
25
  bail(new Error(erroredResponse?.error?.message));
28
26
  return;
29
27
  }
30
- throw new Error(`Failed to fetch environment from dashboard for project: ${projectRepo} and env slug: ${environmentSlug}`);
28
+ throw new Error(`Failed to fetch environment from dashboard for env slug: ${environmentSlug}`);
31
29
  }
32
30
  return (await resp.json());
33
31
  }, {
@@ -38,7 +36,7 @@ const fetchEnvironment = async (projectName, environmentSlug) => {
38
36
  });
39
37
  const environment = data?.data?.environments?.find((env) => env.slug === environmentSlug);
40
38
  if (!environment) {
41
- throw new Error(`Failed to fetch environment from dashboard for project: ${projectRepo} and env slug: ${environmentSlug}.`);
39
+ throw new Error(`Failed to fetch environment from dashboard for env slug: ${environmentSlug}.`);
42
40
  }
43
41
  return environment;
44
42
  };
package/dist/index.d.ts CHANGED
@@ -7,7 +7,6 @@ import { getProjectsFromPlaywrightConfig } from "./utils/config";
7
7
  export { getProjectsFromPlaywrightConfig, parseTestListOutput, runSpecificTestsCmd, spawnCmd, };
8
8
  export { type BuildTestListOptions, type BuildTestListResult, buildTestList, buildTestListFromFailedTestRun, expandSerialDependencies, getAllTestsForFile, normalizeTestLine, parseTestListLine, type TestList, } from "./failed-test-list";
9
9
  export * from "./glob-matcher";
10
- export { type CancellationWatcher, startCancellationWatcher, } from "./lib/cancellation-watcher";
11
10
  export { filterArrayByGlobMatchersSet, generateProjectFilters, generateProjectFiltersV2, } from "./utils";
12
11
  export declare function runSingleTest({ testName, suites, filePath, projects, envOverrides, repoDir, stdout, stderr, }: {
13
12
  testName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAI/E,OAAO,EAAkB,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,GACT,CAAC;AACF,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,aAAa,EACb,8BAA8B,EAC9B,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,QAAQ,GACd,MAAM,oBAAoB,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,KAAK,mBAAmB,EACxB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,SAAS,CAAC;AAQjB,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,MAAM,EACN,MAAM,GACP,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;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC,GAAG,OAAO,CAAC;IACV,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,oBAAoB,CAAC;CACnC,CAAC,CAmBD;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CACjD,CAAC,CAeD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAI/E,OAAO,EAAkB,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,GACT,CAAC;AACF,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,aAAa,EACb,8BAA8B,EAC9B,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,QAAQ,GACd,MAAM,oBAAoB,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,SAAS,CAAC;AAQjB,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,MAAM,EACN,MAAM,GACP,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;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC,GAAG,OAAO,CAAC;IACV,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,oBAAoB,CAAC;CACnC,CAAC,CAmBD;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CACjD,CAAC,CAeD"}
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.generateProjectFiltersV2 = exports.generateProjectFilters = exports.filterArrayByGlobMatchersSet = exports.startCancellationWatcher = exports.parseTestListLine = exports.normalizeTestLine = exports.getAllTestsForFile = exports.expandSerialDependencies = exports.buildTestListFromFailedTestRun = exports.buildTestList = exports.spawnCmd = exports.runSpecificTestsCmd = exports.parseTestListOutput = exports.getProjectsFromPlaywrightConfig = void 0;
20
+ exports.generateProjectFiltersV2 = exports.generateProjectFilters = exports.filterArrayByGlobMatchersSet = exports.parseTestListLine = exports.normalizeTestLine = exports.getAllTestsForFile = exports.expandSerialDependencies = exports.buildTestListFromFailedTestRun = exports.buildTestList = exports.spawnCmd = exports.runSpecificTestsCmd = exports.parseTestListOutput = exports.getProjectsFromPlaywrightConfig = void 0;
21
21
  exports.runSingleTest = runSingleTest;
22
22
  exports.listProjectsAndTests = listProjectsAndTests;
23
23
  const fs_1 = __importDefault(require("fs"));
@@ -38,8 +38,6 @@ Object.defineProperty(exports, "getAllTestsForFile", { enumerable: true, get: fu
38
38
  Object.defineProperty(exports, "normalizeTestLine", { enumerable: true, get: function () { return failed_test_list_1.normalizeTestLine; } });
39
39
  Object.defineProperty(exports, "parseTestListLine", { enumerable: true, get: function () { return failed_test_list_1.parseTestListLine; } });
40
40
  __exportStar(require("./glob-matcher"), exports);
41
- var cancellation_watcher_1 = require("./lib/cancellation-watcher");
42
- Object.defineProperty(exports, "startCancellationWatcher", { enumerable: true, get: function () { return cancellation_watcher_1.startCancellationWatcher; } });
43
41
  var utils_1 = require("./utils");
44
42
  Object.defineProperty(exports, "filterArrayByGlobMatchersSet", { enumerable: true, get: function () { return utils_1.filterArrayByGlobMatchersSet; } });
45
43
  Object.defineProperty(exports, "generateProjectFilters", { enumerable: true, get: function () { return utils_1.generateProjectFilters; } });
@@ -1 +1 @@
1
- {"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../src/lib/cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,eAAe,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMxC,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,EACX,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC;;;GAqEF;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;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CACxC,GACA,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiD5C"}
1
+ {"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../src/lib/cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,eAAe,CAAC;AAGzD,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,EACX,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC;;;GAqBF;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;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CACxC,GACA,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiD5C"}
package/dist/lib/cmd.js CHANGED
@@ -5,7 +5,6 @@ exports.runTestsForCmd = runTestsForCmd;
5
5
  exports.spawnCmd = spawnCmd;
6
6
  const child_process_1 = require("child_process");
7
7
  const logger_1 = require("../logger");
8
- const cancellation_watcher_1 = require("./cancellation-watcher");
9
8
  function getCommandFromString(command) {
10
9
  const regex = /[^\s"']+|"([^"]*)"|'([^']*)'/g;
11
10
  const matches = command.match(regex) || [];
@@ -22,37 +21,8 @@ function getCommandFromString(command) {
22
21
  }
23
22
  async function runTestsForCmd({ command, args, env }, cwd, options) {
24
23
  logger_1.logger.debug(`Running cmd: ${command} with args: ${args}`);
25
- const testRunId = process.env.TEST_RUN_GITHUB_ACTION_ID;
26
- const apiKey = process.env.EMPIRICALRUN_API_KEY;
27
- console.log(`[CancellationWatcher] Environment: TEST_RUN_GITHUB_ACTION_ID=${testRunId}, EMPIRICALRUN_API_KEY=${apiKey ? "***" : "undefined"}`);
28
24
  let hasTestPassed = true;
29
25
  let wasCancelled = false;
30
- let cancellationWatcher;
31
- let childProcess;
32
- const cancelHandler = () => {
33
- wasCancelled = true;
34
- console.log(`[CancellationWatcher] Cancel handler invoked, killing child process (pid: ${childProcess?.pid})`);
35
- if (childProcess && !childProcess.killed) {
36
- // Use SIGTERM for more forceful termination that propagates to child processes
37
- childProcess.kill("SIGTERM");
38
- // Also try to kill the process group to ensure Playwright workers are stopped
39
- if (childProcess.pid) {
40
- try {
41
- process.kill(-childProcess.pid, "SIGTERM");
42
- console.log(`[CancellationWatcher] Sent SIGTERM to process group ${childProcess.pid}`);
43
- }
44
- catch {
45
- // Process group kill may fail if not a group leader
46
- }
47
- }
48
- }
49
- };
50
- if (testRunId && apiKey) {
51
- cancellationWatcher = (0, cancellation_watcher_1.startCancellationWatcher)(testRunId, apiKey, cancelHandler);
52
- }
53
- else {
54
- console.log("[CancellationWatcher] Not starting watcher - missing testRunId or apiKey");
55
- }
56
26
  try {
57
27
  await spawnCmd(command, args, {
58
28
  cwd,
@@ -61,17 +31,11 @@ async function runTestsForCmd({ command, args, env }, cwd, options) {
61
31
  throwOnError: true,
62
32
  stdout: options?.stdout,
63
33
  stderr: options?.stderr,
64
- onSpawn: (proc) => {
65
- childProcess = proc;
66
- },
67
34
  });
68
35
  }
69
36
  catch {
70
37
  hasTestPassed = false;
71
38
  }
72
- finally {
73
- cancellationWatcher?.stop();
74
- }
75
39
  return { hasTestPassed, wasCancelled };
76
40
  }
77
41
  async function spawnCmd(command, args, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/lib/merge-reports/html.ts"],"names":[],"mappings":"AAaA,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,IAAI,CAAC,CAsIf"}
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/lib/merge-reports/html.ts"],"names":[],"mappings":"AAeA,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoHf"}
@@ -52,10 +52,7 @@ async function patchMergedHtmlReport(htmlFilePath, summaryJsonFilePath) {
52
52
  logger_1.logger.error(`[Merge Reports] Failed to read HTML file:`, error);
53
53
  return;
54
54
  }
55
- // Support both old format (1.53.x) and new format (1.57.0+)
56
- const oldFormatMatch = htmlContent.match(/window\.playwrightReportBase64\s*=\s*"(?:data:application\/zip;base64,)?([^"]+)"/);
57
- const newFormatMatch = htmlContent.match(/<script\s+id="playwrightReportBase64"[^>]*>(?:data:application\/zip;base64,)?([^<]+)<\/script>/);
58
- const base64 = oldFormatMatch?.[1] || newFormatMatch?.[1];
55
+ const base64 = (0, reporter_1.findPlaywrightReportBase64)(htmlContent);
59
56
  if (!base64) {
60
57
  logger_1.logger.error(`[Merge Reports] Base64 zip data not found in HTML`);
61
58
  return;
@@ -89,13 +86,7 @@ async function patchMergedHtmlReport(htmlFilePath, summaryJsonFilePath) {
89
86
  const newBuffer = await (0, zip_1.createZipFromDirectory)(tempDir);
90
87
  const newBase64 = newBuffer.toString("base64");
91
88
  logger_1.logger.info(`[Merge Reports] New zip created in ${Date.now() - stepTime}ms`);
92
- let updatedHtml;
93
- if (oldFormatMatch) {
94
- updatedHtml = htmlContent.replace(/(window\.playwrightReportBase64\s*=\s*")(?:data:application\/zip;base64,)?[^"]*(")/, `$1data:application/zip;base64,${newBase64}$2`);
95
- }
96
- else {
97
- updatedHtml = htmlContent.replace(/(<script\s+id="playwrightReportBase64"[^>]*>)(?:data:application\/zip;base64,)?[^<]*(<\/script>)/, `$1data:application/zip;base64,${newBase64}$2`);
98
- }
89
+ const updatedHtml = (0, reporter_1.replacePlaywrightReportBase64)(htmlContent, newBase64);
99
90
  await fs_1.default.promises.writeFile(htmlFilePath, updatedHtml, "utf8");
100
91
  logger_1.logger.info(`[Merge Reports] HTML file patched successfully`);
101
92
  }
@@ -2,11 +2,16 @@ import type { MergeReportsOptions, UploadOptions } from "./types";
2
2
  export { patchMergedHtmlReport } from "./html";
3
3
  export { patchSummaryJson } from "./json";
4
4
  export type { MergeReportsOptions, UploadOptions } from "./types";
5
+ export declare function parsePlaywrightVersionFromReportJsonl(content: string): string | null;
6
+ export declare function getPlaywrightVersionForMerge(blobDir: string): Promise<string | null>;
5
7
  export declare function runPlaywrightMergeReports(options: MergeReportsOptions): Promise<{
6
8
  success: boolean;
7
9
  }>;
8
10
  export declare function extractUrlMappingsFromBlobs(blobDir: string): Promise<Record<string, string>>;
9
- export declare function uploadMergedReports(cwd: string, outputDir: string, uploadOptions: UploadOptions): Promise<void>;
11
+ export declare function uploadMergedReports({ outputDir, uploadOptions, }: {
12
+ outputDir: string;
13
+ uploadOptions: UploadOptions;
14
+ }): Promise<void>;
10
15
  export declare function mergeReports(options: {
11
16
  blobDir?: string;
12
17
  cwd?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/merge-reports/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC1C,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AA0DlE,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA+B/B;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAoCjC;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,IAAI,CAAC,CAsDf;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA+EhC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/merge-reports/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC1C,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AA0DlE,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CA6Bf;AAMD,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyCxB;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA+C/B;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAoCjC;AAED,wBAAsB,mBAAmB,CAAC,EACxC,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;CAC9B,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDhB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAgFhC"}
@@ -4,6 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.patchSummaryJson = exports.patchMergedHtmlReport = void 0;
7
+ exports.parsePlaywrightVersionFromReportJsonl = parsePlaywrightVersionFromReportJsonl;
8
+ exports.getPlaywrightVersionForMerge = getPlaywrightVersionForMerge;
7
9
  exports.runPlaywrightMergeReports = runPlaywrightMergeReports;
8
10
  exports.extractUrlMappingsFromBlobs = extractUrlMappingsFromBlobs;
9
11
  exports.uploadMergedReports = uploadMergedReports;
@@ -64,13 +66,86 @@ function getCredentialsFromEnv(enableS3) {
64
66
  }
65
67
  return null;
66
68
  }
69
+ function parsePlaywrightVersionFromReportJsonl(content) {
70
+ let userAgentVersion = null;
71
+ for (const line of content.split("\n")) {
72
+ if (!line.trim()) {
73
+ continue;
74
+ }
75
+ try {
76
+ const event = JSON.parse(line);
77
+ if (event.method === "onConfigure") {
78
+ const version = event.params?.config?.version;
79
+ if (typeof version === "string") {
80
+ return version;
81
+ }
82
+ }
83
+ if (event.method === "onBlobReportMetadata") {
84
+ const userAgent = event.params?.userAgent;
85
+ if (typeof userAgent === "string") {
86
+ const match = userAgent.match(/\bPlaywright\/([^\s)]+)/);
87
+ if (match?.[1])
88
+ userAgentVersion = match[1];
89
+ }
90
+ }
91
+ }
92
+ catch {
93
+ // Ignore malformed lines; Playwright merge-reports will validate the blob.
94
+ }
95
+ }
96
+ return userAgentVersion;
97
+ }
98
+ function isSafePlaywrightVersion(version) {
99
+ return /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version);
100
+ }
101
+ async function getPlaywrightVersionForMerge(blobDir) {
102
+ const override = process.env.PLAYWRIGHT_MERGE_VERSION;
103
+ if (override) {
104
+ if (!isSafePlaywrightVersion(override)) {
105
+ throw new Error(`Invalid PLAYWRIGHT_MERGE_VERSION: ${override}`);
106
+ }
107
+ return override;
108
+ }
109
+ const versions = new Set();
110
+ const files = fs_1.default.readdirSync(blobDir).filter((f) => f.endsWith(".zip"));
111
+ for (const fileName of files) {
112
+ const reportJsonl = await (0, zip_1.readZipEntry)(path_1.default.join(blobDir, fileName), "report.jsonl");
113
+ if (!reportJsonl) {
114
+ continue;
115
+ }
116
+ const version = parsePlaywrightVersionFromReportJsonl(reportJsonl.toString("utf8"));
117
+ if (version) {
118
+ if (!isSafePlaywrightVersion(version)) {
119
+ throw new Error(`Invalid Playwright version in ${fileName}: ${version}`);
120
+ }
121
+ versions.add(version);
122
+ }
123
+ }
124
+ if (versions.size > 1) {
125
+ logger_1.logger.warn(`[Merge Reports] Multiple Playwright versions found in blobs: ${Array.from(versions).join(", ")}`);
126
+ }
127
+ return versions.values().next().value ?? null;
128
+ }
67
129
  async function runPlaywrightMergeReports(options) {
68
130
  const { blobDir, outputDir, cwd } = options;
69
131
  logger_1.logger.debug(`[Merge Reports] Running playwright merge-reports`);
70
132
  logger_1.logger.debug(`[Merge Reports] Blob dir: ${blobDir}`);
71
133
  logger_1.logger.debug(`[Merge Reports] Output dir: ${outputDir}`);
72
134
  try {
73
- await (0, cmd_1.spawnCmd)("npx", ["playwright", "merge-reports", blobDir, "--reporter", "html,json"], {
135
+ const playwrightVersion = await getPlaywrightVersionForMerge(blobDir);
136
+ if (!playwrightVersion) {
137
+ logger_1.logger.error(`[Merge Reports] Could not determine Playwright version from blob reports`);
138
+ return { success: false };
139
+ }
140
+ logger_1.logger.debug(`[Merge Reports] Playwright version: ${playwrightVersion}`);
141
+ await (0, cmd_1.spawnCmd)("npx", [
142
+ "--yes",
143
+ `playwright@${playwrightVersion}`,
144
+ "merge-reports",
145
+ blobDir,
146
+ "--reporter",
147
+ "html,json",
148
+ ], {
74
149
  cwd,
75
150
  envOverrides: {
76
151
  PLAYWRIGHT_HTML_OPEN: "never",
@@ -112,9 +187,9 @@ async function extractUrlMappingsFromBlobs(blobDir) {
112
187
  logger_1.logger.info(`[Merge Reports] Total URL mappings: ${Object.keys(combinedMap).length}`);
113
188
  return combinedMap;
114
189
  }
115
- async function uploadMergedReports(cwd, outputDir, uploadOptions) {
116
- const { projectName, runId, baseUrl, uploadBucket, credentials } = uploadOptions;
117
- const destinationDir = path_1.default.join(projectName, runId);
190
+ async function uploadMergedReports({ outputDir, uploadOptions, }) {
191
+ const { projectSlug, runId, baseUrl, uploadBucket, credentials } = uploadOptions;
192
+ const destinationDir = path_1.default.join(projectSlug, runId);
118
193
  const htmlFilePath = path_1.default.join(outputDir, "index.html");
119
194
  const jsonFilePath = path_1.default.join(outputDir, "summary.json");
120
195
  if (fs_1.default.existsSync(htmlFilePath)) {
@@ -164,7 +239,7 @@ async function mergeReports(options) {
164
239
  const cwd = options.cwd || process.cwd();
165
240
  const blobDir = options.blobDir || path_1.default.join(cwd, "blob-report");
166
241
  const outputDir = path_1.default.join(cwd, "playwright-report");
167
- const projectName = process.env.PROJECT_NAME;
242
+ const projectSlug = process.env.PROJECT_NAME;
168
243
  const runId = process.env.TEST_RUN_GITHUB_ACTION_ID;
169
244
  // Track peak memory usage
170
245
  let peakMemoryMb = 0;
@@ -175,7 +250,7 @@ async function mergeReports(options) {
175
250
  }
176
251
  }, 100);
177
252
  try {
178
- if (!projectName || !runId) {
253
+ if (!projectSlug || !runId) {
179
254
  logger_1.logger.error(`[Merge Reports] PROJECT_NAME and TEST_RUN_GITHUB_ACTION_ID must be set`);
180
255
  return { success: false };
181
256
  }
@@ -202,13 +277,14 @@ async function mergeReports(options) {
202
277
  const credentials = getCredentialsFromEnv(enableS3);
203
278
  if (credentials) {
204
279
  const { baseUrl, uploadBucket } = getStorageConfig(enableS3);
205
- await uploadMergedReports(cwd, outputDir, {
206
- projectName,
280
+ const options = {
281
+ projectSlug,
207
282
  runId,
208
283
  baseUrl,
209
284
  uploadBucket,
210
285
  credentials,
211
- });
286
+ };
287
+ await uploadMergedReports({ uploadOptions: options, outputDir });
212
288
  }
213
289
  else {
214
290
  const storageType = enableS3 ? "S3" : "R2";
@@ -5,7 +5,7 @@ export interface MergeReportsOptions {
5
5
  }
6
6
  import type { StorageCredentials } from "@empiricalrun/r2-uploader";
7
7
  export interface UploadOptions {
8
- projectName: string;
8
+ projectSlug: string;
9
9
  runId: string;
10
10
  baseUrl: string;
11
11
  uploadBucket: string;
@@ -1 +1 @@
1
- {"version":3,"file":"run-all-tests.d.ts","sourceRoot":"","sources":["../../src/lib/run-all-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAQlD,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,eAAe,EACf,cAAc,EACd,WAAW,EACX,YAAY,GACb,EAAE;IACD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B,GAAG,YAAY,CAsBf"}
1
+ {"version":3,"file":"run-all-tests.d.ts","sourceRoot":"","sources":["../../src/lib/run-all-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAQlD,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,eAAe,EACf,cAAc,EACd,WAAW,EACX,YAAY,GACb,EAAE;IACD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B,GAAG,YAAY,CAgCf"}
@@ -11,17 +11,23 @@ function runAllTestsCmd({ projects, passthroughArgs, patternsToGrep, filesFilter
11
11
  const projectsArg = (projects || [])
12
12
  .map((project) => `--project ${project}`)
13
13
  .join(" ");
14
- const grepArgs = (patternsToGrep || [])
15
- .map((pattern) => ` -g "${pattern}"`)
16
- .join(" ");
17
- let args = ` ${filesFilter || ""} ${grepArgs} ${projectsArg} ${passthroughArgs || ""}`;
14
+ let args = ` ${filesFilter || ""} ${projectsArg} ${passthroughArgs || ""}`;
18
15
  const envVars = Object.assign({ ...process.env, PW_TEST_HTML_REPORT_OPEN: "never" }, envOverrides);
19
16
  if (envVars.RUN_PLAYWRIGHT_HEADED === "true") {
20
17
  args = `${args} --headed`;
21
18
  }
22
19
  const testRunCmd = normalizeSpaces(`npx ${testRunner} test ${args}`);
20
+ const parsed = (0, cmd_1.getCommandFromString)(testRunCmd);
21
+ // Multiple `-g` flags collapse to the last one in Playwright's CLI, so OR
22
+ // all patterns into a single regex passed as one `-g` argument. We append
23
+ // this after `getCommandFromString` because that helper re-escapes regex
24
+ // specials inside quoted args, which would clobber the `|` alternation.
25
+ if (patternsToGrep && patternsToGrep.length > 0) {
26
+ const escapedPatterns = patternsToGrep.map((pattern) => pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
27
+ parsed.args.push("-g", escapedPatterns.join("|"));
28
+ }
23
29
  return {
24
- ...(0, cmd_1.getCommandFromString)(testRunCmd),
30
+ ...parsed,
25
31
  env: envVars,
26
32
  };
27
33
  }
@@ -41,8 +41,6 @@ export declare const generateProjectFiltersV2: ({ match, ignore, repoDir, }: {
41
41
  ignore: string[];
42
42
  repoDir: string;
43
43
  }) => Promise<string[]>;
44
- export declare function buildRepoName(projectName: string): string;
45
- export declare const pickNameFromPackageJson: () => Promise<string | undefined>;
46
44
  export declare const downloadBuild: (buildUrl: string) => Promise<void>;
47
45
  export declare const getTestRunner: () => string;
48
46
  export declare const handleTeardownSkipFlag: (directory: string, repoDir: string) => Promise<void>;
@@ -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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"}
@@ -3,7 +3,7 @@ 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.handleTeardownSkipFlag = exports.getTestRunner = exports.downloadBuild = exports.pickNameFromPackageJson = exports.generateProjectFiltersV2 = exports.generateProjectFilters = exports.filterArrayByGlobMatchersSet = exports.getTestModuleAliasFromSourceFile = void 0;
6
+ exports.handleTeardownSkipFlag = exports.getTestRunner = exports.downloadBuild = exports.generateProjectFiltersV2 = exports.generateProjectFilters = exports.filterArrayByGlobMatchersSet = exports.getTestModuleAliasFromSourceFile = void 0;
7
7
  exports.getAllFilePaths = getAllFilePaths;
8
8
  exports.getTestCaseNode = getTestCaseNode;
9
9
  exports.hasTestBlock = hasTestBlock;
@@ -12,7 +12,6 @@ exports.findFirstSerialDescribeBlock = findFirstSerialDescribeBlock;
12
12
  exports.hasTopLevelDescribeConfigureWithSerialMode = hasTopLevelDescribeConfigureWithSerialMode;
13
13
  exports.markTestAsOnly = markTestAsOnly;
14
14
  exports.labelTeardownProjects = labelTeardownProjects;
15
- exports.buildRepoName = buildRepoName;
16
15
  exports.getTypescriptTestBlock = getTypescriptTestBlock;
17
16
  const fs_1 = require("fs");
18
17
  const promises_1 = __importDefault(require("fs/promises"));
@@ -207,16 +206,6 @@ const generateProjectFiltersV2 = async ({ match, ignore, repoDir, }) => {
207
206
  return filteredProjects;
208
207
  };
209
208
  exports.generateProjectFiltersV2 = generateProjectFiltersV2;
210
- function buildRepoName(projectName) {
211
- return `${projectName}-tests`;
212
- }
213
- const pickNameFromPackageJson = async () => {
214
- const packageJSONPath = "package.json";
215
- const packageJsonStr = await promises_1.default.readFile(packageJSONPath, "utf-8");
216
- const packageJSONData = JSON.parse(packageJsonStr);
217
- return packageJSONData.name && packageJSONData.name.replace("-tests", "");
218
- };
219
- exports.pickNameFromPackageJson = pickNameFromPackageJson;
220
209
  const downloadBuild = async (buildUrl) => {
221
210
  const packageJSONPath = "package.json";
222
211
  const packageJsonStr = await promises_1.default.readFile(packageJSONPath, "utf-8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-run",
3
- "version": "0.16.1",
3
+ "version": "0.17.1",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -37,21 +37,21 @@
37
37
  "minimatch": "^10.0.1",
38
38
  "ts-morph": "^23.0.0",
39
39
  "@empiricalrun/r2-uploader": "^0.9.1",
40
- "@empiricalrun/reporter": "^0.28.1"
40
+ "@empiricalrun/reporter": "^0.29.1"
41
41
  },
42
42
  "devDependencies": {
43
- "@playwright/test": "1.57.0",
43
+ "@playwright/test": "1.60.0",
44
44
  "@types/async-retry": "^1.4.8",
45
45
  "@types/js-yaml": "^4.0.9",
46
46
  "@types/console-log-level": "^1.4.5",
47
47
  "@types/node": "^22.5.5",
48
48
  "memfs": "^4.17.1",
49
- "@empiricalrun/shared-types": "0.12.1"
49
+ "@empiricalrun/shared-types": "0.14.0"
50
50
  },
51
51
  "scripts": {
52
52
  "dev": "tsc --build --watch",
53
53
  "build": "tsc --build",
54
- "clean": "tsc --build --clean",
54
+ "clean": "rm -rf dist && tsc --build --clean",
55
55
  "lint": "biome check --unsafe",
56
56
  "test": "vitest run",
57
57
  "test:watch": "vitest"
@@ -1 +1 @@
1
- {"root":["./src/cmd.ts","./src/dashboard.ts","./src/env-files.ts","./src/failed-test-list.ts","./src/glob-matcher.ts","./src/index.ts","./src/logger.ts","./src/bin/index.ts","./src/bin/commands/estimate-time-shard.ts","./src/bin/commands/failed-list.ts","./src/bin/commands/merge.ts","./src/bin/commands/optimize-shards.ts","./src/bin/commands/run.ts","./src/lib/cancellation-watcher.ts","./src/lib/cmd.ts","./src/lib/run-all-tests.ts","./src/lib/run-specific-test.ts","./src/lib/memfs/read-hello-world.ts","./src/lib/merge-reports/html.ts","./src/lib/merge-reports/index.ts","./src/lib/merge-reports/json.ts","./src/lib/merge-reports/types.ts","./src/stdout-parser/index.ts","./src/types/index.ts","./src/utils/config-parser.ts","./src/utils/config.ts","./src/utils/index.ts"],"version":"5.8.3"}
1
+ {"root":["./src/cmd.ts","./src/dashboard.ts","./src/env-files.ts","./src/failed-test-list.ts","./src/glob-matcher.ts","./src/index.ts","./src/logger.ts","./src/bin/index.ts","./src/bin/commands/failed-list.ts","./src/bin/commands/merge.ts","./src/bin/commands/run.ts","./src/lib/cmd.ts","./src/lib/run-all-tests.ts","./src/lib/run-specific-test.ts","./src/lib/memfs/read-hello-world.ts","./src/lib/merge-reports/html.ts","./src/lib/merge-reports/index.ts","./src/lib/merge-reports/json.ts","./src/lib/merge-reports/types.ts","./src/stdout-parser/index.ts","./src/types/index.ts","./src/utils/config-parser.ts","./src/utils/config.ts","./src/utils/index.ts"],"version":"5.8.3"}
@@ -1,3 +0,0 @@
1
- import type { Command } from "commander";
2
- export declare function registerEstimateTimeShardCommand(program: Command): void;
3
- //# sourceMappingURL=estimate-time-shard.d.ts.map