@nsxbet/playwright-orchestrator 0.6.1 → 0.6.2

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/README.md CHANGED
@@ -6,12 +6,12 @@ Intelligent Playwright test distribution across CI shards using historical timin
6
6
 
7
7
  Default Playwright sharding (`--shard=N/M`) distributes tests by **file count**, not by duration. This creates significant imbalance:
8
8
 
9
- | Shard | Duration | vs Fastest |
10
- |-------|----------|------------|
11
- | Shard 1 | ~31 min | +182% |
12
- | Shard 2 | ~15 min | +36% |
13
- | Shard 3 | ~22 min | +100% |
14
- | Shard 4 | ~11 min | baseline |
9
+ | Shard | Duration | vs Fastest |
10
+ | ------- | -------- | ---------- |
11
+ | Shard 1 | ~31 min | +182% |
12
+ | Shard 2 | ~15 min | +36% |
13
+ | Shard 3 | ~22 min | +100% |
14
+ | Shard 4 | ~11 min | baseline |
15
15
 
16
16
  Your CI is bottlenecked by the slowest shard, wasting runner time.
17
17
 
@@ -75,13 +75,10 @@ playwright-orchestrator merge-timing \
75
75
  Add the reporter to your `playwright.config.ts`:
76
76
 
77
77
  ```typescript
78
- import { defineConfig } from '@playwright/test';
78
+ import { defineConfig } from "@playwright/test";
79
79
 
80
80
  export default defineConfig({
81
- reporter: [
82
- ['@nsxbet/playwright-orchestrator/reporter'],
83
- ['html'],
84
- ],
81
+ reporter: [["@nsxbet/playwright-orchestrator/reporter"], ["html"]],
85
82
  });
86
83
  ```
87
84
 
@@ -110,6 +107,8 @@ Use the orchestrator in your own repository. The recommended pattern runs orches
110
107
 
111
108
  **Important**: Use `npx playwright test --list --reporter=json` to generate the test list. This ensures accurate discovery of parameterized tests (`test.each`) and avoids mismatches between discovered and actual tests.
112
109
 
