@andrii_kremlovskyi/playwright-failure-analyzer 0.0.0-stage → 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 The Playwright Report Viewer Authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,345 @@
1
- # Temporary Holding Version
1
+ # Playwright Failure Analyzer
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Explain Playwright test failures with GitHub Copilot, using the same evidence
4
+ engine from a local application or CI. Includes a TypeScript library and CLI.
5
+
6
+ ```text
7
+ HTML report + trace attachments
8
+ -> playwright-traces-reader
9
+ -> per-attempt evidence and small-model explanations
10
+ -> big-model grouping
11
+ -> JSON evidence and Markdown reports
12
+ ```
13
+
14
+ This package does not run tests, start a dashboard, edit test code, publish
15
+ artifacts, or create defects. It is not affiliated with Microsoft or the
16
+ Playwright team.
17
+
18
+ ## Requirements
19
+
20
+ - Node.js `^20.19.0 || >=22.12.0 <27`.
21
+ - A complete Playwright Test HTML report with traces for the attempts to analyze.
22
+ - GitHub Copilot access and available small/big model IDs.
23
+ - Normal npm installation, including optional dependencies for the native SDK
24
+ runtime. A global Copilot CLI installation is not needed.
25
+
26
+ The trace reader owns trace-version compatibility. Missing traces or incomplete
27
+ metadata are reported as incomplete coverage, not as a clean test run. Failed
28
+ retry attempts remain independent even when the test eventually passes.
29
+
30
+ ## Installation
31
+
32
+ After the package has been published:
33
+
34
+ ```sh
35
+ npm install --save-dev @andrii_kremlovskyi/playwright-failure-analyzer
36
+ ```
37
+
38
+ Applications importing the library at runtime should use a production dependency
39
+ instead of `--save-dev`.
40
+
41
+ ## CLI
42
+
43
+ ```sh
44
+ npx playwright-failure-analyzer analyze \
45
+ --report ./playwright-report \
46
+ --output ./failure-analysis \
47
+ --small-model "<available-model-id>" \
48
+ --big-model "<available-model-id>" \
49
+ --timeout-ms 900000
50
+ ```
51
+
52
+ For PowerShell, put the command on one line or use PowerShell continuation syntax.
53
+ Quote paths containing spaces.
54
+
55
+ | Option | Behavior |
56
+ | ------------------------------- | ------------------------------------------------------------------------ |
57
+ | `--report` | HTML report root, containing `index.html` |
58
+ | `--output` | Parent directory for a fresh `run-*` output; must not overlap the report |
59
+ | `--small-model` / `--big-model` | Required exact model IDs; never silently substituted |
60
+ | `--workers` | Reader preparation workers, 1-5; default 4 |
61
+ | `--concurrency` | Concurrent attempt analyses; default 3 |
62
+ | `--timeout-ms` | Optional overall deadline, including preparation and AI stages |
63
+ | `--max-attempts` | Optional cap in manifest order; omissions make the result partial |
64
+ | `--format` | `json` (default) or `text` |
65
+
66
+ No overall deadline or attempt cap is imposed unless configured. Always set a
67
+ deadline shorter than the workflow job timeout in CI. Each attempt request has a
68
+ three-minute timeout; grouping/evidence/repair requests each have a ten-minute
69
+ timeout. Correction and repair requests can incur additional usage.
70
+
71
+ Other commands:
72
+
73
+ ```sh
74
+ npx playwright-failure-analyzer check-access
75
+ npx playwright-failure-analyzer models
76
+ npx playwright-failure-analyzer --help
77
+ npx playwright-failure-analyzer --version
78
+ ```
79
+
80
+ Access/model discovery is not proof that a billable inference request succeeds.
81
+ Help/version and verified no-failure runs do not start Copilot.
82
+
83
+ JSON mode emits one final object to stdout. Count/phase progress is written to
84
+ stderr. Tokens are not accepted on the command line. Technical errors and
85
+ diagnostics are explicit; inspect the generated result even if the command exits
86
+ nonzero.
87
+
88
+ | Exit code | Meaning |
89
+ | --------- | ----------------------------------------------------------------------------- |
90
+ | 0 | Complete analysis or verified no failures |
91
+ | 1 | Invalid arguments, authentication failure, fatal preparation/output error |
92
+ | 2 | Partial analysis, missing/unknown coverage, source-only fallback, or deadline |
93
+ | 130 / 143 | SIGINT / SIGTERM cancellation |
94
+
95
+ The CLI's exit code describes analysis, not the original Playwright test result.
96
+ Do not use it to turn a failing regression run green.
97
+
98
+ ## Authentication
99
+
100
+ Resolution order:
101
+
102
+ 1. Explicit library token.
103
+ 2. `COPILOT_GITHUB_TOKEN`.
104
+ 3. `GH_TOKEN`.
105
+ 4. `GITHUB_TOKEN`.
106
+ 5. Stored local Copilot/GitHub CLI credentials.
107
+
108
+ CI disables stored-login fallback by default. Local usage supports existing CLI
109
+ login; the package never starts an interactive login or stores a supplied token.
110
+ Explicit `allowStoredLogin: false` is available for headless library consumers.
111
+
112
+ In GitHub Actions, pass `${{ github.token }}` through `COPILOT_GITHUB_TOKEN` and
113
+ grant the job `copilot-requests: write`. Organization-owned repositories require
114
+ the **Allow use of Copilot CLI billed to the organization** policy. This does not
115
+ require a personal access token. Organization policies, model access, and usage
116
+ budgets still apply.
117
+
118
+ [GitHub's authentication instructions](https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli-in-actions)
119
+
120
+ ## Library API
121
+
122
+ ```ts
123
+ import { analyzeFailures } from "@andrii_kremlovskyi/playwright-failure-analyzer";
124
+
125
+ const result = await analyzeFailures({
126
+ reportPath: "/reports/playwright-report",
127
+ outputDir: "/reports/failure-analysis",
128
+ smallModel: "your-small-model-id",
129
+ bigModel: "your-big-model-id",
130
+ authentication: {
131
+ token: process.env.COPILOT_GITHUB_TOKEN,
132
+ allowStoredLogin: false,
133
+ },
134
+ workers: 4,
135
+ concurrency: 3,
136
+ timeoutMs: 900_000,
137
+ onProgress(event) {
138
+ console.log(event.phase);
139
+ },
140
+ });
141
+
142
+ console.log(result.status, result.runDir);
143
+ ```
144
+
145
+ CommonJS is also supported:
146
+
147
+ ```js
148
+ const {
149
+ analyzeFailures,
150
+ } = require("@andrii_kremlovskyi/playwright-failure-analyzer");
151
+ ```
152
+
153
+ `AnalysisResult` contains coverage, attempt counts, warnings/errors, grouping
154
+ diagnostics, versions, duration, and artifact paths. Complete, partial,
155
+ no-failure, and cancelled results are returned. Fatal failures after a run is
156
+ allocated throw `FailureAnalysisError`, whose `result` points to retained output.
157
+ Earlier input/preparation setup errors can occur before any run is allocated.
158
+ Output failures are never disguised as successful analysis.
159
+
160
+ An `AbortSignal` cancels the high-level runner, stops new work, and shuts down
161
+ its owned reader process tree and SDK runtime. Already completed evidence is
162
+ retained. Cancellation during preparation can leave incomplete raw evidence
163
+ inside that run; it is not a completed manifest.
164
+
165
+ ### Reusing prepared evidence
166
+
167
+ Applications that own report preparation and artifact lifecycle can use:
168
+
169
+ ```ts
170
+ import {
171
+ withCopilotAnalysisClient,
172
+ analyzeRun,
173
+ groupRun,
174
+ isAnalyzableEntry,
175
+ validateManifest,
176
+ } from "@andrii_kremlovskyi/playwright-failure-analyzer";
177
+
178
+ await withCopilotAnalysisClient(
179
+ { smallModel, bigModel },
180
+ optionalToken,
181
+ async (client) => {
182
+ // The application prepares/registers a fresh run here, after preflight.
183
+ const manifest = validateManifest(preparedJson, actualRunDirectory);
184
+ const analysis = await analyzeRun(
185
+ client,
186
+ actualRunDirectory,
187
+ manifest,
188
+ smallModel,
189
+ onAttemptProgress,
190
+ );
191
+ if (manifest.failures.filter(isAnalyzableEntry).length > 1) {
192
+ await groupRun(
193
+ client,
194
+ actualRunDirectory,
195
+ manifest,
196
+ analysis.records,
197
+ smallModel,
198
+ bigModel,
199
+ );
200
+ }
201
+ },
202
+ { signal },
203
+ );
204
+ ```
205
+
206
+ Prepared-run APIs write only their own evidence/grouping files and refuse
207
+ conflicting output. They do not replace/delete prior runs or manage report IDs.
208
+ The client wrapper owns runtime shutdown; when supplying another `AnalysisClient`,
209
+ the caller must arrange cancellation of active requests and client cleanup.
210
+
211
+ `copilotAccessCheck` and `copilotModels` support separate access checks and model
212
+ pickers. Pure evidence renderers, schema-v4 types, and artifact constants are also
213
+ exported. Importing the package does not start the runtime.
214
+
215
+ ## Output
216
+
217
+ ```text
218
+ failure-analysis/
219
+ run-<unique-id>/
220
+ index.json
221
+ analysis-result.json
222
+ summary.md
223
+ grouped-analysis.md
224
+ <attempt>/
225
+ failure.json
226
+ error.md
227
+ evidence.json
228
+ ai-analysis.md
229
+ ...raw reader evidence
230
+ ```
231
+
232
+ - Reader manifests keep schema version 2; canonical AI evidence keeps schema
233
+ version 4. The new run envelope has schema version 1.
234
+ - `error.md` is ground truth. Each fenced Error details block remains an exact,
235
+ ordered source issue in `evidence.json`.
236
+ - Invalid model output gets one correction; a second invalid response retains
237
+ low-confidence source-only issues with a warning and partial run status.
238
+ - Grouping uses one bounded evidence round and one reference repair, preserving
239
+ valid issues and explicitly recording provisional/unclassified results.
240
+ - `summary.md` is deterministic, including zero/single-attempt and failed runs.
241
+ It includes counts/status only, not test names, source blocks, or network bodies.
242
+ - Grouped Markdown exists only when grouping produces a valid artifact.
243
+ - `attemptUsage` contains token counts only when the SDK reports them. Grouping
244
+ usage is recorded in its diagnostics; neither is a currency/billing estimate.
245
+ - Artifact pointers are relative to the run directory. `runDir` and original
246
+ reader trace paths describe the machine that produced them; do not trust them
247
+ as filesystem authority after downloading an artifact.
248
+
249
+ ## GitHub Actions consumption
250
+
251
+ After publication, add the package to your project's manifest/lockfile and an
252
+ npm script:
253
+
254
+ ```json
255
+ {
256
+ "scripts": {
257
+ "analyze:failures": "playwright-failure-analyzer analyze"
258
+ }
259
+ }
260
+ ```
261
+
262
+ The analysis job installs dependencies, downloads the exact report artifact from
263
+ the test job, and then runs:
264
+
265
+ ```yaml
266
+ - name: Analyze failures
267
+ env:
268
+ COPILOT_GITHUB_TOKEN: ${{ github.token }}
269
+ SMALL_MODEL: ${{ vars.COPILOT_SMALL_MODEL }}
270
+ BIG_MODEL: ${{ vars.COPILOT_BIG_MODEL }}
271
+ run: |
272
+ npm run analyze:failures -- \
273
+ --report playwright-report \
274
+ --output failure-analysis \
275
+ --small-model "$SMALL_MODEL" \
276
+ --big-model "$BIG_MODEL" \
277
+ --timeout-ms 900000
278
+ ```
279
+
280
+ This is a step fragment, not a complete workflow. Give the analysis job
281
+ `contents: read` and `copilot-requests: write`, an explicit failed-prerequisite
282
+ condition, and time for artifact upload after analysis fails. Keep application
283
+ secrets and deployment permissions out of the analysis job. Retain the original
284
+ test failure. Authentication/model access must be smoke-tested with the installed
285
+ SDK in the target organization; the unit suite does not make billable requests.
286
+
287
+ ## Data handling and limitations
288
+
289
+ **Evidence is not automatically redacted.** Error Markdown, test source,
290
+ page content, and selected network data are sent to GitHub Copilot. Obtain
291
+ approval for the report content before using real regression reports. Restrict
292
+ artifact access/retention. Do not paste raw evidence into public workflow
293
+ summaries. The model can only infer causes supported by supplied evidence.
294
+
295
+ Sessions expose no tools, skip repository instructions/skills/hooks, disable
296
+ configuration discovery, and run in an isolated working directory. This limits
297
+ agent actions; it does not make sensitive evidence safe to disclose. BYOK/provider
298
+ environment overrides are not forwarded to the owned runtime.
299
+
300
+ Screenshots can be extracted for human inspection, but are not automatically
301
+ submitted for visual analysis. Global setup/infrastructure errors and failures
302
+ without trace evidence are not diagnosed by a report-only model fallback.
303
+
304
+ ## Development and publishing
305
+
306
+ ```sh
307
+ npm ci
308
+ npm test
309
+ npm pack --dry-run
310
+ npm pack
311
+ ```
312
+
313
+ Tests use generated reports and fake model clients. The runtime smoke test starts
314
+ the bundled runtime and requests local status only, using a synthetic credential;
315
+ it performs no model inference. No real reports or credentials belong in fixtures.
316
+
317
+ Release checks cover Windows (Node 22) and Linux (Node 24), including independent
318
+ tarball installation, CommonJS/ESM imports, declarations, the executable, and
319
+ owned process-tree shutdown. The declared engine range follows dependency
320
+ requirements; every Node version and processor architecture has not been tested.
321
+ Live small/big-model inference through the packaged SDK still requires a separate
322
+ target-environment smoke test before production use.
323
+
324
+ The SDK is deliberately pinned to 1.0.14: its supported Zod range can resolve a
325
+ patched release, whereas SDK 1.0.28 pins vulnerable Zod 4.3.6. The lockfile records
326
+ the tested resolution. Recheck audit and runtime compatibility when upgrading;
327
+ do not use a library-local override as a supposed fix for downstream consumers.
328
+
329
+ Only `dist/`, this README, the MIT license, and npm's package manifest are
330
+ published. The planning document, tests, local caches, and tarballs are excluded.
331
+
332
+ Publication is manual:
333
+
334
+ ```sh
335
+ npm publish --access public
336
+ ```
337
+
338
+ Publishing permissions/credentials are separate from Copilot authentication.
339
+ This command is documentation for the package owner, not an automated release
340
+ step. Consumer migration should begin only after publication is confirmed.
341
+
342
+ ## License
343
+
344
+ MIT. The extracted engine retains the copyright notice of the Playwright Report
345
+ Viewer Authors; see [LICENSE](LICENSE).
@@ -0,0 +1,79 @@
1
+ import { type AnalyzeProgress, type TokenUsage } from "./copilot-analyzer";
2
+ import { type GroupRunResult } from "./copilot-grouper";
3
+ import type { AuthenticationOptions } from "./copilot-client";
4
+ import { type Coverage } from "./reader";
5
+ import { AnalysisError } from "./shared";
6
+ export declare const ANALYSIS_RESULT_FILENAME = "analysis-result.json";
7
+ export declare const SUMMARY_FILENAME = "summary.md";
8
+ export declare const ANALYSIS_RESULT_SCHEMA_VERSION = 1;
9
+ export interface AnalysisOptions {
10
+ reportPath: string;
11
+ outputDir: string;
12
+ smallModel: string;
13
+ bigModel: string;
14
+ authentication?: AuthenticationOptions;
15
+ workers?: number;
16
+ concurrency?: number;
17
+ timeoutMs?: number;
18
+ maxAttempts?: number;
19
+ signal?: AbortSignal;
20
+ onProgress?: (event: AnalysisProgress) => void;
21
+ }
22
+ export type AnalysisProgress = {
23
+ phase: "preparation" | "grouping" | "complete";
24
+ } | {
25
+ phase: "analysis";
26
+ progress: AnalyzeProgress;
27
+ };
28
+ export interface AnalysisResult {
29
+ schemaVersion: typeof ANALYSIS_RESULT_SCHEMA_VERSION;
30
+ status: "complete" | "no-failures" | "partial" | "failed" | "cancelled";
31
+ runDir: string;
32
+ coverage: Coverage;
33
+ attempts: {
34
+ total: number;
35
+ analyzed: number;
36
+ unavailable: number;
37
+ excluded: number;
38
+ omitted: number;
39
+ fallbacks: number;
40
+ };
41
+ grouping: {
42
+ status: "complete" | "partial" | "failed" | "not-needed";
43
+ problemCount?: number;
44
+ diagnostics?: GroupRunResult["diagnostics"];
45
+ };
46
+ models: {
47
+ smallModel: string;
48
+ bigModel: string;
49
+ };
50
+ versions: {
51
+ analyzer: string;
52
+ reader: string;
53
+ sdk: string;
54
+ runtime: string;
55
+ node: string;
56
+ };
57
+ durationMs: number;
58
+ attemptUsage?: TokenUsage;
59
+ warnings: string[];
60
+ errors: Array<{
61
+ stage: string;
62
+ code: string;
63
+ message: string;
64
+ }>;
65
+ artifacts: {
66
+ manifest?: string;
67
+ result: string;
68
+ summary: string;
69
+ groupedAnalysis?: string;
70
+ attempts: string[];
71
+ };
72
+ }
73
+ export declare class FailureAnalysisError extends AnalysisError {
74
+ readonly result: AnalysisResult;
75
+ constructor(result: AnalysisResult, cause: unknown);
76
+ }
77
+ export declare function renderSummary(result: AnalysisResult): string;
78
+ export declare function validateOptions(options: AnalysisOptions): void;
79
+ export declare function analyzeFailures(options: AnalysisOptions): Promise<AnalysisResult>;