playwright-order-manager 0.1.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.
- package/CHANGELOG.md +20 -0
- package/README.md +240 -0
- package/bin/run.js +133 -0
- package/dist/constants/index.d.ts +72 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +93 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/core/OrderedExecution.d.ts +52 -0
- package/dist/core/OrderedExecution.d.ts.map +1 -0
- package/dist/core/OrderedExecution.js +253 -0
- package/dist/core/OrderedExecution.js.map +1 -0
- package/dist/core/OrderedReportParser.d.ts +38 -0
- package/dist/core/OrderedReportParser.d.ts.map +1 -0
- package/dist/core/OrderedReportParser.js +169 -0
- package/dist/core/OrderedReportParser.js.map +1 -0
- package/dist/core/OrderedSummary.d.ts +20 -0
- package/dist/core/OrderedSummary.d.ts.map +1 -0
- package/dist/core/OrderedSummary.js +747 -0
- package/dist/core/OrderedSummary.js.map +1 -0
- package/dist/fixtures/index.d.ts +30 -0
- package/dist/fixtures/index.d.ts.map +1 -0
- package/dist/fixtures/index.js +212 -0
- package/dist/fixtures/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/runner/TestOrderManager.d.ts +62 -0
- package/dist/runner/TestOrderManager.d.ts.map +1 -0
- package/dist/runner/TestOrderManager.js +490 -0
- package/dist/runner/TestOrderManager.js.map +1 -0
- package/dist/types/index.d.ts +215 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +65 -0
- package/templates/playwright.merge.config.ts +57 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrderedExecution = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// INTERNAL HELPERS
|
|
7
|
+
// These are private to this file. Not exported. Not part of the public API.
|
|
8
|
+
// =============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Returns true if the test has ANY of the given tags.
|
|
11
|
+
*
|
|
12
|
+
* Why a separate helper?
|
|
13
|
+
* Tag matching happens in multiple places (boundary detection, priority grouping).
|
|
14
|
+
* Centralizing it means if Playwright ever changes how tags work, we fix one place.
|
|
15
|
+
*/
|
|
16
|
+
function hasAnyTag(test, tags) {
|
|
17
|
+
return test.tags.some((tag) => tags.includes(tag));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns the highest-priority tag found on a test.
|
|
21
|
+
*
|
|
22
|
+
* "Highest priority" means earliest in the PRIORITY_TAGS array.
|
|
23
|
+
* So if a test has both '@P2' and '@P3', this returns '@P2'.
|
|
24
|
+
*
|
|
25
|
+
* Returns undefined if the test has no priority tag at all.
|
|
26
|
+
*/
|
|
27
|
+
function getHighestPriorityTag(test) {
|
|
28
|
+
return constants_1.RunnerConstants.PRIORITY_TAGS.find((tag) => test.tags.includes(tag));
|
|
29
|
+
}
|
|
30
|
+
// =============================================================================
|
|
31
|
+
// BUCKET BUILDERS — one function per OrderMode
|
|
32
|
+
// =============================================================================
|
|
33
|
+
/**
|
|
34
|
+
* Builds buckets for 'basic' mode.
|
|
35
|
+
*
|
|
36
|
+
* Basic mode does the minimum: boundary tests (@runFirst / @runLast) get
|
|
37
|
+
* their own buckets, everything else goes into one single bucket in the
|
|
38
|
+
* middle. No priority ordering within that middle bucket.
|
|
39
|
+
*/
|
|
40
|
+
function buildBasicBuckets(tests, runFirstTags, runLastTags) {
|
|
41
|
+
const runFirstTests = [];
|
|
42
|
+
const middleTests = [];
|
|
43
|
+
const runLastTests = [];
|
|
44
|
+
for (const test of tests) {
|
|
45
|
+
if (hasAnyTag(test, runFirstTags)) {
|
|
46
|
+
runFirstTests.push(test);
|
|
47
|
+
}
|
|
48
|
+
else if (hasAnyTag(test, runLastTags)) {
|
|
49
|
+
runLastTests.push(test);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
middleTests.push(test);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const buckets = [];
|
|
56
|
+
if (runFirstTests.length > 0) {
|
|
57
|
+
buckets.push({
|
|
58
|
+
key: constants_1.RunnerConstants.BUCKET_KEYS.RUN_FIRST,
|
|
59
|
+
label: 'Run First',
|
|
60
|
+
kind: 'boundary',
|
|
61
|
+
critical: true,
|
|
62
|
+
tests: runFirstTests,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (middleTests.length > 0) {
|
|
66
|
+
buckets.push({
|
|
67
|
+
key: constants_1.RunnerConstants.BUCKET_KEYS.NO_PRIORITY,
|
|
68
|
+
label: 'All Tests',
|
|
69
|
+
kind: 'none',
|
|
70
|
+
critical: false,
|
|
71
|
+
tests: middleTests,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (runLastTests.length > 0) {
|
|
75
|
+
buckets.push({
|
|
76
|
+
key: constants_1.RunnerConstants.BUCKET_KEYS.RUN_LAST,
|
|
77
|
+
label: 'Run Last',
|
|
78
|
+
kind: 'boundary',
|
|
79
|
+
critical: false,
|
|
80
|
+
tests: runLastTests,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return buckets;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Builds buckets for 'priority' mode.
|
|
87
|
+
*
|
|
88
|
+
* Priority mode creates one bucket per priority level that has at least
|
|
89
|
+
* one test. So if you have @P1 and @P3 tests but no @P2, you get two
|
|
90
|
+
* priority buckets (not three). Tests with no priority tag go into the
|
|
91
|
+
* NoPriority bucket, which runs after all priority buckets.
|
|
92
|
+
*
|
|
93
|
+
* Full execution order:
|
|
94
|
+
* [runFirst] → [@P1] → [@P2] → [@P3] → [@P4] → [NoPriority] → [runLast]
|
|
95
|
+
*
|
|
96
|
+
* Empty buckets are omitted entirely.
|
|
97
|
+
*/
|
|
98
|
+
function buildPriorityBuckets(tests, runFirstTags, runLastTags) {
|
|
99
|
+
const runFirstTests = [];
|
|
100
|
+
const runLastTests = [];
|
|
101
|
+
const noPriorityTests = [];
|
|
102
|
+
// One array per priority tag, keyed by tag name
|
|
103
|
+
const priorityMap = new Map(constants_1.RunnerConstants.PRIORITY_TAGS.map((tag) => [tag, []]));
|
|
104
|
+
// Single pass through all tests — assign each to exactly one bucket
|
|
105
|
+
for (const test of tests) {
|
|
106
|
+
if (hasAnyTag(test, runFirstTags)) {
|
|
107
|
+
runFirstTests.push(test);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (hasAnyTag(test, runLastTags)) {
|
|
111
|
+
runLastTests.push(test);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const priorityTag = getHighestPriorityTag(test);
|
|
115
|
+
if (priorityTag) {
|
|
116
|
+
// Non-null assertion safe here: we just found the tag in PRIORITY_TAGS
|
|
117
|
+
priorityMap.get(priorityTag).push(test);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
noPriorityTests.push(test);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const buckets = [];
|
|
124
|
+
// 1. runFirst bucket (critical — if this fails, we stop)
|
|
125
|
+
if (runFirstTests.length > 0) {
|
|
126
|
+
buckets.push({
|
|
127
|
+
key: constants_1.RunnerConstants.BUCKET_KEYS.RUN_FIRST,
|
|
128
|
+
label: 'Run First',
|
|
129
|
+
kind: 'boundary',
|
|
130
|
+
critical: true,
|
|
131
|
+
tests: runFirstTests,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// 2. One bucket per priority tag, in P1 → P4 order
|
|
135
|
+
// Skip empty priority buckets entirely
|
|
136
|
+
for (const tag of constants_1.RunnerConstants.PRIORITY_TAGS) {
|
|
137
|
+
const testsForTag = priorityMap.get(tag);
|
|
138
|
+
if (testsForTag.length === 0)
|
|
139
|
+
continue;
|
|
140
|
+
// '@P1' → 'P1', '@P2' → 'P2', etc.
|
|
141
|
+
const shortTag = tag.replace('@', '');
|
|
142
|
+
buckets.push({
|
|
143
|
+
key: `priority-${shortTag}`,
|
|
144
|
+
label: `Priority ${shortTag}`,
|
|
145
|
+
kind: 'priority',
|
|
146
|
+
critical: false,
|
|
147
|
+
tests: testsForTag,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// 3. NoPriority bucket — tests with no @Px tag
|
|
151
|
+
if (noPriorityTests.length > 0) {
|
|
152
|
+
buckets.push({
|
|
153
|
+
key: constants_1.RunnerConstants.BUCKET_KEYS.NO_PRIORITY,
|
|
154
|
+
label: constants_1.RunnerConstants.NO_PRIORITY_TOKEN,
|
|
155
|
+
kind: 'none',
|
|
156
|
+
critical: false,
|
|
157
|
+
tests: noPriorityTests,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// 4. runLast bucket (not critical — cleanup should always attempt to run)
|
|
161
|
+
if (runLastTests.length > 0) {
|
|
162
|
+
buckets.push({
|
|
163
|
+
key: constants_1.RunnerConstants.BUCKET_KEYS.RUN_LAST,
|
|
164
|
+
label: 'Run Last',
|
|
165
|
+
kind: 'boundary',
|
|
166
|
+
critical: false,
|
|
167
|
+
tests: runLastTests,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return buckets;
|
|
171
|
+
}
|
|
172
|
+
// =============================================================================
|
|
173
|
+
// PUBLIC API
|
|
174
|
+
// =============================================================================
|
|
175
|
+
class OrderedExecution {
|
|
176
|
+
/**
|
|
177
|
+
* Takes a flat list of discovered tests and groups them into ordered buckets.
|
|
178
|
+
*
|
|
179
|
+
* This is the core algorithm of the entire package. The buckets returned
|
|
180
|
+
* here define the execution order — the runner executes them one by one,
|
|
181
|
+
* in the order they appear in this array.
|
|
182
|
+
*
|
|
183
|
+
* @param options - See BuildBucketOptions in types/index.ts
|
|
184
|
+
* @returns An ordered array of BucketPlan objects, ready for execution
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* const buckets = OrderedExecution.buildBuckets({
|
|
189
|
+
* tests: discoveredTests,
|
|
190
|
+
* orderMode: 'priority',
|
|
191
|
+
* });
|
|
192
|
+
* // buckets[0] = runFirst tests (if any)
|
|
193
|
+
* // buckets[1] = @P1 tests (if any)
|
|
194
|
+
* // buckets[2] = @P2 tests (if any)
|
|
195
|
+
* // ...and so on
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
static buildBuckets(options) {
|
|
199
|
+
const { tests, orderMode, runFirstTags = [constants_1.RunnerConstants.RUN_FIRST_TAG], runLastTags = [constants_1.RunnerConstants.RUN_LAST_TAG], } = options;
|
|
200
|
+
// Guard: nothing to do with an empty test list
|
|
201
|
+
if (tests.length === 0) {
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
switch (orderMode) {
|
|
205
|
+
case 'basic':
|
|
206
|
+
return buildBasicBuckets(tests, runFirstTags, runLastTags);
|
|
207
|
+
case 'priority':
|
|
208
|
+
return buildPriorityBuckets(tests, runFirstTags, runLastTags);
|
|
209
|
+
case 'custom':
|
|
210
|
+
// v2 — not implemented yet
|
|
211
|
+
// We throw instead of silently falling back so the user knows immediately
|
|
212
|
+
throw new Error(`OrderMode 'custom' is not implemented in v1. ` +
|
|
213
|
+
`Use 'basic' or 'priority'.`);
|
|
214
|
+
default: {
|
|
215
|
+
// This branch should be unreachable if TypeScript types are respected.
|
|
216
|
+
// But if someone passes an invalid value via JavaScript or env vars,
|
|
217
|
+
// we want a clear error message.
|
|
218
|
+
const exhaustiveCheck = orderMode;
|
|
219
|
+
throw new Error(`Unknown orderMode: '${exhaustiveCheck}'. ` +
|
|
220
|
+
`Valid values are: 'basic', 'priority'.`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Splits an array of buckets into three phases for the runner to process.
|
|
226
|
+
*
|
|
227
|
+
* Why split into phases?
|
|
228
|
+
* The runner needs to handle the runFirst bucket specially — if it fails
|
|
229
|
+
* and the FailurePolicy is 'critical', we stop before running any middle
|
|
230
|
+
* buckets. Similarly, runLast should always attempt to run (cleanup)
|
|
231
|
+
* even if middle buckets failed.
|
|
232
|
+
*
|
|
233
|
+
* @param buckets - The output from buildBuckets()
|
|
234
|
+
* @returns An object with three arrays: runFirst, middle, runLast
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* const { runFirst, middle, runLast } = OrderedExecution.groupBuckets(buckets);
|
|
239
|
+
* // Run runFirst phase, check failure policy
|
|
240
|
+
* // Run middle phase buckets in order
|
|
241
|
+
* // Run runLast phase regardless of middle results
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
static groupBuckets(buckets) {
|
|
245
|
+
const runFirst = buckets.filter((b) => b.key === constants_1.RunnerConstants.BUCKET_KEYS.RUN_FIRST);
|
|
246
|
+
const runLast = buckets.filter((b) => b.key === constants_1.RunnerConstants.BUCKET_KEYS.RUN_LAST);
|
|
247
|
+
const middle = buckets.filter((b) => b.key !== constants_1.RunnerConstants.BUCKET_KEYS.RUN_FIRST &&
|
|
248
|
+
b.key !== constants_1.RunnerConstants.BUCKET_KEYS.RUN_LAST);
|
|
249
|
+
return { runFirst, middle, runLast };
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
exports.OrderedExecution = OrderedExecution;
|
|
253
|
+
//# sourceMappingURL=OrderedExecution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderedExecution.js","sourceRoot":"","sources":["../../src/core/OrderedExecution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DiscoveredTestCase, ExecutedTestResult } from '../types';
|
|
2
|
+
export declare class OrderedReportParser {
|
|
3
|
+
/**
|
|
4
|
+
* Parses Playwright's execution JSON report into our typed ExecutedTestResult array.
|
|
5
|
+
*
|
|
6
|
+
* Call this after a Playwright run completes and writes its JSON report.
|
|
7
|
+
* The result is what OrderedSummary uses to build the final summary.
|
|
8
|
+
*
|
|
9
|
+
* @param rawJson - The parsed contents of Playwright's JSON report file.
|
|
10
|
+
* Pass the result of JSON.parse(fs.readFileSync(reportPath, 'utf8')).
|
|
11
|
+
* @returns A flat array of ExecutedTestResult, one entry per test per project.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const raw = JSON.parse(fs.readFileSync('./test-results/report.json', 'utf8'));
|
|
16
|
+
* const results = OrderedReportParser.parseExecutionReport(raw);
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
static parseExecutionReport(rawJson: unknown): ExecutedTestResult[];
|
|
20
|
+
/**
|
|
21
|
+
* Parses the discovery JSON written during `playwright --list` phase.
|
|
22
|
+
*
|
|
23
|
+
* During discovery, our fixture writes a JSON file containing the list
|
|
24
|
+
* of all tests Playwright found. This method reads that file's contents
|
|
25
|
+
* and converts them into DiscoveredTestCase objects.
|
|
26
|
+
*
|
|
27
|
+
* @param rawJson - The parsed contents of the discovery JSON file.
|
|
28
|
+
* @returns A flat array of DiscoveredTestCase objects.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const raw = JSON.parse(fs.readFileSync('./ordered-results/ordered-discovery.json', 'utf8'));
|
|
33
|
+
* const tests = OrderedReportParser.parseDiscoveryReport(raw);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
static parseDiscoveryReport(rawJson: unknown): DiscoveredTestCase[];
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=OrderedReportParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderedReportParser.d.ts","sourceRoot":"","sources":["../../src/core/OrderedReportParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAEnB,MAAM,UAAU,CAAC;AA0JlB,qBAAa,mBAAmB;IAC9B;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,kBAAkB,EAAE;IA0DnE;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,kBAAkB,EAAE;CA8BpE"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrderedReportParser = void 0;
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// INTERNAL HELPERS
|
|
6
|
+
// =============================================================================
|
|
7
|
+
/**
|
|
8
|
+
* Normalises whatever status string Playwright gives us into our TestStatus type.
|
|
9
|
+
* Playwright uses 'expected', 'unexpected', 'flaky', 'skipped' — we map those
|
|
10
|
+
* to our simpler 'passed' | 'failed' | 'skipped' | 'timedOut' | 'interrupted'.
|
|
11
|
+
*/
|
|
12
|
+
function normaliseStatus(raw) {
|
|
13
|
+
switch (raw) {
|
|
14
|
+
case 'expected':
|
|
15
|
+
case 'passed':
|
|
16
|
+
return 'passed';
|
|
17
|
+
case 'skipped':
|
|
18
|
+
return 'skipped';
|
|
19
|
+
case 'timedOut':
|
|
20
|
+
return 'timedOut';
|
|
21
|
+
case 'interrupted':
|
|
22
|
+
return 'interrupted';
|
|
23
|
+
// 'unexpected', 'flaky', or anything else we don't recognise → failed
|
|
24
|
+
default:
|
|
25
|
+
return 'failed';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Extracts the most useful error message from a Playwright error array.
|
|
30
|
+
* Playwright can report multiple errors per test — we take the first non-empty one.
|
|
31
|
+
*/
|
|
32
|
+
function extractErrorMessage(errors) {
|
|
33
|
+
if (!errors || errors.length === 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
for (const error of errors) {
|
|
36
|
+
const msg = error.message ?? error.value;
|
|
37
|
+
if (msg && msg.trim().length > 0) {
|
|
38
|
+
// Trim to first 500 chars — full stack traces belong in the HTML report,
|
|
39
|
+
// not in our summary JSON
|
|
40
|
+
return msg.trim().slice(0, 500);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Recursively walks a Playwright suite tree and collects all specs.
|
|
47
|
+
* Suites can be nested arbitrarily deep (file → describe → describe → spec).
|
|
48
|
+
*
|
|
49
|
+
* @param suite - The current suite node to walk
|
|
50
|
+
* @param filePath - The file path, carried down from the top-level suite
|
|
51
|
+
* @param collected - Accumulator array — specs are pushed here
|
|
52
|
+
*/
|
|
53
|
+
function collectSpecs(suite, filePath, collected) {
|
|
54
|
+
// Collect specs at this level
|
|
55
|
+
if (suite.specs) {
|
|
56
|
+
for (const spec of suite.specs) {
|
|
57
|
+
collected.push({ spec, file: filePath });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Recurse into nested suites
|
|
61
|
+
if (suite.suites) {
|
|
62
|
+
for (const child of suite.suites) {
|
|
63
|
+
// Use the child's own file path if it has one, otherwise inherit from parent
|
|
64
|
+
collectSpecs(child, child.file ?? filePath, collected);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// PUBLIC API
|
|
70
|
+
// =============================================================================
|
|
71
|
+
class OrderedReportParser {
|
|
72
|
+
/**
|
|
73
|
+
* Parses Playwright's execution JSON report into our typed ExecutedTestResult array.
|
|
74
|
+
*
|
|
75
|
+
* Call this after a Playwright run completes and writes its JSON report.
|
|
76
|
+
* The result is what OrderedSummary uses to build the final summary.
|
|
77
|
+
*
|
|
78
|
+
* @param rawJson - The parsed contents of Playwright's JSON report file.
|
|
79
|
+
* Pass the result of JSON.parse(fs.readFileSync(reportPath, 'utf8')).
|
|
80
|
+
* @returns A flat array of ExecutedTestResult, one entry per test per project.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const raw = JSON.parse(fs.readFileSync('./test-results/report.json', 'utf8'));
|
|
85
|
+
* const results = OrderedReportParser.parseExecutionReport(raw);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
static parseExecutionReport(rawJson) {
|
|
89
|
+
// Validate that we got something that looks like a Playwright report
|
|
90
|
+
if (!rawJson || typeof rawJson !== 'object') {
|
|
91
|
+
throw new Error('OrderedReportParser.parseExecutionReport: ' +
|
|
92
|
+
'expected a JSON object, got ' + typeof rawJson);
|
|
93
|
+
}
|
|
94
|
+
const report = rawJson;
|
|
95
|
+
if (!Array.isArray(report.suites)) {
|
|
96
|
+
throw new Error('OrderedReportParser.parseExecutionReport: ' +
|
|
97
|
+
'JSON does not look like a Playwright report (missing "suites" array)');
|
|
98
|
+
}
|
|
99
|
+
const results = [];
|
|
100
|
+
// Collect all specs from the entire suite tree
|
|
101
|
+
const allSpecs = [];
|
|
102
|
+
for (const topSuite of report.suites) {
|
|
103
|
+
collectSpecs(topSuite, topSuite.file ?? '', allSpecs);
|
|
104
|
+
}
|
|
105
|
+
// Convert each spec + its tests into ExecutedTestResult entries
|
|
106
|
+
for (const { spec, file } of allSpecs) {
|
|
107
|
+
if (!spec.tests || spec.tests.length === 0)
|
|
108
|
+
continue;
|
|
109
|
+
for (const test of spec.tests) {
|
|
110
|
+
// How many retries were used?
|
|
111
|
+
// results array has one entry per attempt. retries = attempts - 1.
|
|
112
|
+
const retries = test.results
|
|
113
|
+
? Math.max(0, test.results.length - 1)
|
|
114
|
+
: 0;
|
|
115
|
+
// The final error comes from the last result attempt (if it failed)
|
|
116
|
+
const lastResult = test.results?.[test.results.length - 1];
|
|
117
|
+
const errorMessage = extractErrorMessage(lastResult?.errors ?? test.errors);
|
|
118
|
+
results.push({
|
|
119
|
+
title: spec.title,
|
|
120
|
+
file,
|
|
121
|
+
status: normaliseStatus(test.status),
|
|
122
|
+
duration: test.duration,
|
|
123
|
+
retries,
|
|
124
|
+
errorMessage,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return results;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Parses the discovery JSON written during `playwright --list` phase.
|
|
132
|
+
*
|
|
133
|
+
* During discovery, our fixture writes a JSON file containing the list
|
|
134
|
+
* of all tests Playwright found. This method reads that file's contents
|
|
135
|
+
* and converts them into DiscoveredTestCase objects.
|
|
136
|
+
*
|
|
137
|
+
* @param rawJson - The parsed contents of the discovery JSON file.
|
|
138
|
+
* @returns A flat array of DiscoveredTestCase objects.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* const raw = JSON.parse(fs.readFileSync('./ordered-results/ordered-discovery.json', 'utf8'));
|
|
143
|
+
* const tests = OrderedReportParser.parseDiscoveryReport(raw);
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
static parseDiscoveryReport(rawJson) {
|
|
147
|
+
if (!rawJson || typeof rawJson !== 'object') {
|
|
148
|
+
throw new Error('OrderedReportParser.parseDiscoveryReport: ' +
|
|
149
|
+
'expected a JSON object, got ' + typeof rawJson);
|
|
150
|
+
}
|
|
151
|
+
const data = rawJson;
|
|
152
|
+
if (!Array.isArray(data.tests)) {
|
|
153
|
+
throw new Error('OrderedReportParser.parseDiscoveryReport: ' +
|
|
154
|
+
'discovery JSON missing "tests" array. ' +
|
|
155
|
+
'Make sure the orderedDiscovery fixture is set up correctly.');
|
|
156
|
+
}
|
|
157
|
+
// Validate and cast each entry
|
|
158
|
+
return data.tests
|
|
159
|
+
.filter((entry) => {
|
|
160
|
+
return (entry !== null &&
|
|
161
|
+
typeof entry === 'object' &&
|
|
162
|
+
typeof entry.title === 'string' &&
|
|
163
|
+
typeof entry.file === 'string' &&
|
|
164
|
+
Array.isArray(entry.tags));
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
exports.OrderedReportParser = OrderedReportParser;
|
|
169
|
+
//# sourceMappingURL=OrderedReportParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderedReportParser.js","sourceRoot":"","sources":["../../src/core/OrderedReportParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OrderedRunSummary, BucketExecutionRecord } from '../types';
|
|
2
|
+
export declare class OrderedSummary {
|
|
3
|
+
/**
|
|
4
|
+
* Writes the ordered run summary to disk as both JSON and HTML.
|
|
5
|
+
*
|
|
6
|
+
* @param summary - The complete run summary to write
|
|
7
|
+
* @param reportRoot - Directory to write into. Defaults to RunnerConstants.DEFAULTS.REPORT_ROOT
|
|
8
|
+
* @returns Absolute paths of the files written: { jsonPath, htmlPath }
|
|
9
|
+
*/
|
|
10
|
+
static write(summary: OrderedRunSummary, reportRoot?: string): {
|
|
11
|
+
jsonPath: string;
|
|
12
|
+
htmlPath: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Builds an OrderedRunSummary from raw bucket execution records.
|
|
16
|
+
* Call this after all buckets finish, then pass the result to write().
|
|
17
|
+
*/
|
|
18
|
+
static buildSummary(buckets: BucketExecutionRecord[], startedAt: string, orderMode: string, failurePolicy: string): OrderedRunSummary;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=OrderedSummary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderedSummary.d.ts","sourceRoot":"","sources":["../../src/core/OrderedSummary.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,UAAU,CAAC;AAyqBlB,qBAAa,cAAc;IACzB;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CACV,OAAO,EAAE,iBAAiB,EAC1B,UAAU,GAAE,MAA6C,GACxD;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IA2BzC;;;OAGG;IACH,MAAM,CAAC,YAAY,CACjB,OAAO,EAAE,qBAAqB,EAAE,EAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,iBAAiB;CA6BrB"}
|