110
+ **Monorepo Note**: In monorepos, generate the test list from the same directory where tests run (where `playwright.config.ts` lives). See [Monorepo Usage](./docs/external-integration.md#monorepo-usage) for details.
111
+
113
112
  ```yaml
114
113
  jobs:
115
114
  # Phase 1: Orchestrate (runs once)
@@ -119,12 +118,12 @@ jobs:
119
118
  shard-files: ${{ steps.orchestrate.outputs.shard-files }}
120
119
  steps:
121
120
  - uses: actions/checkout@v4
122
-
121
+
123
122
  - uses: actions/setup-node@v4
124
123
  with:
125
124
  node-version: 20
126
125
  cache: npm
127
-
126
+
128
127
  - run: npm ci
129
128
 
130
129
  - uses: NSXBet/playwright-orchestrator/.github/actions/setup-orchestrator@v0
@@ -136,14 +135,15 @@ jobs:
136
135
  key: playwright-timing-${{ github.ref_name }}
137
136
  restore-keys: playwright-timing-
138
137
 
139
- # IMPORTANT: Generate test list with Playwright for accurate discovery
138
+ # IMPORTANT: Generate test list from the directory where tests run
139
+ # In monorepos, use working-directory to match where playwright.config.ts lives
140
140
  - run: npx playwright test --list --reporter=json > test-list.json
141
141
 
142
142
  # Action handles all orchestration logic
143
143
  - uses: NSXBet/playwright-orchestrator/.github/actions/orchestrate@v0
144
144
  id: orchestrate
145
145
  with:
146
- test-list: test-list.json # Use pre-generated list (recommended)
146
+ test-list: test-list.json # Use pre-generated list (recommended)
147
147
  shards: 4
148
148
  timing-file: timing-data.json
149
149
 
@@ -176,12 +176,12 @@ See [docs/external-integration.md](./docs/external-integration.md) for complete
176
176
 
177
177
  ## CLI Commands
178
178
 
179
- | Command | Description |
180
- |---------|-------------|
181
- | `list-tests` | Discover tests in a project (uses Playwright `--list`) |
182
- | `assign` | Distribute tests across shards (uses Playwright `--list` for accurate discovery) |
183
- | `extract-timing` | Extract timing from Playwright report |
184
- | `merge-timing` | Merge timing data with EMA smoothing |
179
+ | Command | Description |
180
+ | ---------------- | -------------------------------------------------------------------------------- |
181
+ | `list-tests` | Discover tests in a project (uses Playwright `--list`) |
182
+ | `assign` | Distribute tests across shards (uses Playwright `--list` for accurate discovery) |
183
+ | `extract-timing` | Extract timing from Playwright report |
184
+ | `merge-timing` | Merge timing data with EMA smoothing |
185
185
 
186
186
  Run `playwright-orchestrator <command> --help` for details.
187
187
 
@@ -205,6 +205,34 @@ make build
205
205
  make act-test
206
206
  ```
207
207
 
208
+ ## E2E Testing
209
+
210
+ The repository includes comprehensive E2E tests that simulate real-world monorepo usage:
211
+
212
+ ```bash
213
+ # Run E2E monorepo workflow with Act
214
+ make act-e2e-monorepo
215
+ ```
216
+
217
+ The E2E workflow (`e2e-monorepo.yml`) tests the complete orchestration cycle:
218
+
219
+ 1. **setup**: Build package, create tarball artifact
220
+ 2. **orchestrate**: Use real `orchestrate` action to assign tests
221
+ 3. **e2e-tests** (matrix): Use `get-shard` and `extract-timing` actions
222
+ 4. **merge**: Use `merge-timing` action to combine timing data
223
+
224
+ **Note**: Publish validation is handled separately in CI via the `test-publish` job (Verdaccio).
225
+
226
+ Test scenarios covered in `examples/monorepo/`:
227
+
228
+ - Path normalization (orchestrate from root, run from subdirectory)
229
+ - Parameterized tests (`test.each` patterns)
230
+ - Nested describe blocks (4+ levels deep)
231
+ - Special characters in test names (Unicode, brackets)
232
+ - `::` separator conflicts in test titles
233
+ - Skip patterns (`skip`, `fixme`, `slow`, tags)
234
+ - Deep subdirectory paths
235
+
208
236
  See [AGENTS.md](./AGENTS.md) for AI assistant instructions.
209
237
 
210
238
  ## License
@@ -3,6 +3,7 @@ export * from './estimate.js';
3
3
  export * from './lpt-algorithm.js';
4
4
  export * from './slugify.js';
5
5
  export * from './test-discovery.js';
6
+ export * from './test-id.js';
6
7
  export * from './timing-store.js';
7
8
  export * from './types.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC"}
@@ -3,6 +3,7 @@ export * from './estimate.js';
3
3
  export * from './lpt-algorithm.js';
4
4
  export * from './slugify.js';
5
5
  export * from './test-discovery.js';
6
+ export * from './test-id.js';
6
7
  export * from './timing-store.js';
7
8
  export * from './types.js';
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"test-discovery.d.ts","sourceRoot":"","sources":["../../src/core/test-discovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,YAAY,CAAC;AAGpB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAGvE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,EAAE,CAyBlB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,GACjB,cAAc,EAAE,CA2BlB;AAsED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,MAAuB,GACnC,cAAc,EAAE,CAgBlB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,cAAc,EAAE,CAkElB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EAAE,GACtB,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAU/B"}
1
+ {"version":3,"file":"test-discovery.d.ts","sourceRoot":"","sources":["../../src/core/test-discovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,YAAY,CAAC;AAGpB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAGvE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,EAAE,CAyBlB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,GACjB,cAAc,EAAE,CA2BlB;AA0ED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,MAAuB,GACnC,cAAc,EAAE,CAgBlB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,cAAc,EAAE,CAkElB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EAAE,GACtB,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAU/B"}
@@ -113,22 +113,26 @@ function extractTestsFromSuite(suite, parentTitles, tests, rootDir, isRootSuite
113
113
  }
114
114
  }
115
115
  /**
116
- * Resolve file path to be relative to CWD
116
+ * Resolve file path to be relative to rootDir (Playwright's testDir/config dir)
117
117
  *
118
118
  * Playwright JSON output may contain:
119
119
  * - Just filename (relative to rootDir): "account.spec.ts"
120
120
  * - Full absolute path: "/Users/.../src/test/e2e/account.spec.ts"
121
121
  *
122
- * We need to return path relative to CWD for consistency with reporter.
122
+ * We return paths relative to rootDir for consistency.
123
+ * This ensures test IDs match between:
124
+ * - Orchestrator (running from repo root, reading test-list.json)
125
+ * - Fixture (running from subdirectory where tests live)
126
+ *
127
+ * Both will generate paths like "src/test/e2e/login.spec.ts" regardless of CWD.
123
128
  */
124
129
  function resolveFilePath(filePath, rootDir) {
125
- // If it's already an absolute path, make it relative to CWD
130
+ // If it's already an absolute path, make it relative to rootDir
126
131
  if (path.isAbsolute(filePath)) {
127
- return path.relative(process.cwd(), filePath).replace(/\\/g, '/');
132
+ return path.relative(rootDir, filePath).replace(/\\/g, '/');
128
133
  }
129
- // If it's just a filename, resolve it from rootDir then make relative to CWD
130
- const absolutePath = path.resolve(rootDir, filePath);
131
- return path.relative(process.cwd(), absolutePath).replace(/\\/g, '/');
134
+ // If it's a relative path already (relative to rootDir), just normalize it
135
+ return filePath.replace(/\\/g, '/');
132
136
  }
133
137
  /**
134
138
  * Discover tests by scanning test files directly (fallback method)
@@ -1 +1 @@
1
- {"version":3,"file":"test-discovery.js","sourceRoot":"","sources":["../../src/core/test-discovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-discovery.js","sourceRoot":"","sources":["../../src/core/test-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Test ID Generation Module
3
+ *
4
+ * This module provides shared functions for generating consistent test IDs
5
+ * across all orchestrator components (fixture, reporter).
6
+ *
7
+ * CRITICAL: All components MUST use these shared functions to ensure
8
+ * test IDs match between shard assignment and runtime filtering.
9
+ *
10
+ * There are two contexts for test ID generation:
11
+ * 1. Discovery context: Uses buildTestId from types.ts (data from Playwright JSON)
12
+ * 2. Runtime context: Uses buildTestIdFromRuntime (data from testInfo.titlePath)
13
+ *
14
+ * @module @nsxbet/playwright-orchestrator/core/test-id
15
+ */
16
+ /**
17
+ * Options for filtering runtime titlePath
18
+ */
19
+ export interface FilterTitlePathOptions {
20
+ /** Playwright project name to exclude from titlePath */
21
+ projectName?: string;
22
+ /** File name (basename) to exclude from titlePath */
23
+ fileName?: string;
24
+ }
25
+ /**
26
+ * Filter titlePath from Playwright runtime (testInfo.titlePath) to get only
27
+ * describe blocks and test title.
28
+ *
29
+ * Playwright's runtime titlePath includes:
30
+ * - Project name (e.g., "chromium")
31
+ * - File path or filename
32
+ * - Describe block titles
33
+ * - Test title
34
+ *
35
+ * This function removes non-meaningful elements to produce a clean titlePath
36
+ * that matches what test-discovery produces from Playwright's JSON output.
37
+ *
38
+ * @param titlePath - Raw titlePath from testInfo.titlePath or test.titlePath()
39
+ * @param options - Options for filtering
40
+ * @returns Filtered titlePath containing only describe blocks and test title
41
+ */
42
+ export declare function filterRuntimeTitlePath(titlePath: string[], options?: FilterTitlePathOptions): string[];
43
+ /**
44
+ * Options for building a test ID from runtime data
45
+ */
46
+ export interface BuildTestIdFromRuntimeOptions {
47
+ /** Playwright project name to exclude from titlePath */
48
+ projectName?: string;
49
+ /** Base directory for relative path resolution (testDir or rootDir) */
50
+ baseDir?: string;
51
+ }
52
+ /**
53
+ * Build a test ID from Playwright runtime data (fixture or reporter context).
54
+ *
55
+ * This function:
56
+ * 1. Converts the absolute file path to relative (using baseDir or cwd)
57
+ * 2. Filters the titlePath to remove project name, filename, and file paths
58
+ * 3. Joins file and filtered titles with "::"
59
+ *
60
+ * The resulting test ID format: {relative-file}::{describe1}::{describe2}::{testTitle}
61
+ *
62
+ * @param filePath - Absolute path to the test file (testInfo.file or test.location.file)
63
+ * @param titlePath - Raw titlePath from testInfo.titlePath or test.titlePath()
64
+ * @param options - Options for path resolution and filtering
65
+ * @returns Test ID string
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const testId = buildTestIdFromRuntime(
70
+ * '/project/e2e/login.spec.ts',
71
+ * ['chromium', 'login.spec.ts', 'Login', 'should work'],
72
+ * { projectName: 'chromium', baseDir: '/project' }
73
+ * );
74
+ * // Result: 'e2e/login.spec.ts::Login::should work'
75
+ * ```
76
+ */
77
+ export declare function buildTestIdFromRuntime(filePath: string, titlePath: string[], options?: BuildTestIdFromRuntimeOptions): string;
78
+ //# sourceMappingURL=test-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-id.d.ts","sourceRoot":"","sources":["../../src/core/test-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,GAAE,sBAA2B,GACnC,MAAM,EAAE,CAsBV;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,GAAE,6BAAkC,GAC1C,MAAM,CAgBR"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Test ID Generation Module
3
+ *
4
+ * This module provides shared functions for generating consistent test IDs
5
+ * across all orchestrator components (fixture, reporter).
6
+ *
7
+ * CRITICAL: All components MUST use these shared functions to ensure
8
+ * test IDs match between shard assignment and runtime filtering.
9
+ *
10
+ * There are two contexts for test ID generation:
11
+ * 1. Discovery context: Uses buildTestId from types.ts (data from Playwright JSON)
12
+ * 2. Runtime context: Uses buildTestIdFromRuntime (data from testInfo.titlePath)
13
+ *
14
+ * @module @nsxbet/playwright-orchestrator/core/test-id
15
+ */
16
+ import * as path from 'node:path';
17
+ /**
18
+ * Filter titlePath from Playwright runtime (testInfo.titlePath) to get only
19
+ * describe blocks and test title.
20
+ *
21
+ * Playwright's runtime titlePath includes:
22
+ * - Project name (e.g., "chromium")
23
+ * - File path or filename
24
+ * - Describe block titles
25
+ * - Test title
26
+ *
27
+ * This function removes non-meaningful elements to produce a clean titlePath
28
+ * that matches what test-discovery produces from Playwright's JSON output.
29
+ *
30
+ * @param titlePath - Raw titlePath from testInfo.titlePath or test.titlePath()
31
+ * @param options - Options for filtering
32
+ * @returns Filtered titlePath containing only describe blocks and test title
33
+ */
34
+ export function filterRuntimeTitlePath(titlePath, options = {}) {
35
+ const { projectName, fileName } = options;
36
+ return titlePath.filter((title) => {
37
+ // Filter empty strings
38
+ if (!title || title === '')
39
+ return false;
40
+ // Filter project name
41
+ if (projectName && title === projectName)
42
+ return false;
43
+ // Filter filename
44
+ if (fileName && title === fileName)
45
+ return false;
46
+ // Filter out file paths (contain / or \)
47
+ if (title.includes('/') || title.includes('\\'))
48
+ return false;
49
+ // Filter out spec/test file extensions
50
+ if (title.endsWith('.spec.ts') || title.endsWith('.test.ts'))
51
+ return false;
52
+ if (title.endsWith('.spec.js') || title.endsWith('.test.js'))
53
+ return false;
54
+ return true;
55
+ });
56
+ }
57
+ /**
58
+ * Build a test ID from Playwright runtime data (fixture or reporter context).
59
+ *
60
+ * This function:
61
+ * 1. Converts the absolute file path to relative (using baseDir or cwd)
62
+ * 2. Filters the titlePath to remove project name, filename, and file paths
63
+ * 3. Joins file and filtered titles with "::"
64
+ *
65
+ * The resulting test ID format: {relative-file}::{describe1}::{describe2}::{testTitle}
66
+ *
67
+ * @param filePath - Absolute path to the test file (testInfo.file or test.location.file)
68
+ * @param titlePath - Raw titlePath from testInfo.titlePath or test.titlePath()
69
+ * @param options - Options for path resolution and filtering
70
+ * @returns Test ID string
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const testId = buildTestIdFromRuntime(
75
+ * '/project/e2e/login.spec.ts',
76
+ * ['chromium', 'login.spec.ts', 'Login', 'should work'],
77
+ * { projectName: 'chromium', baseDir: '/project' }
78
+ * );
79
+ * // Result: 'e2e/login.spec.ts::Login::should work'
80
+ * ```
81
+ */
82
+ export function buildTestIdFromRuntime(filePath, titlePath, options = {}) {
83
+ const { projectName, baseDir = process.cwd() } = options;
84
+ // Convert absolute path to relative
85
+ const file = path.relative(baseDir, filePath).replace(/\\/g, '/');
86
+ // Get filename for filtering
87
+ const fileName = path.basename(filePath);
88
+ // Filter titlePath
89
+ const filteredTitles = filterRuntimeTitlePath(titlePath, {
90
+ projectName,
91
+ fileName,
92
+ });
93
+ return [file, ...filteredTitles].join('::');
94
+ }
95
+ //# sourceMappingURL=test-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-id.js","sourceRoot":"","sources":["../../src/core/test-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAYlC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CACpC,SAAmB,EACnB,UAAkC,EAAE;IAEpC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE1C,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAChC,uBAAuB;QACvB,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;QAEzC,sBAAsB;QACtB,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW;YAAE,OAAO,KAAK,CAAC;QAEvD,kBAAkB;QAClB,IAAI,QAAQ,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAEjD,yCAAyC;QACzC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAE9D,uCAAuC;QACvC,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3E,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QAE3E,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAYD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAgB,EAChB,SAAmB,EACnB,UAAyC,EAAE;IAE3C,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAEzD,oCAAoC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAElE,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzC,mBAAmB;IACnB,MAAM,cAAc,GAAG,sBAAsB,CAAC,SAAS,EAAE;QACvD,WAAW;QACX,QAAQ;KACT,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9C,CAAC"}
package/dist/fixture.d.ts CHANGED
@@ -38,6 +38,7 @@ export declare function shouldRunTest(testInfo: {
38
38
  titlePath: string[];
39
39
  project: {
40
40
  name: string;
41
+ testDir?: string;
41
42
  };
42
43
  }): boolean;
43
44
  //# sourceMappingURL=fixture.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fixture.d.ts","sourceRoot":"","sources":["../src/fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAmDjD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EACxE,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GACnB,IAAI,CAoBN;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3B,GAAG,OAAO,CAWV"}
1
+ {"version":3,"file":"fixture.d.ts","sourceRoot":"","sources":["../src/fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAuDjD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EACxE,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GACnB,IAAI,CA0BN;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C,GAAG,OAAO,CAUV"}
package/dist/fixture.js CHANGED
@@ -19,7 +19,11 @@
19
19
  * @module @nsxbet/playwright-orchestrator/fixture
20
20
  */
21
21
  import * as fs from 'node:fs';
22
- import * as path from 'node:path';
22
+ import { buildTestIdFromRuntime } from './core/test-id.js';
23
+ // Module initialization debug - only in debug mode
24
+ if (process.env.ORCHESTRATOR_DEBUG === '1') {
25
+ process.stderr.write('[Fixture Module] Loading orchestrator fixture\n');
26
+ }
23
27
  // Cache the shard file to avoid re-reading on every test
24
28
  let cachedAllowedTestIds = null;
25
29
  let cacheInitialized = false;
@@ -35,9 +39,18 @@ function loadShardFile() {
35
39
  return null;
36
40
  }
37
41
  try {
38
- const testIds = JSON.parse(fs.readFileSync(shardFile, 'utf-8'));
42
+ const parsed = JSON.parse(fs.readFileSync(shardFile, 'utf-8'));
43
+ // Validate shard file format
44
+ if (!Array.isArray(parsed) ||
45
+ !parsed.every((id) => typeof id === 'string')) {
46
+ throw new Error('[Orchestrator] Shard file must be a JSON array of strings');
47
+ }
48
+ const testIds = parsed;
39
49
  cachedAllowedTestIds = new Set(testIds);
40
- console.log(`[Orchestrator] Loaded ${cachedAllowedTestIds.size} tests for this shard`);
50
+ if (process.env.ORCHESTRATOR_DEBUG === '1') {
51
+ process.stderr.write(`[Orchestrator] Loaded ${testIds.length} tests for this shard\n`);
52
+ process.stderr.write(`[Orchestrator] Sample IDs: ${testIds.slice(0, 3).join(' | ')}\n`);
53
+ }
41
54
  return cachedAllowedTestIds;
42
55
  }
43
56
  catch (error) {
@@ -45,21 +58,6 @@ function loadShardFile() {
45
58
  throw error;
46
59
  }
47
60
  }
48
- function buildTestId(filePath, titlePath, projectName) {
49
- const file = path.relative(process.cwd(), filePath).replace(/\\/g, '/');
50
- const fileName = path.basename(filePath);
51
- // Filter titlePath to exclude project name, filename, and empty strings
52
- const filteredTitles = titlePath.filter((title) => {
53
- if (!title || title === '')
54
- return false;
55
- if (title === projectName)
56
- return false;
57
- if (title === fileName)
58
- return false;
59
- return true;
60
- });
61
- return [file, ...filteredTitles].join('::');
62
- }
63
61
  /**
64
62
  * Sets up the orchestrator filter as a beforeEach hook.
65
63
  * This will skip tests that are not in the current shard.
@@ -71,11 +69,17 @@ export function setupOrchestratorFilter(test) {
71
69
  test.beforeEach(async ({}, testInfo) => {
72
70
  const allowedTestIds = loadShardFile();
73
71
  if (allowedTestIds) {
74
- const testId = buildTestId(testInfo.file, testInfo.titlePath, testInfo.project.name);
75
- if (!allowedTestIds.has(testId)) {
76
- if (process.env.ORCHESTRATOR_DEBUG === '1') {
77
- console.log(`[Orchestrator Skip] ${testId}`);
78
- }
72
+ // Use project.testDir for consistent path resolution with test-discovery
73
+ const testId = buildTestIdFromRuntime(testInfo.file, testInfo.titlePath, {
74
+ projectName: testInfo.project.name,
75
+ baseDir: testInfo.project.testDir,
76
+ });
77
+ const isAllowed = allowedTestIds.has(testId);
78
+ // Debug: Write to stderr for visibility in CI logs
79
+ if (process.env.ORCHESTRATOR_DEBUG === '1') {
80
+ process.stderr.write(`[Fixture] testDir=${testInfo.project.testDir} | testId=${testId} | allowed=${isAllowed}\n`);
81
+ }
82
+ if (!isAllowed) {
79
83
  test.skip(true, 'Not in shard');
80
84
  }
81
85
  }
@@ -92,7 +96,10 @@ export function shouldRunTest(testInfo) {
92
96
  const allowedTestIds = loadShardFile();
93
97
  if (!allowedTestIds)
94
98
  return true;
95
- const testId = buildTestId(testInfo.file, testInfo.titlePath, testInfo.project.name);
99
+ const testId = buildTestIdFromRuntime(testInfo.file, testInfo.titlePath, {
100
+ projectName: testInfo.project.name,
101
+ baseDir: testInfo.project.testDir,
102
+ });
96
103
  return allowedTestIds.has(testId);
97
104
  }
98
105
  //# sourceMappingURL=fixture.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fixture.js","sourceRoot":"","sources":["../src/fixture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fixture.js","sourceRoot":"","sources":["../src/fixture.ts"],"names":[],"mappings":"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"}
@@ -1,43 +1,63 @@
1
1
  /**
2
2
  * Playwright Orchestrator Reporter
3
3
  *
4
- * A custom Playwright reporter that filters tests based on a JSON file
5
- * containing test IDs. Uses exact Set.has() matching to avoid substring
6
- * collisions that plague --grep approaches.
4
+ * A custom Playwright reporter that provides clean output for sharded tests.
5
+ * Shows only tests assigned to the current shard, with proper counts and summaries.
6
+ *
7
+ * Features:
8
+ * - Correct "Running X tests" count (only shard tests, not total)
9
+ * - Clean output showing only shard tests (no skipped noise)
10
+ * - Debug mode to see filtered tests
11
+ * - Compatible with other reporters (json, html)
7
12
  *
8
13
  * Usage:
9
14
  * 1. Add to playwright.config.ts:
10
- * reporter: [['@nsxbet/playwright-orchestrator/reporter'], ['html']]
15
+ * reporter: [['@nsxbet/playwright-orchestrator/reporter'], ['json', {...}]]
11
16
  * 2. Set ORCHESTRATOR_SHARD_FILE env var to path of JSON file with test IDs
12
17
  *
13
18
  * Environment variables:
14
19
  * - ORCHESTRATOR_SHARD_FILE: Path to JSON file with array of test IDs
15
- * - ORCHESTRATOR_DEBUG: Set to "1" to enable debug logging
16
- *
17
- * @example
18
- * // shard.json
19
- * ["e2e/login.spec.ts::Login::should login", "e2e/home.spec.ts::Home::should render"]
20
- *
21
- * // Run with filtering
22
- * ORCHESTRATOR_SHARD_FILE=shard.json npx playwright test
20
+ * - ORCHESTRATOR_DEBUG: Set to "1" to show filtered tests
23
21
  *
24
22
  * @module @nsxbet/playwright-orchestrator/reporter
25
23
  */
26
- import type { FullConfig, Reporter, Suite, TestCase } from '@playwright/test/reporter';
24
+ import type { FullConfig, FullResult, Reporter, Suite, TestCase, TestResult } from '@playwright/test/reporter';
27
25
  export default class OrchestratorReporter implements Reporter {
28
26
  private allowedTestIds;
29
27
  private debug;
30
- onBegin(_config: FullConfig, _suite: Suite): void;
31
- onTestBegin(test: TestCase): void;
28
+ private startTime;
29
+ private rootDir;
30
+ private passed;
31
+ private failed;
32
+ private skipped;
33
+ private filtered;
34
+ onBegin(config: FullConfig, suite: Suite): void;
35
+ onTestEnd(test: TestCase, result: TestResult): void;
36
+ onEnd(_result: FullResult): void;
37
+ /**
38
+ * Print a test result line
39
+ */
40
+ private printTestResult;
41
+ /**
42
+ * Print a filtered test (debug mode only)
43
+ */
44
+ private printFiltered;
45
+ /**
46
+ * Get display title for a test (file > describe > test)
47
+ */
48
+ private getDisplayTitle;
49
+ /**
50
+ * Filter titlePath to get only describe blocks and test title.
51
+ * Uses shared filterRuntimeTitlePath function for consistency.
52
+ */
53
+ private getFilteredTitles;
54
+ /**
55
+ * Format duration in human readable format
56
+ */
57
+ private formatDuration;
32
58
  /**
33
59
  * Build test ID from TestCase.
34
- * Format: {relative-file}::{describe}::{test-title}
35
- *
36
- * This must match the format generated by the orchestrator.
37
- *
38
- * Note: titlePath() returns [projectName?, fileName, ...describes, testTitle]
39
- * We need to filter out projectName and fileName since we already have
40
- * the full relative file path.
60
+ * Uses shared buildTestIdFromRuntime function for consistency with fixture.
41
61
  */
42
62
  private buildTestId;
43
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACT,MAAM,2BAA2B,CAAC;AAEnC,MAAM,CAAC,OAAO,OAAO,oBAAqB,YAAW,QAAQ;IAC3D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,KAAK,CAA0C;IAEvD,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK;IAsB1C,WAAW,CAAC,IAAI,EAAE,QAAQ;IAa1B;;;;;;;;;OASG;IACH,OAAO,CAAC,WAAW;CAsBpB"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AA0BnC,MAAM,CAAC,OAAO,OAAO,oBAAqB,YAAW,QAAQ;IAC3D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,KAAK,CAA0C;IACvD,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,OAAO,CAAM;IAGrB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAK;IAErB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK;IAsCxC,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU;IAsB5C,KAAK,CAAC,OAAO,EAAE,UAAU;IA0BzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAsCvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAKrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;;OAGG;IACH,OAAO,CAAC,WAAW;CASpB"}
package/dist/reporter.js CHANGED
@@ -1,94 +1,217 @@
1
1
  /**
2
2
  * Playwright Orchestrator Reporter
3
3
  *
4
- * A custom Playwright reporter that filters tests based on a JSON file
5
- * containing test IDs. Uses exact Set.has() matching to avoid substring
6
- * collisions that plague --grep approaches.
4
+ * A custom Playwright reporter that provides clean output for sharded tests.
5
+ * Shows only tests assigned to the current shard, with proper counts and summaries.
6
+ *
7
+ * Features:
8
+ * - Correct "Running X tests" count (only shard tests, not total)
9
+ * - Clean output showing only shard tests (no skipped noise)
10
+ * - Debug mode to see filtered tests
11
+ * - Compatible with other reporters (json, html)
7
12
  *
8
13
  * Usage:
9
14
  * 1. Add to playwright.config.ts:
10
- * reporter: [['@nsxbet/playwright-orchestrator/reporter'], ['html']]
15
+ * reporter: [['@nsxbet/playwright-orchestrator/reporter'], ['json', {...}]]
11
16
  * 2. Set ORCHESTRATOR_SHARD_FILE env var to path of JSON file with test IDs
12
17
  *
13
18
  * Environment variables:
14
19
  * - ORCHESTRATOR_SHARD_FILE: Path to JSON file with array of test IDs
15
- * - ORCHESTRATOR_DEBUG: Set to "1" to enable debug logging
16
- *
17
- * @example
18
- * // shard.json
19
- * ["e2e/login.spec.ts::Login::should login", "e2e/home.spec.ts::Home::should render"]
20
- *
21
- * // Run with filtering
22
- * ORCHESTRATOR_SHARD_FILE=shard.json npx playwright test
20
+ * - ORCHESTRATOR_DEBUG: Set to "1" to show filtered tests
23
21
  *
24
22
  * @module @nsxbet/playwright-orchestrator/reporter
25
23
  */
26
24
  import * as fs from 'node:fs';
27
25
  import * as path from 'node:path';
26
+ import { buildTestIdFromRuntime, filterRuntimeTitlePath, } from './core/test-id.js';
27
+ // ANSI color codes
28
+ const colors = {
29
+ green: '\x1b[32m',
30
+ red: '\x1b[31m',
31
+ yellow: '\x1b[33m',
32
+ gray: '\x1b[90m',
33
+ reset: '\x1b[0m',
34
+ bold: '\x1b[1m',
35
+ };
36
+ // Check if colors should be used
37
+ const useColors = process.env.FORCE_COLOR !== '0' &&
38
+ process.env.NO_COLOR === undefined &&
39
+ process.stdout.isTTY;
40
+ function color(code, text) {
41
+ return useColors ? `${colors[code]}${text}${colors.reset}` : text;
42
+ }
28
43
  export default class OrchestratorReporter {
29
44
  allowedTestIds = null;
30
45
  debug = process.env.ORCHESTRATOR_DEBUG === '1';
31
- onBegin(_config, _suite) {
46
+ startTime = 0;
47
+ rootDir = '';
48
+ // Counters for summary
49
+ passed = 0;
50
+ failed = 0;
51
+ skipped = 0;
52
+ filtered = 0;
53
+ onBegin(config, suite) {
54
+ this.startTime = Date.now();
55
+ this.rootDir = config.rootDir;
32
56
  const shardFile = process.env.ORCHESTRATOR_SHARD_FILE;
33
57
  if (!shardFile || !fs.existsSync(shardFile)) {
58
+ // No shard file - let other reporters handle output
34
59
  if (this.debug) {
35
- console.log('[Orchestrator] No shard file, running all tests');
60
+ console.log(color('gray', '[Orchestrator] No shard file, running all tests'));
36
61
  }
37
62
  return;
38
63
  }
39
64
  try {
40
65
  const testIds = JSON.parse(fs.readFileSync(shardFile, 'utf-8'));
41
66
  this.allowedTestIds = new Set(testIds);
42
- console.log(`[Orchestrator] ${this.allowedTestIds.size} tests for this shard`);
67
+ // Count tests
68
+ const allTests = suite.allTests();
69
+ const shardTestCount = this.allowedTestIds.size;
70
+ this.filtered = allTests.length - shardTestCount;
71
+ // Print header
72
+ const workers = config.workers;
73
+ let header = `\nRunning ${color('bold', String(shardTestCount))} tests using ${workers} workers`;
74
+ if (this.debug && this.filtered > 0) {
75
+ header += color('gray', ` (${this.filtered} filtered by orchestrator)`);
76
+ }
77
+ console.log(header);
78
+ console.log('');
43
79
  }
44
80
  catch (error) {
45
81
  console.error('[Orchestrator] Failed to load shard file:', error);
46
82
  throw error;
47
83
  }
48
84
  }
49
- onTestBegin(test) {
85
+ onTestEnd(test, result) {
86
+ const testId = this.buildTestId(test);
87
+ const isInShard = !this.allowedTestIds || this.allowedTestIds.has(testId);
88
+ if (isInShard) {
89
+ // Track stats for shard tests
90
+ if (result.status === 'passed') {
91
+ this.passed++;
92
+ }
93
+ else if (result.status === 'failed' || result.status === 'timedOut') {
94
+ this.failed++;
95
+ }
96
+ else if (result.status === 'skipped') {
97
+ this.skipped++;
98
+ }
99
+ // Print test result
100
+ this.printTestResult(test, result);
101
+ }
102
+ else if (this.debug) {
103
+ // Show filtered tests only in debug mode
104
+ this.printFiltered(test);
105
+ }
106
+ }
107
+ onEnd(_result) {
108
+ // Only print summary if we have a shard file
50
109
  if (!this.allowedTestIds)
51
110
  return;
52
- const testId = this.buildTestId(test);
53
- if (!this.allowedTestIds.has(testId)) {
54
- test.annotations.push({ type: 'skip', description: 'Not in shard' });
55
- if (this.debug) {
56
- console.log(`[Skip] ${testId}`);
111
+ const duration = Date.now() - this.startTime;
112
+ const durationStr = this.formatDuration(duration);
113
+ console.log('');
114
+ // Build summary parts
115
+ const parts = [];
116
+ if (this.passed > 0) {
117
+ parts.push(color('green', `${this.passed} passed`));
118
+ }
119
+ if (this.failed > 0) {
120
+ parts.push(color('red', `${this.failed} failed`));
121
+ }
122
+ if (this.skipped > 0) {
123
+ parts.push(color('yellow', `${this.skipped} skipped`));
124
+ }
125
+ if (parts.length > 0) {
126
+ console.log(` ${parts.join(', ')} ${color('gray', `(${durationStr})`)}`);
127
+ }
128
+ }
129
+ /**
130
+ * Print a test result line
131
+ */
132
+ printTestResult(test, result) {
133
+ const duration = result.duration;
134
+ const durationStr = duration > 0 ? color('gray', ` (${this.formatDuration(duration)})`) : '';
135
+ const titlePath = this.getDisplayTitle(test);
136
+ let status;
137
+ switch (result.status) {
138
+ case 'passed':
139
+ status = color('green', '✓');
140
+ break;
141
+ case 'failed':
142
+ case 'timedOut':
143
+ status = color('red', '✗');
144
+ break;
145
+ case 'skipped':
146
+ status = color('yellow', '-');
147
+ break;
148
+ default:
149
+ status = '?';
150
+ }
151
+ console.log(` ${status} ${titlePath}${durationStr}`);
152
+ // Print error for failed tests
153
+ if (result.status === 'failed' || result.status === 'timedOut') {
154
+ for (const error of result.errors) {
155
+ if (error.message) {
156
+ const lines = error.message.split('\n').slice(0, 3);
157
+ for (const line of lines) {
158
+ console.log(color('red', ` ${line}`));
159
+ }
160
+ }
57
161
  }
58
162
  }
59
163
  }
60
164
  /**
61
- * Build test ID from TestCase.
62
- * Format: {relative-file}::{describe}::{test-title}
63
- *
64
- * This must match the format generated by the orchestrator.
65
- *
66
- * Note: titlePath() returns [projectName?, fileName, ...describes, testTitle]
67
- * We need to filter out projectName and fileName since we already have
68
- * the full relative file path.
165
+ * Print a filtered test (debug mode only)
69
166
  */
70
- buildTestId(test) {
71
- const file = path
72
- .relative(process.cwd(), test.location.file)
73
- .replace(/\\/g, '/');
74
- const fileName = path.basename(test.location.file);
75
- // Filter titlePath to exclude project name, filename, and empty strings
76
- // titlePath typically starts with [projectName, fileName, ...describes, testTitle]
167
+ printFiltered(test) {
168
+ const titlePath = this.getDisplayTitle(test);
169
+ console.log(` ${color('gray', '○')} ${color('gray', titlePath)}`);
170
+ }
171
+ /**
172
+ * Get display title for a test (file > describe > test)
173
+ */
174
+ getDisplayTitle(test) {
175
+ const file = path.basename(test.location.file);
176
+ const filteredTitles = this.getFilteredTitles(test);
177
+ return `${file} > ${filteredTitles.join(' > ')}`;
178
+ }
179
+ /**
180
+ * Filter titlePath to get only describe blocks and test title.
181
+ * Uses shared filterRuntimeTitlePath function for consistency.
182
+ */
183
+ getFilteredTitles(test) {
77
184
  const titlePath = test.titlePath();
78
185
  const projectName = test.parent?.project()?.name;
79
- const filteredTitles = titlePath.filter((title) => {
80
- // Skip empty strings
81
- if (!title || title === '')
82
- return false;
83
- // Skip if it's the project name
84
- if (title === projectName)
85
- return false;
86
- // Skip if it matches the filename
87
- if (title === fileName)
88
- return false;
89
- return true;
186
+ const fileName = path.basename(test.location.file);
187
+ return filterRuntimeTitlePath(titlePath, { projectName, fileName });
188
+ }
189
+ /**
190
+ * Format duration in human readable format
191
+ */
192
+ formatDuration(ms) {
193
+ if (ms < 1000) {
194
+ return `${ms}ms`;
195
+ }
196
+ const seconds = ms / 1000;
197
+ if (seconds < 60) {
198
+ return `${seconds.toFixed(1)}s`;
199
+ }
200
+ const minutes = Math.floor(seconds / 60);
201
+ const remainingSeconds = Math.round(seconds % 60);
202
+ return `${minutes}m ${remainingSeconds}s`;
203
+ }
204
+ /**
205
+ * Build test ID from TestCase.
206
+ * Uses shared buildTestIdFromRuntime function for consistency with fixture.
207
+ */
208
+ buildTestId(test) {
209
+ const testDir = test.parent?.project()?.testDir;
210
+ const baseDir = testDir || this.rootDir || process.cwd();
211
+ return buildTestIdFromRuntime(test.location.file, test.titlePath(), {
212
+ projectName: test.parent?.project()?.name,
213
+ baseDir,
90
214
  });
91
- return [file, ...filteredTitles].join('::');
92
215
  }
93
216
  }
94
217
  //# sourceMappingURL=reporter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nsxbet/playwright-orchestrator",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Intelligent Playwright test distribution across CI shards using historical timing data",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",