@nsxbet/playwright-orchestrator 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +161 -0
  2. package/bin/run.js +5 -0
  3. package/dist/commands/assign.d.ts +23 -0
  4. package/dist/commands/assign.d.ts.map +1 -0
  5. package/dist/commands/assign.js +256 -0
  6. package/dist/commands/assign.js.map +1 -0
  7. package/dist/commands/extract-timing.d.ts +40 -0
  8. package/dist/commands/extract-timing.d.ts.map +1 -0
  9. package/dist/commands/extract-timing.js +196 -0
  10. package/dist/commands/extract-timing.js.map +1 -0
  11. package/dist/commands/list-tests.d.ts +16 -0
  12. package/dist/commands/list-tests.d.ts.map +1 -0
  13. package/dist/commands/list-tests.js +98 -0
  14. package/dist/commands/list-tests.js.map +1 -0
  15. package/dist/commands/merge-timing.d.ts +19 -0
  16. package/dist/commands/merge-timing.d.ts.map +1 -0
  17. package/dist/commands/merge-timing.js +217 -0
  18. package/dist/commands/merge-timing.js.map +1 -0
  19. package/dist/core/ckk-algorithm.d.ts +38 -0
  20. package/dist/core/ckk-algorithm.d.ts.map +1 -0
  21. package/dist/core/ckk-algorithm.js +192 -0
  22. package/dist/core/ckk-algorithm.js.map +1 -0
  23. package/dist/core/estimate.d.ts +72 -0
  24. package/dist/core/estimate.d.ts.map +1 -0
  25. package/dist/core/estimate.js +142 -0
  26. package/dist/core/estimate.js.map +1 -0
  27. package/dist/core/grep-pattern.d.ts +61 -0
  28. package/dist/core/grep-pattern.d.ts.map +1 -0
  29. package/dist/core/grep-pattern.js +104 -0
  30. package/dist/core/grep-pattern.js.map +1 -0
  31. package/dist/core/index.d.ts +9 -0
  32. package/dist/core/index.d.ts.map +1 -0
  33. package/dist/core/index.js +9 -0
  34. package/dist/core/index.js.map +1 -0
  35. package/dist/core/lpt-algorithm.d.ts +28 -0
  36. package/dist/core/lpt-algorithm.d.ts.map +1 -0
  37. package/dist/core/lpt-algorithm.js +80 -0
  38. package/dist/core/lpt-algorithm.js.map +1 -0
  39. package/dist/core/slugify.d.ts +13 -0
  40. package/dist/core/slugify.d.ts.map +1 -0
  41. package/dist/core/slugify.js +19 -0
  42. package/dist/core/slugify.js.map +1 -0
  43. package/dist/core/test-discovery.d.ts +46 -0
  44. package/dist/core/test-discovery.d.ts.map +1 -0
  45. package/dist/core/test-discovery.js +192 -0
  46. package/dist/core/test-discovery.js.map +1 -0
  47. package/dist/core/timing-store.d.ts +90 -0
  48. package/dist/core/timing-store.d.ts.map +1 -0
  49. package/dist/core/timing-store.js +280 -0
  50. package/dist/core/timing-store.js.map +1 -0
  51. package/dist/core/types.d.ts +241 -0
  52. package/dist/core/types.d.ts.map +1 -0
  53. package/dist/core/types.js +54 -0
  54. package/dist/core/types.js.map +1 -0
  55. package/dist/index.d.ts +9 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +9 -0
  58. package/dist/index.js.map +1 -0
  59. package/package.json +70 -0
