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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-03-30
|
|
6
|
+
|
|
7
|
+
### First release
|
|
8
|
+
|
|
9
|
+
- `OrderedExecution` — pure bucketing algorithm with `basic` and `priority` modes
|
|
10
|
+
- `TestOrderManager` — full CLI orchestrator (discover → plan → execute → report)
|
|
11
|
+
- `OrderedReportParser` — parses Playwright JSON reports into typed objects
|
|
12
|
+
- `OrderedSummary` — writes JSON summary and self-contained HTML report
|
|
13
|
+
- Playwright fixtures via `playwright-order-manager/fixtures` subpath export
|
|
14
|
+
- `@runFirst` / `@runLast` boundary tags
|
|
15
|
+
- `@P1` / `@P2` / `@P3` / `@P4` priority tags
|
|
16
|
+
- Three failure policies: `critical`, `continue`, `immediate`
|
|
17
|
+
- HTML report with progress bar, bucket navigation, flaky detection,
|
|
18
|
+
collapsible sections, and inline error preview
|
|
19
|
+
- CLI via `npx pw-order`
|
|
20
|
+
- Full TypeScript types exported for consumers
|
package/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# playwright-order-manager
|
|
2
|
+
|
|
3
|
+
Priority-ordered test execution for Playwright. Run your most critical tests first, get faster feedback on failures, and keep your CI pipeline moving.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
Playwright runs tests in parallel by default, which is fast but gives you no control over *which* tests run first. If your most critical test (say, user login) fails, you still wait for hundreds of other tests to finish before you find out.
|
|
10
|
+
|
|
11
|
+
`playwright-order-manager` solves this by:
|
|
12
|
+
|
|
13
|
+
- Grouping tests into **buckets** by priority (`@P1` → `@P2` → `@P3` → `@P4`)
|
|
14
|
+
- Running buckets **one at a time**, highest priority first
|
|
15
|
+
- Stopping early if a critical bucket fails — no wasted CI time
|
|
16
|
+
- Writing an **HTML report** showing exactly what ran, in what order, and why it failed
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
```bash
|
|
22
|
+
npm install --save-dev playwright-order-manager
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Requirements:**
|
|
26
|
+
- Node.js >= 18
|
|
27
|
+
- `@playwright/test` >= 1.40 (installed separately as a peer dependency)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### Step 1 — Tag your tests
|
|
34
|
+
|
|
35
|
+
Add priority tags to your tests. The tag goes in the test title:
|
|
36
|
+
```typescript
|
|
37
|
+
import { test, expect } from 'playwright-order-manager/fixtures';
|
|
38
|
+
|
|
39
|
+
// Runs first — highest priority
|
|
40
|
+
test('@P1 user can log in', async ({ page }) => {
|
|
41
|
+
await page.goto('/login');
|
|
42
|
+
// ...
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Runs second
|
|
46
|
+
test('@P2 user can view dashboard', async ({ page }) => {
|
|
47
|
+
// ...
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Always runs before everything else
|
|
51
|
+
test('@runFirst seed the database', async ({ page }) => {
|
|
52
|
+
// ...
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Always runs after everything else
|
|
56
|
+
test('@runLast clean up test data', async ({ page }) => {
|
|
57
|
+
// ...
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
> **Important:** Import `test` from `playwright-order-manager` instead of
|
|
62
|
+
> `@playwright/test`. Everything else (`expect`, `Page`, `Browser`, etc.)
|
|
63
|
+
> works exactly the same — it is a drop-in replacement.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### Step 2 — Copy the merge config template
|
|
68
|
+
```bash
|
|
69
|
+
cp node_modules/playwright-order-manager/templates/playwright.merge.config.ts .
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### Step 3 — Run
|
|
75
|
+
```bash
|
|
76
|
+
npx pw-order
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
That's it. The runner will:
|
|
80
|
+
1. Discover all your tests
|
|
81
|
+
2. Group them into priority buckets
|
|
82
|
+
3. Execute buckets in order
|
|
83
|
+
4. Write an HTML report to `./ordered-results/ordered-report.html`
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Execution Order
|
|
88
|
+
|
|
89
|
+
Given tests tagged with various priorities, the execution order is always:
|
|
90
|
+
```
|
|
91
|
+
[@runFirst tests] → [@P1 tests] → [@P2 tests] → [@P3 tests] → [@P4 tests] → [untagged tests] → [@runLast tests]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- Empty buckets are skipped entirely
|
|
95
|
+
- `@runLast` always executes, even if earlier buckets failed — it is your cleanup guarantee
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## CLI Reference
|
|
100
|
+
```bash
|
|
101
|
+
npx pw-order [options]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| Flag | Description | Default |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `--order-mode` | `priority` or `basic` | `priority` |
|
|
107
|
+
| `--failure-policy` | `critical`, `continue`, or `immediate` | `critical` |
|
|
108
|
+
| `--project` | Playwright project name (e.g. `chromium`) | all projects |
|
|
109
|
+
| `--config` | Path to your `playwright.config.ts` | `./playwright.config.ts` |
|
|
110
|
+
| `--report-root` | Directory for output files | `./ordered-results` |
|
|
111
|
+
|
|
112
|
+
**Examples:**
|
|
113
|
+
```bash
|
|
114
|
+
# Run with a specific project
|
|
115
|
+
npx pw-order --project=chromium
|
|
116
|
+
|
|
117
|
+
# Continue running even after failures
|
|
118
|
+
npx pw-order --failure-policy=continue
|
|
119
|
+
|
|
120
|
+
# Stop immediately on any failure
|
|
121
|
+
npx pw-order --failure-policy=immediate
|
|
122
|
+
|
|
123
|
+
# Custom config path
|
|
124
|
+
npx pw-order --config=./e2e/playwright.config.ts
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Failure Policies
|
|
130
|
+
|
|
131
|
+
| Policy | Behaviour |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `critical` | Stop the run if a bucket marked **critical** fails. Only `@runFirst` buckets are critical by default. |
|
|
134
|
+
| `immediate` | Stop on the very first failure, regardless of bucket. |
|
|
135
|
+
| `continue` | Never stop early. Always run all buckets and collect all results. |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Environment Variables
|
|
140
|
+
|
|
141
|
+
All CLI flags have equivalent environment variables. Useful for CI pipelines:
|
|
142
|
+
|
|
143
|
+
| Variable | Equivalent Flag |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `ORDER_MODE` | `--order-mode` |
|
|
146
|
+
| `FAILURE_POLICY` | `--failure-policy` |
|
|
147
|
+
| `ORDERED_REPORT_ROOT` | `--report-root` |
|
|
148
|
+
| `PLAYWRIGHT_CONFIG` | `--config` |
|
|
149
|
+
| `PLAYWRIGHT_PROJECT` | `--project` (comma-separated for multiple) |
|
|
150
|
+
| `ORDERED_DEBUG` | Enables verbose debug logging |
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Programmatic Usage
|
|
155
|
+
|
|
156
|
+
If you want to embed ordered execution into your own script:
|
|
157
|
+
```typescript
|
|
158
|
+
import { TestOrderManager } from 'playwright-order-manager';
|
|
159
|
+
|
|
160
|
+
const exitCode = await TestOrderManager.run({
|
|
161
|
+
orderMode: 'priority',
|
|
162
|
+
failurePolicy: 'continue',
|
|
163
|
+
project: 'chromium',
|
|
164
|
+
reportRoot: './test-output',
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
process.exit(exitCode);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Using `OrderedExecution` directly
|
|
173
|
+
|
|
174
|
+
If you only want the bucketing algorithm without the full runner:
|
|
175
|
+
```typescript
|
|
176
|
+
import { OrderedExecution, RunnerConstants } from 'playwright-order-manager';
|
|
177
|
+
import type { DiscoveredTestCase } from 'playwright-order-manager';
|
|
178
|
+
|
|
179
|
+
const tests: DiscoveredTestCase[] = [ /* ... */ ];
|
|
180
|
+
|
|
181
|
+
const buckets = OrderedExecution.buildBuckets({
|
|
182
|
+
tests,
|
|
183
|
+
orderMode: 'priority',
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const { runFirst, middle, runLast } = OrderedExecution.groupBuckets(buckets);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Output Files
|
|
192
|
+
|
|
193
|
+
After a run, the `ordered-results/` directory contains:
|
|
194
|
+
|
|
195
|
+
| File | Description |
|
|
196
|
+
|---|---|
|
|
197
|
+
| `ordered-report.html` | Full HTML report — open in any browser |
|
|
198
|
+
| `ordered-summary.json` | Machine-readable summary of the entire run |
|
|
199
|
+
| `ordered-discovery.json` | List of all discovered tests (written during `--list` phase) |
|
|
200
|
+
| `bucket-N-*.json` | Per-bucket Playwright JSON reports (intermediate, safe to delete) |
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## HTML Report Features
|
|
205
|
+
|
|
206
|
+
The HTML report is self-contained — no internet connection required. It includes:
|
|
207
|
+
|
|
208
|
+
- Overall pass/fail status with progress bar
|
|
209
|
+
- Bucket navigation bar — jump to any bucket, colour-coded by result
|
|
210
|
+
- Per-bucket execution timestamps — see exactly when each bucket ran
|
|
211
|
+
- Per-test tags — verify tests landed in the correct bucket
|
|
212
|
+
- Flaky test detection — tests that passed only after retries are marked
|
|
213
|
+
- Collapsible buckets — passing buckets auto-collapse when failures exist
|
|
214
|
+
- Inline error preview — first line of error visible without expanding
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## CI Integration
|
|
219
|
+
|
|
220
|
+
### GitHub Actions
|
|
221
|
+
```yaml
|
|
222
|
+
- name: Run ordered tests
|
|
223
|
+
run: npx pw-order --project=chromium
|
|
224
|
+
env:
|
|
225
|
+
ORDER_MODE: priority
|
|
226
|
+
FAILURE_POLICY: critical
|
|
227
|
+
|
|
228
|
+
- name: Upload report
|
|
229
|
+
uses: actions/upload-artifact@v4
|
|
230
|
+
if: always()
|
|
231
|
+
with:
|
|
232
|
+
name: ordered-test-report
|
|
233
|
+
path: ordered-results/
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Licence
|
|
239
|
+
|
|
240
|
+
MIT © [rajeshyemul](https://github.com/rajeshyemul)
|
package/bin/run.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* bin/run.js — CLI entry point for playwright-order-manager
|
|
5
|
+
*
|
|
6
|
+
* This file is intentionally plain JavaScript (not TypeScript).
|
|
7
|
+
* It runs directly from node_modules/.bin/pw-order and calls into
|
|
8
|
+
* the compiled dist/ output.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* npx pw-order
|
|
12
|
+
* npx pw-order --project=chromium
|
|
13
|
+
* npx pw-order --project=chromium --order-mode=priority
|
|
14
|
+
*
|
|
15
|
+
* All flags are forwarded to the runner. Playwright-specific flags
|
|
16
|
+
* (like --project) are forwarded directly to Playwright.
|
|
17
|
+
* Runner-specific flags (like --order-mode) are parsed here.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
'use strict';
|
|
21
|
+
|
|
22
|
+
const { TestOrderManager } = require('../dist/runner/TestOrderManager');
|
|
23
|
+
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// CLI ARG PARSING
|
|
26
|
+
// We keep this intentionally simple — no external arg-parsing library.
|
|
27
|
+
// The supported flags are few and well-defined.
|
|
28
|
+
// =============================================================================
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Parses a single --key=value or --key value argument pair.
|
|
32
|
+
* Returns { key, value } or null if the arg doesn't match the expected key.
|
|
33
|
+
*/
|
|
34
|
+
function parseFlag(args, flag) {
|
|
35
|
+
for (let i = 0; i < args.length; i++) {
|
|
36
|
+
const arg = args[i];
|
|
37
|
+
|
|
38
|
+
// --flag=value form
|
|
39
|
+
if (arg.startsWith(`--${flag}=`)) {
|
|
40
|
+
return arg.slice(`--${flag}=`.length);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// --flag value form (next arg is the value)
|
|
44
|
+
if (arg === `--${flag}` && i + 1 < args.length) {
|
|
45
|
+
return args[i + 1];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Collects all args that are NOT recognised runner flags.
|
|
53
|
+
* These get forwarded to Playwright as extraArgs.
|
|
54
|
+
*/
|
|
55
|
+
function collectExtraArgs(args) {
|
|
56
|
+
const runnerFlags = new Set([
|
|
57
|
+
'--order-mode',
|
|
58
|
+
'--failure-policy',
|
|
59
|
+
'--report-root',
|
|
60
|
+
'--config',
|
|
61
|
+
'--merge-config',
|
|
62
|
+
'--project',
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
const extra = [];
|
|
66
|
+
let i = 0;
|
|
67
|
+
|
|
68
|
+
while (i < args.length) {
|
|
69
|
+
const arg = args[i];
|
|
70
|
+
|
|
71
|
+
// Check if this is a known runner flag in --flag=value form
|
|
72
|
+
const isKnownFlagWithEquals = [...runnerFlags].some((f) =>
|
|
73
|
+
arg.startsWith(`${f}=`) || arg === f
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (isKnownFlagWithEquals) {
|
|
77
|
+
// If it's --flag value form (no =), skip the next arg too
|
|
78
|
+
if (!arg.includes('=')) i++;
|
|
79
|
+
i++;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
extra.push(arg);
|
|
84
|
+
i++;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return extra;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// =============================================================================
|
|
91
|
+
// MAIN
|
|
92
|
+
// =============================================================================
|
|
93
|
+
|
|
94
|
+
async function main() {
|
|
95
|
+
// argv[0] = node, argv[1] = this script, argv[2+] = user args
|
|
96
|
+
const args = process.argv.slice(2);
|
|
97
|
+
|
|
98
|
+
// Parse runner-specific flags
|
|
99
|
+
const orderMode = parseFlag(args, 'order-mode');
|
|
100
|
+
const failurePolicy = parseFlag(args, 'failure-policy');
|
|
101
|
+
const reportRoot = parseFlag(args, 'report-root');
|
|
102
|
+
const config = parseFlag(args, 'config');
|
|
103
|
+
const mergeConfig = parseFlag(args, 'merge-config');
|
|
104
|
+
const project = parseFlag(args, 'project');
|
|
105
|
+
|
|
106
|
+
// Everything else gets forwarded to Playwright unchanged
|
|
107
|
+
const extraArgs = collectExtraArgs(args);
|
|
108
|
+
|
|
109
|
+
// Build the RunConfig — only include fields that were actually provided
|
|
110
|
+
// so that env vars and defaults fill in the rest correctly
|
|
111
|
+
const runConfig = {};
|
|
112
|
+
|
|
113
|
+
if (orderMode) runConfig.orderMode = orderMode;
|
|
114
|
+
if (failurePolicy) runConfig.failurePolicy = failurePolicy;
|
|
115
|
+
if (reportRoot) runConfig.reportRoot = reportRoot;
|
|
116
|
+
if (config) runConfig.playwrightConfigPath = config;
|
|
117
|
+
if (mergeConfig) runConfig.mergeConfigPath = mergeConfig;
|
|
118
|
+
if (project) runConfig.project = project;
|
|
119
|
+
if (extraArgs.length > 0) runConfig.extraArgs = extraArgs;
|
|
120
|
+
|
|
121
|
+
let exitCode = 1;
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
exitCode = await TestOrderManager.run(runConfig);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
console.error(`[pw-order] Unexpected error: ${err.message}`);
|
|
127
|
+
exitCode = 1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
process.exit(exitCode);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
main();
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunnerConstants — the single source of truth for all tags, tokens, and defaults.
|
|
3
|
+
*
|
|
4
|
+
* Every magic string in the package comes from here.
|
|
5
|
+
* No file should ever hardcode '@P1' or '@runFirst' directly.
|
|
6
|
+
*/
|
|
7
|
+
export declare const RunnerConstants: {
|
|
8
|
+
/**
|
|
9
|
+
* Tests tagged with this run in their own bucket before all other buckets.
|
|
10
|
+
* Example test tag: test('@runFirst should seed the database', ...)
|
|
11
|
+
*/
|
|
12
|
+
readonly RUN_FIRST_TAG: "@runFirst";
|
|
13
|
+
/**
|
|
14
|
+
* Tests tagged with this run in their own bucket after all other buckets.
|
|
15
|
+
* Example test tag: test('@runLast should clean up test data', ...)
|
|
16
|
+
*/
|
|
17
|
+
readonly RUN_LAST_TAG: "@runLast";
|
|
18
|
+
/**
|
|
19
|
+
* All valid priority tags, in execution order (highest to lowest).
|
|
20
|
+
* `as const` makes this a readonly tuple: ['@P1', '@P2', '@P3', '@P4']
|
|
21
|
+
* This means TypeScript knows the exact values, not just `string[]`.
|
|
22
|
+
*/
|
|
23
|
+
readonly PRIORITY_TAGS: readonly ["@P1", "@P2", "@P3", "@P4"];
|
|
24
|
+
/**
|
|
25
|
+
* Used as the bucket key for tests that have no priority tag at all.
|
|
26
|
+
* These tests run after all prioritized buckets.
|
|
27
|
+
*/
|
|
28
|
+
readonly NO_PRIORITY_TOKEN: "NoPriority";
|
|
29
|
+
readonly DEFAULTS: {
|
|
30
|
+
/**
|
|
31
|
+
* The default OrderMode when ORDER_MODE env var is not set.
|
|
32
|
+
* 'priority' means tests are grouped by @P1/@P2/@P3/@P4 tags.
|
|
33
|
+
*/
|
|
34
|
+
readonly ORDER_MODE: "priority";
|
|
35
|
+
/**
|
|
36
|
+
* The default FailurePolicy when FAILURE_POLICY env var is not set.
|
|
37
|
+
* 'critical' means: stop the run if a critical bucket fails.
|
|
38
|
+
*/
|
|
39
|
+
readonly FAILURE_POLICY: "critical";
|
|
40
|
+
/**
|
|
41
|
+
* The default folder where run output is written.
|
|
42
|
+
* Relative to wherever the user runs the CLI command from.
|
|
43
|
+
*/
|
|
44
|
+
readonly REPORT_ROOT: "ordered-results";
|
|
45
|
+
/**
|
|
46
|
+
* Default filename for the summary JSON written after a full run.
|
|
47
|
+
*/
|
|
48
|
+
readonly SUMMARY_FILENAME: "ordered-summary.json";
|
|
49
|
+
/**
|
|
50
|
+
* Default filename for the HTML report written after a full run.
|
|
51
|
+
*/
|
|
52
|
+
readonly REPORT_FILENAME: "ordered-report.html";
|
|
53
|
+
/**
|
|
54
|
+
* Default filename for the discovery output written during --list phase.
|
|
55
|
+
*/
|
|
56
|
+
readonly DISCOVERY_FILENAME: "ordered-discovery.json";
|
|
57
|
+
};
|
|
58
|
+
readonly BUCKET_KEYS: {
|
|
59
|
+
/** The bucket containing @runFirst tests */
|
|
60
|
+
readonly RUN_FIRST: "boundary-run-first";
|
|
61
|
+
/** The bucket containing @runLast tests */
|
|
62
|
+
readonly RUN_LAST: "boundary-run-last";
|
|
63
|
+
/** The bucket containing tests with no priority tag */
|
|
64
|
+
readonly NO_PRIORITY: "none";
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* The type of PRIORITY_TAGS entries, derived directly from the array.
|
|
69
|
+
* Results in: '@P1' | '@P2' | '@P3' | '@P4'
|
|
70
|
+
*/
|
|
71
|
+
export type PriorityTagValue = typeof RunnerConstants.PRIORITY_TAGS[number];
|
|
72
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,eAAe;IAQ1B;;;OAGG;;IAGH;;;OAGG;;IASH;;;;OAIG;;IAQH;;;OAGG;;;QASD;;;WAGG;;QAGH;;;WAGG;;QAGH;;;WAGG;;QAGH;;WAEG;;QAGH;;WAEG;;QAGH;;WAEG;;;;QAWH,4CAA4C;;QAG5C,2CAA2C;;QAG3C,uDAAuD;;;CAIjD,CAAC;AASX;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAC1B,OAAO,eAAe,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RunnerConstants = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* RunnerConstants — the single source of truth for all tags, tokens, and defaults.
|
|
6
|
+
*
|
|
7
|
+
* Every magic string in the package comes from here.
|
|
8
|
+
* No file should ever hardcode '@P1' or '@runFirst' directly.
|
|
9
|
+
*/
|
|
10
|
+
exports.RunnerConstants = {
|
|
11
|
+
// ===========================================================================
|
|
12
|
+
// BOUNDARY TAGS
|
|
13
|
+
// These tags, when attached to a test, force it into a special bucket
|
|
14
|
+
// that runs before or after everything else.
|
|
15
|
+
// ===========================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Tests tagged with this run in their own bucket before all other buckets.
|
|
18
|
+
* Example test tag: test('@runFirst should seed the database', ...)
|
|
19
|
+
*/
|
|
20
|
+
RUN_FIRST_TAG: '@runFirst',
|
|
21
|
+
/**
|
|
22
|
+
* Tests tagged with this run in their own bucket after all other buckets.
|
|
23
|
+
* Example test tag: test('@runLast should clean up test data', ...)
|
|
24
|
+
*/
|
|
25
|
+
RUN_LAST_TAG: '@runLast',
|
|
26
|
+
// ===========================================================================
|
|
27
|
+
// PRIORITY TAGS
|
|
28
|
+
// Used to group tests into priority buckets.
|
|
29
|
+
// P1 = highest priority (runs first), P4 = lowest priority (runs last).
|
|
30
|
+
// ===========================================================================
|
|
31
|
+
/**
|
|
32
|
+
* All valid priority tags, in execution order (highest to lowest).
|
|
33
|
+
* `as const` makes this a readonly tuple: ['@P1', '@P2', '@P3', '@P4']
|
|
34
|
+
* This means TypeScript knows the exact values, not just `string[]`.
|
|
35
|
+
*/
|
|
36
|
+
PRIORITY_TAGS: ['@P1', '@P2', '@P3', '@P4'],
|
|
37
|
+
// ===========================================================================
|
|
38
|
+
// TOKENS
|
|
39
|
+
// Internal identifiers used in bucket keys and report labels.
|
|
40
|
+
// ===========================================================================
|
|
41
|
+
/**
|
|
42
|
+
* Used as the bucket key for tests that have no priority tag at all.
|
|
43
|
+
* These tests run after all prioritized buckets.
|
|
44
|
+
*/
|
|
45
|
+
NO_PRIORITY_TOKEN: 'NoPriority',
|
|
46
|
+
// ===========================================================================
|
|
47
|
+
// DEFAULTS
|
|
48
|
+
// Fallback values used when the user hasn't configured something explicitly.
|
|
49
|
+
// ===========================================================================
|
|
50
|
+
DEFAULTS: {
|
|
51
|
+
/**
|
|
52
|
+
* The default OrderMode when ORDER_MODE env var is not set.
|
|
53
|
+
* 'priority' means tests are grouped by @P1/@P2/@P3/@P4 tags.
|
|
54
|
+
*/
|
|
55
|
+
ORDER_MODE: 'priority',
|
|
56
|
+
/**
|
|
57
|
+
* The default FailurePolicy when FAILURE_POLICY env var is not set.
|
|
58
|
+
* 'critical' means: stop the run if a critical bucket fails.
|
|
59
|
+
*/
|
|
60
|
+
FAILURE_POLICY: 'critical',
|
|
61
|
+
/**
|
|
62
|
+
* The default folder where run output is written.
|
|
63
|
+
* Relative to wherever the user runs the CLI command from.
|
|
64
|
+
*/
|
|
65
|
+
REPORT_ROOT: 'ordered-results',
|
|
66
|
+
/**
|
|
67
|
+
* Default filename for the summary JSON written after a full run.
|
|
68
|
+
*/
|
|
69
|
+
SUMMARY_FILENAME: 'ordered-summary.json',
|
|
70
|
+
/**
|
|
71
|
+
* Default filename for the HTML report written after a full run.
|
|
72
|
+
*/
|
|
73
|
+
REPORT_FILENAME: 'ordered-report.html',
|
|
74
|
+
/**
|
|
75
|
+
* Default filename for the discovery output written during --list phase.
|
|
76
|
+
*/
|
|
77
|
+
DISCOVERY_FILENAME: 'ordered-discovery.json',
|
|
78
|
+
},
|
|
79
|
+
// ===========================================================================
|
|
80
|
+
// BUCKET KEYS
|
|
81
|
+
// Stable string identifiers for each bucket type.
|
|
82
|
+
// Used as keys in BucketPlan and BucketExecutionRecord.
|
|
83
|
+
// ===========================================================================
|
|
84
|
+
BUCKET_KEYS: {
|
|
85
|
+
/** The bucket containing @runFirst tests */
|
|
86
|
+
RUN_FIRST: 'boundary-run-first',
|
|
87
|
+
/** The bucket containing @runLast tests */
|
|
88
|
+
RUN_LAST: 'boundary-run-last',
|
|
89
|
+
/** The bucket containing tests with no priority tag */
|
|
90
|
+
NO_PRIORITY: 'none',
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACU,QAAA,eAAe,GAAG;IAE7B,8EAA8E;IAC9E,gBAAgB;IAChB,sEAAsE;IACtE,6CAA6C;IAC7C,8EAA8E;IAE9E;;;OAGG;IACH,aAAa,EAAE,WAAW;IAE1B;;;OAGG;IACH,YAAY,EAAE,UAAU;IAExB,8EAA8E;IAC9E,gBAAgB;IAChB,6CAA6C;IAC7C,wEAAwE;IACxE,8EAA8E;IAE9E;;;;OAIG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU;IAEpD,8EAA8E;IAC9E,SAAS;IACT,8DAA8D;IAC9D,8EAA8E;IAE9E;;;OAGG;IACH,iBAAiB,EAAE,YAAY;IAE/B,8EAA8E;IAC9E,WAAW;IACX,6EAA6E;IAC7E,8EAA8E;IAE9E,QAAQ,EAAE;QACR;;;WAGG;QACH,UAAU,EAAE,UAAmB;QAE/B;;;WAGG;QACH,cAAc,EAAE,UAAmB;QAEnC;;;WAGG;QACH,WAAW,EAAE,iBAAiB;QAE9B;;WAEG;QACH,gBAAgB,EAAE,sBAAsB;QAExC;;WAEG;QACH,eAAe,EAAE,qBAAqB;QAEtC;;WAEG;QACH,kBAAkB,EAAE,wBAAwB;KAC7C;IAED,8EAA8E;IAC9E,cAAc;IACd,kDAAkD;IAClD,wDAAwD;IACxD,8EAA8E;IAE9E,WAAW,EAAE;QACX,4CAA4C;QAC5C,SAAS,EAAE,oBAAoB;QAE/B,2CAA2C;QAC3C,QAAQ,EAAE,mBAAmB;QAE7B,uDAAuD;QACvD,WAAW,EAAE,MAAM;KACpB;CAEO,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { BucketPlan, BuildBucketOptions } from '../types';
|
|
2
|
+
export declare class OrderedExecution {
|
|
3
|
+
/**
|
|
4
|
+
* Takes a flat list of discovered tests and groups them into ordered buckets.
|
|
5
|
+
*
|
|
6
|
+
* This is the core algorithm of the entire package. The buckets returned
|
|
7
|
+
* here define the execution order — the runner executes them one by one,
|
|
8
|
+
* in the order they appear in this array.
|
|
9
|
+
*
|
|
10
|
+
* @param options - See BuildBucketOptions in types/index.ts
|
|
11
|
+
* @returns An ordered array of BucketPlan objects, ready for execution
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const buckets = OrderedExecution.buildBuckets({
|
|
16
|
+
* tests: discoveredTests,
|
|
17
|
+
* orderMode: 'priority',
|
|
18
|
+
* });
|
|
19
|
+
* // buckets[0] = runFirst tests (if any)
|
|
20
|
+
* // buckets[1] = @P1 tests (if any)
|
|
21
|
+
* // buckets[2] = @P2 tests (if any)
|
|
22
|
+
* // ...and so on
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
static buildBuckets(options: BuildBucketOptions): BucketPlan[];
|
|
26
|
+
/**
|
|
27
|
+
* Splits an array of buckets into three phases for the runner to process.
|
|
28
|
+
*
|
|
29
|
+
* Why split into phases?
|
|
30
|
+
* The runner needs to handle the runFirst bucket specially — if it fails
|
|
31
|
+
* and the FailurePolicy is 'critical', we stop before running any middle
|
|
32
|
+
* buckets. Similarly, runLast should always attempt to run (cleanup)
|
|
33
|
+
* even if middle buckets failed.
|
|
34
|
+
*
|
|
35
|
+
* @param buckets - The output from buildBuckets()
|
|
36
|
+
* @returns An object with three arrays: runFirst, middle, runLast
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const { runFirst, middle, runLast } = OrderedExecution.groupBuckets(buckets);
|
|
41
|
+
* // Run runFirst phase, check failure policy
|
|
42
|
+
* // Run middle phase buckets in order
|
|
43
|
+
* // Run runLast phase regardless of middle results
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
static groupBuckets(buckets: BucketPlan[]): {
|
|
47
|
+
runFirst: BucketPlan[];
|
|
48
|
+
middle: BucketPlan[];
|
|
49
|
+
runLast: BucketPlan[];
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=OrderedExecution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderedExecution.d.ts","sourceRoot":"","sources":["../../src/core/OrderedExecution.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,UAAU,EACV,kBAAkB,EAEnB,MAAM,UAAU,CAAC;AAiNlB,qBAAa,gBAAgB;IAC3B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,kBAAkB,GAAG,UAAU,EAAE;IAyC9D;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG;QAC1C,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,MAAM,EAAE,UAAU,EAAE,CAAC;QACrB,OAAO,EAAE,UAAU,EAAE,CAAC;KACvB;CAiBF"}
|