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.
Files changed (37) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +240 -0
  3. package/bin/run.js +133 -0
  4. package/dist/constants/index.d.ts +72 -0
  5. package/dist/constants/index.d.ts.map +1 -0
  6. package/dist/constants/index.js +93 -0
  7. package/dist/constants/index.js.map +1 -0
  8. package/dist/core/OrderedExecution.d.ts +52 -0
  9. package/dist/core/OrderedExecution.d.ts.map +1 -0
  10. package/dist/core/OrderedExecution.js +253 -0
  11. package/dist/core/OrderedExecution.js.map +1 -0
  12. package/dist/core/OrderedReportParser.d.ts +38 -0
  13. package/dist/core/OrderedReportParser.d.ts.map +1 -0
  14. package/dist/core/OrderedReportParser.js +169 -0
  15. package/dist/core/OrderedReportParser.js.map +1 -0
  16. package/dist/core/OrderedSummary.d.ts +20 -0
  17. package/dist/core/OrderedSummary.d.ts.map +1 -0
  18. package/dist/core/OrderedSummary.js +747 -0
  19. package/dist/core/OrderedSummary.js.map +1 -0
  20. package/dist/fixtures/index.d.ts +30 -0
  21. package/dist/fixtures/index.d.ts.map +1 -0
  22. package/dist/fixtures/index.js +212 -0
  23. package/dist/fixtures/index.js.map +1 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +31 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/runner/TestOrderManager.d.ts +62 -0
  29. package/dist/runner/TestOrderManager.d.ts.map +1 -0
  30. package/dist/runner/TestOrderManager.js +490 -0
  31. package/dist/runner/TestOrderManager.js.map +1 -0
  32. package/dist/types/index.d.ts +215 -0
  33. package/dist/types/index.d.ts.map +1 -0
  34. package/dist/types/index.js +6 -0
  35. package/dist/types/index.js.map +1 -0
  36. package/package.json +65 -0
  37. package/templates/playwright.merge.config.ts +57 -0
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Controls how tests are grouped and sequenced before execution.
3
+ *
4
+ * - 'basic' → runs tests in the order Playwright discovers them. No reordering.
5
+ * - 'priority' → groups tests by @P1/@P2/@P3/@P4 tags, runs highest priority first.
6
+ * - 'custom' → reserved for v2. Allows user-defined ordering functions.
7
+ */
8
+ export type OrderMode = 'basic' | 'priority' | 'custom';
9
+ /**
10
+ * Controls what happens when a bucket (group of tests) fails.
11
+ *
12
+ * - 'critical' → if a bucket marked critical fails, stop the entire run immediately.
13
+ * - 'continue' → log the failure and continue running remaining buckets.
14
+ * - 'immediate' → stop the entire run on the very first failure, regardless of bucket.
15
+ */
16
+ export type FailurePolicy = 'critical' | 'continue' | 'immediate';
17
+ /**
18
+ * The four priority tags your tests can be annotated with.
19
+ * @P1 = highest priority, @P4 = lowest priority.
20
+ */
21
+ export type PriorityTag = '@P1' | '@P2' | '@P3' | '@P4';
22
+ /**
23
+ * How a bucket was formed.
24
+ *
25
+ * - 'boundary' → a special bucket: the @runFirst or @runLast group.
26
+ * - 'priority' → a bucket formed from a @P1/@P2/@P3/@P4 group.
27
+ * - 'none' → a bucket formed from tests with no priority tag (NoPriority group).
28
+ */
29
+ export type BucketKind = 'boundary' | 'priority' | 'none';
30
+ /**
31
+ * Represents a single test case as discovered by `playwright --list`.
32
+ * This is the raw information before any ordering or grouping happens.
33
+ */
34
+ export interface DiscoveredTestCase {
35
+ /** Full test title including describe block(s), e.g. "Login > should redirect on success" */
36
+ title: string;
37
+ /** Absolute path to the test file on disk */
38
+ file: string;
39
+ /** Line number where the test is defined in its file */
40
+ line: number;
41
+ /**
42
+ * All tags attached to this test.
43
+ * e.g. ['@P1', '@runFirst', '@smoke']
44
+ */
45
+ tags: string[];
46
+ /**
47
+ * The project name this test belongs to, as defined in playwright.config.ts.
48
+ * e.g. 'chromium', 'firefox', 'Mobile Chrome'
49
+ */
50
+ project: string;
51
+ }
52
+ /**
53
+ * The outcome of a single test after it has been executed.
54
+ */
55
+ export type TestStatus = 'passed' | 'failed' | 'skipped' | 'timedOut' | 'interrupted';
56
+ /**
57
+ * Represents the result of one test case after a Playwright run completes.
58
+ */
59
+ export interface ExecutedTestResult {
60
+ /** Full test title, matching what was in DiscoveredTestCase */
61
+ title: string;
62
+ /** Absolute path to the test file */
63
+ file: string;
64
+ /** Final status of this test */
65
+ status: TestStatus;
66
+ /**
67
+ * How long this test took to run, in milliseconds.
68
+ * Will be 0 for skipped tests.
69
+ */
70
+ duration: number;
71
+ /**
72
+ * Number of retry attempts used.
73
+ * 0 means the test passed (or failed) on the first try.
74
+ */
75
+ retries: number;
76
+ /** Error message if the test failed. undefined if it passed or was skipped. */
77
+ errorMessage?: string;
78
+ /**
79
+ * Tags attached to this test, e.g. ['@P1', '@runFirst', '@smoke'].
80
+ * Optional — populated during discovery, carried through to the report.
81
+ */
82
+ tags?: string[];
83
+ }
84
+ /**
85
+ * A planned group of tests before execution begins.
86
+ * OrderedExecution.buildBuckets() produces an array of these.
87
+ */
88
+ export interface BucketPlan {
89
+ /**
90
+ * Unique identifier for this bucket.
91
+ * e.g. 'boundary-run-first', 'priority-P1', 'priority-P2', 'none'
92
+ */
93
+ key: string;
94
+ /**
95
+ * Human-readable label shown in logs and reports.
96
+ * e.g. 'Run First', 'Priority P1', 'No Priority'
97
+ */
98
+ label: string;
99
+ /** How this bucket was formed */
100
+ kind: BucketKind;
101
+ /**
102
+ * If true, a failure in this bucket will trigger the FailurePolicy.
103
+ * Boundary buckets (@runFirst) are typically critical.
104
+ */
105
+ critical: boolean;
106
+ /** The tests that belong to this bucket, in execution order */
107
+ tests: DiscoveredTestCase[];
108
+ }
109
+ /**
110
+ * The result record for a bucket after it has been fully executed.
111
+ * One of these is written to disk for every bucket that ran.
112
+ */
113
+ export interface BucketExecutionRecord {
114
+ /** Matches the key from BucketPlan */
115
+ key: string;
116
+ /** Matches the label from BucketPlan */
117
+ label: string;
118
+ /** Whether this bucket was marked critical */
119
+ critical: boolean;
120
+ /** Total number of tests in this bucket */
121
+ totalTests: number;
122
+ /** How many tests passed */
123
+ passed: number;
124
+ /** How many tests failed */
125
+ failed: number;
126
+ /** How many tests were skipped */
127
+ skipped: number;
128
+ /** Total wall-clock time for the entire bucket, in milliseconds */
129
+ duration: number;
130
+ /** The final status of the bucket as a whole */
131
+ status: 'passed' | 'failed' | 'skipped';
132
+ /**
133
+ * ISO 8601 timestamp of when this bucket started executing.
134
+ * Optional — only present when the runner records timing per bucket.
135
+ */
136
+ startedAt?: string;
137
+ /**
138
+ * ISO 8601 timestamp of when this bucket finished executing.
139
+ * Optional — only present when the runner records timing per bucket.
140
+ */
141
+ finishedAt?: string;
142
+ /** Individual test results within this bucket */
143
+ results: ExecutedTestResult[];
144
+ }
145
+ /**
146
+ * The complete summary of an ordered test run.
147
+ * Written to disk as JSON and used to generate the HTML report.
148
+ */
149
+ export interface OrderedRunSummary {
150
+ /** ISO 8601 timestamp of when the run started, e.g. "2024-03-27T10:30:00.000Z" */
151
+ startedAt: string;
152
+ /** ISO 8601 timestamp of when the run finished */
153
+ finishedAt: string;
154
+ /** Total wall-clock duration of the entire run, in milliseconds */
155
+ totalDuration: number;
156
+ /** The OrderMode that was used for this run */
157
+ orderMode: OrderMode;
158
+ /** The FailurePolicy that was used for this run */
159
+ failurePolicy: FailurePolicy;
160
+ /** Summary counts across all buckets */
161
+ totals: {
162
+ tests: number;
163
+ passed: number;
164
+ failed: number;
165
+ skipped: number;
166
+ buckets: number;
167
+ };
168
+ /** Whether the overall run should be considered a success */
169
+ success: boolean;
170
+ /** One record per bucket that was executed */
171
+ buckets: BucketExecutionRecord[];
172
+ }
173
+ /**
174
+ * Options passed to OrderedExecution.buildBuckets().
175
+ * Controls how tests are grouped into buckets.
176
+ */
177
+ export interface BuildBucketOptions {
178
+ /** The discovered tests to group */
179
+ tests: DiscoveredTestCase[];
180
+ /** How to order and group them */
181
+ orderMode: OrderMode;
182
+ /**
183
+ * Tags that force a test to run first, before all other buckets.
184
+ * Defaults to ['@runFirst']
185
+ */
186
+ runFirstTags?: string[];
187
+ /**
188
+ * Tags that force a test to run last, after all other buckets.
189
+ * Defaults to ['@runLast']
190
+ */
191
+ runLastTags?: string[];
192
+ }
193
+ /**
194
+ * The full configuration object for a programmatic run.
195
+ * Passed to TestOrderManager when used as a library (not via CLI).
196
+ * All fields are optional — anything not provided falls back to env vars,
197
+ * then to the defaults in RunnerConstants.
198
+ */
199
+ export interface RunConfig {
200
+ /** Path to your playwright.config.ts. Defaults to ./playwright.config.ts */
201
+ playwrightConfigPath?: string;
202
+ /** Path to your merge config. Defaults to ./playwright.merge.config.ts */
203
+ mergeConfigPath?: string;
204
+ /** Directory where run output (JSON, HTML) is written. Defaults to ./ordered-results */
205
+ reportRoot?: string;
206
+ /** How to order tests. Defaults to 'priority' */
207
+ orderMode?: OrderMode;
208
+ /** What to do when a critical bucket fails. Defaults to 'critical' */
209
+ failurePolicy?: FailurePolicy;
210
+ /** Playwright project name(s) to run, e.g. 'chromium'. Forwarded to Playwright. */
211
+ project?: string | string[];
212
+ /** Any extra flags to forward to the Playwright CLI */
213
+ extraArgs?: string[];
214
+ }
215
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ // =============================================================================
3
+ // ORDER MODES & POLICIES
4
+ // =============================================================================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "playwright-order-manager",
3
+ "version": "0.1.0",
4
+ "description": "Priority-ordered test execution for Playwright",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ },
12
+ "./fixtures": {
13
+ "require": "./dist/fixtures/index.js",
14
+ "types": "./dist/fixtures/index.d.ts"
15
+ }
16
+ },
17
+ "bin": {
18
+ "pw-order": "bin/run.js"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "bin",
23
+ "templates",
24
+ "README.md",
25
+ "CHANGELOG.md"
26
+ ],
27
+ "scripts": {
28
+ "build": "tsc -p tsconfig.build.json",
29
+ "build:watch": "tsc -p tsconfig.build.json --watch",
30
+ "typecheck": "tsc --noEmit",
31
+ "test": "playwright test --config=tests/playwright.config.ts",
32
+ "prepublishOnly": "npm run build"
33
+ },
34
+ "peerDependencies": {
35
+ "@playwright/test": ">=1.40.0"
36
+ },
37
+ "devDependencies": {
38
+ "@playwright/test": "^1.58.2",
39
+ "@types/node": "^22.19.15",
40
+ "typescript": "^5.9.3"
41
+ },
42
+ "dependencies": {
43
+ "dotenv": "^16.0.0"
44
+ },
45
+ "engines": {
46
+ "node": ">=18"
47
+ },
48
+ "keywords": [
49
+ "playwright",
50
+ "test-order",
51
+ "priority",
52
+ "test-runner",
53
+ "ordered-execution"
54
+ ],
55
+ "author": "rajeshyemul",
56
+ "license": "MIT",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "https://github.com/rajeshyemul/playwright-order-manager.git"
60
+ },
61
+ "bugs": {
62
+ "url": "https://github.com/rajeshyemul/playwright-order-manager/issues"
63
+ },
64
+ "homepage": "https://github.com/rajeshyemul/playwright-order-manager#readme"
65
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * playwright.merge.config.ts
3
+ *
4
+ * Copy this file into your project root and adjust as needed.
5
+ *
6
+ * This config is used by playwright-order-manager during the merge phase —
7
+ * after all buckets have executed, it merges their individual JSON reports
8
+ * into one combined HTML report using Playwright's built-in merge-reports.
9
+ *
10
+ * SETUP:
11
+ * 1. Copy this file to your project root:
12
+ * cp node_modules/playwright-order-manager/templates/playwright.merge.config.ts .
13
+ *
14
+ * 2. Point the runner at it via env var or RunConfig:
15
+ * PLAYWRIGHT_MERGE_CONFIG=./playwright.merge.config.ts
16
+ *
17
+ * DOCS:
18
+ * https://playwright.dev/docs/test-reporters#merge-reports-cli
19
+ */
20
+
21
+ import { defineConfig } from '@playwright/test';
22
+ import * as path from 'path';
23
+
24
+ /**
25
+ * The directory where playwright-order-manager writes per-bucket blob reports.
26
+ * Must match the ORDERED_REPORT_ROOT env var (default: 'ordered-results').
27
+ */
28
+ const REPORT_ROOT = process.env['ORDERED_REPORT_ROOT'] ?? 'ordered-results';
29
+
30
+ export default defineConfig({
31
+ // The merge config does not run tests — it only merges reports.
32
+ // Point testDir at a non-existent path so no tests are accidentally discovered.
33
+ testDir: './this-dir-does-not-exist',
34
+
35
+ reporter: [
36
+ // 1. HTML reporter — opens in browser, full test details
37
+ [
38
+ 'html',
39
+ {
40
+ outputFolder: path.join(REPORT_ROOT, 'playwright-html-report'),
41
+ open: 'never', // never auto-open — let the user decide
42
+ },
43
+ ],
44
+
45
+ // 2. JUnit XML — useful for CI systems like Jenkins, GitLab, Azure DevOps
46
+ // Comment this out if you don't need JUnit output.
47
+ [
48
+ 'junit',
49
+ {
50
+ outputFile: path.join(REPORT_ROOT, 'junit-results.xml'),
51
+ },
52
+ ],
53
+
54
+ // 3. Line reporter — shows a summary line in the terminal during merge
55
+ ['line'],
56
+ ],
57
+ });