@@ -0,0 +1,280 @@
1
+ import * as fs from 'node:fs';
2
+ import { createEmptyTimingData, isTimingDataV1, isTimingDataV2, TIMING_DATA_VERSION, TIMING_DATA_VERSION_V1, } from './types.js';
3
+ /**
4
+ * Default EMA smoothing factor (alpha)
5
+ * Higher values give more weight to recent measurements
6
+ */
7
+ export const DEFAULT_EMA_ALPHA = 0.3;
8
+ /**
9
+ * Default number of days after which to prune old entries
10
+ */
11
+ export const DEFAULT_PRUNE_DAYS = 30;
12
+ /**
13
+ * Load timing data from a JSON file
14
+ *
15
+ * Supports both v1 (file-level) and v2 (test-level) formats.
16
+ *
17
+ * @param filePath - Path to the timing data JSON file
18
+ * @returns Timing data, or empty data if file doesn't exist
19
+ */
20
+ export function loadTimingData(filePath) {
21
+ try {
22
+ const content = fs.readFileSync(filePath, 'utf-8');
23
+ const data = JSON.parse(content);
24
+ // Handle v1 format
25
+ if (data.version === TIMING_DATA_VERSION_V1) {
26
+ // Return as-is for backwards compatibility
27
+ return data;
28
+ }
29
+ // Handle v2 format
30
+ if (data.version === TIMING_DATA_VERSION) {
31
+ return data;
32
+ }
33
+ // Unknown version - return empty v2 data
34
+ console.warn(`Timing data version mismatch: expected ${TIMING_DATA_VERSION}, got ${data.version}. Using empty data.`);
35
+ return createEmptyTimingData();
36
+ }
37
+ catch {
38
+ // File doesn't exist or is invalid - return empty data
39
+ return createEmptyTimingData();
40
+ }
41
+ }
42
+ /**
43
+ * Save timing data to a JSON file
44
+ */
45
+ export function saveTimingData(filePath, data) {
46
+ const content = JSON.stringify(data, null, 2);
47
+ fs.writeFileSync(filePath, content, 'utf-8');
48
+ }
49
+ /**
50
+ * Calculate Exponential Moving Average for duration
51
+ *
52
+ * Formula: newDuration = α * measuredDuration + (1 - α) * oldDuration
53
+ *
54
+ * @param oldDuration - Previous duration value
55
+ * @param newDuration - New measured duration
56
+ * @param alpha - Smoothing factor (0-1), higher = more weight on new value
57
+ */
58
+ export function calculateEMA(oldDuration, newDuration, alpha = DEFAULT_EMA_ALPHA) {
59
+ return Math.round(alpha * newDuration + (1 - alpha) * oldDuration);
60
+ }
61
+ /**
62
+ * Merge new timing measurements into existing timing data using EMA (v1 - file-level)
63
+ *
64
+ * @param existing - Existing timing data (v1)
65
+ * @param newMeasurements - New measurements from shard artifacts
66
+ * @param alpha - EMA smoothing factor
67
+ * @returns Updated timing data
68
+ */
69
+ export function mergeTimingData(existing, newMeasurements, alpha = DEFAULT_EMA_ALPHA) {
70
+ const now = new Date().toISOString();
71
+ // Convert v2 to v1 if needed (lossy - just take file names)
72
+ const existingFiles = isTimingDataV1(existing)
73
+ ? existing.files
74
+ : aggregateTestsToFiles(existing);
75
+ const merged = {
76
+ version: TIMING_DATA_VERSION_V1,
77
+ updatedAt: now,
78
+ files: { ...existingFiles },
79
+ };
80
+ for (const artifact of newMeasurements) {
81
+ for (const [file, duration] of Object.entries(artifact.files)) {
82
+ const existingData = merged.files[file];
83
+ if (existingData) {
84
+ // Apply EMA to existing data
85
+ merged.files[file] = {
86
+ duration: calculateEMA(existingData.duration, duration, alpha),
87
+ runs: existingData.runs + 1,
88
+ lastRun: now,
89
+ };
90
+ }
91
+ else {
92
+ // First measurement for this file
93
+ merged.files[file] = {
94
+ duration,
95
+ runs: 1,
96
+ lastRun: now,
97
+ };
98
+ }
99
+ }
100
+ }
101
+ return merged;
102
+ }
103
+ /**
104
+ * Merge new timing measurements into existing timing data using EMA (v2 - test-level)
105
+ *
106
+ * @param existing - Existing timing data (v2)
107
+ * @param newMeasurements - New measurements from shard artifacts
108
+ * @param alpha - EMA smoothing factor
109
+ * @returns Updated timing data
110
+ */
111
+ export function mergeTestTimingData(existing, newMeasurements, alpha = DEFAULT_EMA_ALPHA) {
112
+ const now = new Date().toISOString();
113
+ const merged = {
114
+ version: TIMING_DATA_VERSION,
115
+ updatedAt: now,
116
+ tests: existing ? { ...existing.tests } : {},
117
+ };
118
+ for (const artifact of newMeasurements) {
119
+ for (const [testId, duration] of Object.entries(artifact.tests)) {
120
+ const existingData = merged.tests[testId];
121
+ const file = extractFileFromTestId(testId);
122
+ if (existingData) {
123
+ // Apply EMA to existing data
124
+ merged.tests[testId] = {
125
+ file: existingData.file,
126
+ duration: calculateEMA(existingData.duration, duration, alpha),
127
+ runs: existingData.runs + 1,
128
+ lastRun: now,
129
+ };
130
+ }
131
+ else {
132
+ // First measurement for this test
133
+ merged.tests[testId] = {
134
+ file,
135
+ duration,
136
+ runs: 1,
137
+ lastRun: now,
138
+ };
139
+ }
140
+ }
141
+ }
142
+ return merged;
143
+ }
144
+ /**
145
+ * Extract file name from test ID
146
+ */
147
+ function extractFileFromTestId(testId) {
148
+ const parts = testId.split('::');
149
+ return parts[0] ?? '';
150
+ }
151
+ /**
152
+ * Aggregate test-level timing to file-level (for backwards compatibility)
153
+ */
154
+ function aggregateTestsToFiles(data) {
155
+ const fileMap = new Map();
156
+ for (const testData of Object.values(data.tests)) {
157
+ const existing = fileMap.get(testData.file);
158
+ if (existing) {
159
+ existing.totalDuration += testData.duration;
160
+ existing.count += 1;
161
+ if (testData.lastRun > existing.lastRun) {
162
+ existing.lastRun = testData.lastRun;
163
+ }
164
+ }
165
+ else {
166
+ fileMap.set(testData.file, {
167
+ totalDuration: testData.duration,
168
+ count: 1,
169
+ lastRun: testData.lastRun,
170
+ });
171
+ }
172
+ }
173
+ const result = {};
174
+ for (const [file, stats] of fileMap) {
175
+ result[file] = {
176
+ duration: stats.totalDuration,
177
+ runs: stats.count,
178
+ lastRun: stats.lastRun,
179
+ };
180
+ }
181
+ return result;
182
+ }
183
+ /**
184
+ * Prune old entries from timing data (v1 - file-level)
185
+ *
186
+ * Removes entries that:
187
+ * 1. Haven't been run in more than `days` days
188
+ * 2. No longer exist in the current test files (if provided)
189
+ *
190
+ * @param data - Timing data to prune
191
+ * @param days - Number of days after which to remove entries
192
+ * @param currentFiles - Optional list of current test files (to remove deleted tests)
193
+ * @returns Pruned timing data
194
+ */
195
+ export function pruneTimingData(data, days = DEFAULT_PRUNE_DAYS, currentFiles) {
196
+ if (isTimingDataV2(data)) {
197
+ return pruneTestTimingData(data, days, currentFiles);
198
+ }
199
+ const now = new Date();
200
+ const cutoffDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);
201
+ const currentFileSet = currentFiles ? new Set(currentFiles) : null;
202
+ const prunedFiles = {};
203
+ for (const [file, timing] of Object.entries(data.files)) {
204
+ const lastRun = new Date(timing.lastRun);
205
+ // Skip if too old
206
+ if (lastRun < cutoffDate) {
207
+ continue;
208
+ }
209
+ // Skip if file no longer exists (when currentFiles is provided)
210
+ if (currentFileSet && !currentFileSet.has(file)) {
211
+ continue;
212
+ }
213
+ prunedFiles[file] = timing;
214
+ }
215
+ return {
216
+ ...data,
217
+ updatedAt: new Date().toISOString(),
218
+ files: prunedFiles,
219
+ };
220
+ }
221
+ /**
222
+ * Prune old entries from timing data (v2 - test-level)
223
+ *
224
+ * @param data - Timing data to prune
225
+ * @param days - Number of days after which to remove entries
226
+ * @param currentTestIds - Optional list of current test IDs (to remove deleted tests)
227
+ * @returns Pruned timing data
228
+ */
229
+ export function pruneTestTimingData(data, days = DEFAULT_PRUNE_DAYS, currentTestIds) {
230
+ const now = new Date();
231
+ const cutoffDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);
232
+ const currentTestSet = currentTestIds ? new Set(currentTestIds) : null;
233
+ const prunedTests = {};
234
+ for (const [testId, timing] of Object.entries(data.tests)) {
235
+ const lastRun = new Date(timing.lastRun);
236
+ // Skip if too old
237
+ if (lastRun < cutoffDate) {
238
+ continue;
239
+ }
240
+ // Skip if test no longer exists (when currentTestIds is provided)
241
+ if (currentTestSet && !currentTestSet.has(testId)) {
242
+ continue;
243
+ }
244
+ prunedTests[testId] = timing;
245
+ }
246
+ return {
247
+ ...data,
248
+ updatedAt: new Date().toISOString(),
249
+ tests: prunedTests,
250
+ };
251
+ }
252
+ /**
253
+ * Get duration for a file from timing data (v1)
254
+ *
255
+ * @param data - Timing data
256
+ * @param file - File name
257
+ * @returns Duration in ms, or undefined if not found
258
+ */
259
+ export function getFileDuration(data, file) {
260
+ if (isTimingDataV1(data)) {
261
+ return data.files[file]?.duration;
262
+ }
263
+ // For v2 data, aggregate tests in this file
264
+ const fileTests = Object.entries(data.tests).filter(([, t]) => t.file === file);
265
+ if (fileTests.length === 0) {
266
+ return undefined;
267
+ }
268
+ return fileTests.reduce((sum, [, t]) => sum + t.duration, 0);
269
+ }
270
+ /**
271
+ * Get duration for a test from timing data (v2)
272
+ *
273
+ * @param data - Timing data (v2)
274
+ * @param testId - Test ID
275
+ * @returns Duration in ms, or undefined if not found
276
+ */
277
+ export function getTestDuration(data, testId) {
278
+ return data.tests[testId]?.duration;
279
+ }
280
+ //# sourceMappingURL=timing-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing-store.js","sourceRoot":"","sources":["../../src/core/timing-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Timing data for a single test file (legacy v1 format)
3
+ */
4
+ export interface FileTimingData {
5
+ /** Duration in milliseconds */
6
+ duration: number;
7
+ /** Number of times this file has been measured */
8
+ runs: number;
9
+ /** ISO timestamp of last measurement */
10
+ lastRun: string;
11
+ }
12
+ /**
13
+ * Timing data for a single test (v2 format - test-level)
14
+ */
15
+ export interface TestTimingData {
16
+ /** Source file containing this test */
17
+ file: string;
18
+ /** Duration in milliseconds */
19
+ duration: number;
20
+ /** Number of times this test has been measured */
21
+ runs: number;
22
+ /** ISO timestamp of last measurement */
23
+ lastRun: string;
24
+ }
25
+ /**
26
+ * Complete timing data structure stored in cache (v1 - file-level)
27
+ */
28
+ export interface TimingDataV1 {
29
+ /** Schema version (1) */
30
+ version: 1;
31
+ /** ISO timestamp of last update */
32
+ updatedAt: string;
33
+ /** Map of file names to their timing data */
34
+ files: Record<string, FileTimingData>;
35
+ }
36
+ /**
37
+ * Complete timing data structure stored in cache (v2 - test-level)
38
+ */
39
+ export interface TimingDataV2 {
40
+ /** Schema version (2) */
41
+ version: 2;
42
+ /** ISO timestamp of last update */
43
+ updatedAt: string;
44
+ /** Map of test IDs to their timing data */
45
+ tests: Record<string, TestTimingData>;
46
+ }
47
+ /**
48
+ * Union type for timing data (supports both versions)
49
+ */
50
+ export type TimingData = TimingDataV1 | TimingDataV2;
51
+ /**
52
+ * Input for the shard assignment algorithm (file-level)
53
+ */
54
+ export interface FileWithDuration {
55
+ /** File path (relative to test directory) */
56
+ file: string;
57
+ /** Duration in milliseconds */
58
+ duration: number;
59
+ /** Whether the duration was estimated (no historical data) */
60
+ estimated: boolean;
61
+ }
62
+ /**
63
+ * Input for the shard assignment algorithm (test-level)
64
+ */
65
+ export interface TestWithDuration {
66
+ /** Test ID in format: file::describe::testTitle */
67
+ testId: string;
68
+ /** Source file */
69
+ file: string;
70
+ /** Duration in milliseconds */
71
+ duration: number;
72
+ /** Whether the duration was estimated (no historical data) */
73
+ estimated: boolean;
74
+ }
75
+ /**
76
+ * Output of the shard assignment algorithm (file-level)
77
+ */
78
+ export interface ShardAssignment {
79
+ /** Shard index (1-based) */
80
+ shardIndex: number;
81
+ /** List of test files assigned to this shard */
82
+ files: string[];
83
+ /** Expected total duration in milliseconds */
84
+ expectedDuration: number;
85
+ }
86
+ /**
87
+ * Output of the shard assignment algorithm (test-level)
88
+ */
89
+ export interface TestShardAssignment {
90
+ /** Shard index (1-based) */
91
+ shardIndex: number;
92
+ /** List of test IDs assigned to this shard */
93
+ tests: string[];
94
+ /** Expected total duration in milliseconds */
95
+ expectedDuration: number;
96
+ }
97
+ /**
98
+ * Complete result from the assign command (file-level)
99
+ */
100
+ export interface AssignResult {
101
+ /** Map of shard index to list of files */
102
+ shards: Record<number, string[]>;
103
+ /** Expected duration per shard */
104
+ expectedDurations: Record<number, number>;
105
+ /** Total number of files */
106
+ totalFiles: number;
107
+ /** Files that had no timing data (estimated) */
108
+ estimatedFiles: string[];
109
+ }
110
+ /**
111
+ * Complete result from the assign command (test-level)
112
+ */
113
+ export interface TestAssignResult {
114
+ /** Map of shard index to list of test IDs */
115
+ shards: Record<number, string[]>;
116
+ /** Map of shard index to grep pattern */
117
+ grepPatterns: Record<number, string>;
118
+ /** Expected duration per shard */
119
+ expectedDurations: Record<number, number>;
120
+ /** Total number of tests */
121
+ totalTests: number;
122
+ /** Tests that had no timing data (estimated) */
123
+ estimatedTests: string[];
124
+ /** Whether CKK found optimal solution (false = fell back to LPT) */
125
+ isOptimal: boolean;
126
+ }
127
+ /**
128
+ * Per-shard timing artifact uploaded after test run (file-level, v1)
129
+ */
130
+ export interface ShardTimingArtifact {
131
+ /** Shard index (1-based) */
132
+ shard: number;
133
+ /** Browser project name */
134
+ project: string;
135
+ /** Map of file names to duration in ms */
136
+ files: Record<string, number>;
137
+ }
138
+ /**
139
+ * Per-shard timing artifact uploaded after test run (test-level, v2)
140
+ */
141
+ export interface TestShardTimingArtifact {
142
+ /** Shard index (1-based) */
143
+ shard: number;
144
+ /** Browser project name */
145
+ project: string;
146
+ /** Map of test IDs to duration in ms */
147
+ tests: Record<string, number>;
148
+ }
149
+ /**
150
+ * Information about a discovered test
151
+ */
152
+ export interface DiscoveredTest {
153
+ /** Source file path */
154
+ file: string;
155
+ /** Test title */
156
+ title: string;
157
+ /** Full title path (describe blocks + test title) */
158
+ titlePath: string[];
159
+ /** Unique test ID: file::describe::testTitle */
160
+ testId: string;
161
+ }
162
+ /**
163
+ * Playwright JSON report structure (relevant fields only)
164
+ */
165
+ export interface PlaywrightReport {
166
+ suites: PlaywrightSuite[];
167
+ }
168
+ export interface PlaywrightSuite {
169
+ title: string;
170
+ file: string;
171
+ suites?: PlaywrightSuite[];
172
+ specs?: PlaywrightSpec[];
173
+ }
174
+ export interface PlaywrightSpec {
175
+ title: string;
176
+ tests: PlaywrightTest[];
177
+ }
178
+ export interface PlaywrightTest {
179
+ results: PlaywrightTestResult[];
180
+ }
181
+ export interface PlaywrightTestResult {
182
+ duration: number;
183
+ status: string;
184
+ }
185
+ /**
186
+ * Playwright --list JSON output structure
187
+ */
188
+ export interface PlaywrightListOutput {
189
+ config: {
190
+ projects: Array<{
191
+ name: string;
192
+ testDir: string;
193
+ }>;
194
+ };
195
+ suites: PlaywrightListSuite[];
196
+ }
197
+ export interface PlaywrightListSuite {
198
+ title: string;
199
+ file: string;
200
+ suites?: PlaywrightListSuite[];
201
+ specs?: PlaywrightListSpec[];
202
+ }
203
+ export interface PlaywrightListSpec {
204
+ title: string;
205
+ file: string;
206
+ line: number;
207
+ column: number;
208
+ }
209
+ /** Current schema version for timing data */
210
+ export declare const TIMING_DATA_VERSION = 2;
211
+ /** Legacy schema version */
212
+ export declare const TIMING_DATA_VERSION_V1 = 1;
213
+ /**
214
+ * Create an empty timing data structure (v2 - test-level)
215
+ */
216
+ export declare function createEmptyTimingData(): TimingDataV2;
217
+ /**
218
+ * Create an empty timing data structure (v1 - file-level, for backwards compatibility)
219
+ */
220
+ export declare function createEmptyTimingDataV1(): TimingDataV1;
221
+ /**
222
+ * Build a test ID from file and title path
223
+ * Format: file::describe1::describe2::testTitle
224
+ */
225
+ export declare function buildTestId(file: string, titlePath: string[]): string;
226
+ /**
227
+ * Parse a test ID back to file and title path
228
+ */
229
+ export declare function parseTestId(testId: string): {
230
+ file: string;
231
+ titlePath: string[];
232
+ };
233
+ /**
234
+ * Check if timing data is v2 (test-level)
235
+ */
236
+ export declare function isTimingDataV2(data: TimingData): data is TimingDataV2;
237
+ /**
238
+ * Check if timing data is v1 (file-level)
239
+ */
240
+ export declare function isTimingDataV1(data: TimingData): data is TimingDataV1;
241
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /** Current schema version for timing data */
2
+ export const TIMING_DATA_VERSION = 2;
3
+ /** Legacy schema version */
4
+ export const TIMING_DATA_VERSION_V1 = 1;
5
+ /**
6
+ * Create an empty timing data structure (v2 - test-level)
7
+ */
8
+ export function createEmptyTimingData() {
9
+ return {
10
+ version: TIMING_DATA_VERSION,
11
+ updatedAt: new Date().toISOString(),
12
+ tests: {},
13
+ };
14
+ }
15
+ /**
16
+ * Create an empty timing data structure (v1 - file-level, for backwards compatibility)
17
+ */
18
+ export function createEmptyTimingDataV1() {
19
+ return {
20
+ version: TIMING_DATA_VERSION_V1,
21
+ updatedAt: new Date().toISOString(),
22
+ files: {},
23
+ };
24
+ }
25
+ /**
26
+ * Build a test ID from file and title path
27
+ * Format: file::describe1::describe2::testTitle
28
+ */
29
+ export function buildTestId(file, titlePath) {
30
+ return [file, ...titlePath].join('::');
31
+ }
32
+ /**
33
+ * Parse a test ID back to file and title path
34
+ */
35
+ export function parseTestId(testId) {
36
+ const parts = testId.split('::');
37
+ return {
38
+ file: parts[0] ?? '',
39
+ titlePath: parts.slice(1),
40
+ };
41
+ }
42
+ /**
43
+ * Check if timing data is v2 (test-level)
44
+ */
45
+ export function isTimingDataV2(data) {
46
+ return data.version === 2;
47
+ }
48
+ /**
49
+ * Check if timing data is v1 (file-level)
50
+ */
51
+ export function isTimingDataV1(data) {
52
+ return data.version === 1;
53
+ }
54
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAsOA,6CAA6C;AAC7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,4BAA4B;AAC5B,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,OAAO,EAAE,mBAAmB;QAC5B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,EAAE;KACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,OAAO,EAAE,sBAAsB;QAC/B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,EAAE;KACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,SAAmB;IAC3D,OAAO,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IAIxC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;QACpB,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,OAAO,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,OAAO,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @nsxbet/playwright-orchestrator
3
+ *
4
+ * Intelligent Playwright test distribution across CI shards
5
+ * using historical timing data.
6
+ */
7
+ export * from './core/index.js';
8
+ export declare const VERSION = "0.1.0";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,iBAAiB,CAAC;AAChC,eAAO,MAAM,OAAO,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @nsxbet/playwright-orchestrator
3
+ *
4
+ * Intelligent Playwright test distribution across CI shards
5
+ * using historical timing data.
6
+ */
7
+ export * from './core/index.js';
8
+ export const VERSION = '0.1.0';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,iBAAiB,CAAC;AAChC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}