@andrii_kremlovskyi/playwright-failure-analyzer 0.0.0-stage → 0.1.1

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,349 @@
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
+ The SDK reads local CLI credentials independently of VS Code's sign-in.
113
+ On Windows, the isolated runtime preserves both `PATH` and `PATHEXT` so it can
114
+ discover `gh.exe` and reuse GitHub CLI authentication.
115
+
116
+ In GitHub Actions, pass `${{ github.token }}` through `COPILOT_GITHUB_TOKEN` and
117
+ grant the job `copilot-requests: write`. Organization-owned repositories require
118
+ the **Allow use of Copilot CLI billed to the organization** policy. This does not
119
+ require a personal access token. Organization policies, model access, and usage
120
+ budgets still apply.
121
+
122
+ [GitHub's authentication instructions](https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli-in-actions)
123
+
124
+ ## Library API
125
+
126
+ ```ts
127
+ import { analyzeFailures } from "@andrii_kremlovskyi/playwright-failure-analyzer";
128
+
129
+ const result = await analyzeFailures({
130
+ reportPath: "/reports/playwright-report",
131
+ outputDir: "/reports/failure-analysis",
132
+ smallModel: "your-small-model-id",
133
+ bigModel: "your-big-model-id",
134
+ authentication: {
135
+ token: process.env.COPILOT_GITHUB_TOKEN,
136
+ allowStoredLogin: false,
137
+ },
138
+ workers: 4,
139
+ concurrency: 3,
140
+ timeoutMs: 900_000,
141
+ onProgress(event) {
142
+ console.log(event.phase);
143
+ },
144
+ });
145
+
146
+ console.log(result.status, result.runDir);
147
+ ```
148
+
149
+ CommonJS is also supported:
150
+
151
+ ```js
152
+ const {
153
+ analyzeFailures,
154
+ } = require("@andrii_kremlovskyi/playwright-failure-analyzer");
155
+ ```
156
+
157
+ `AnalysisResult` contains coverage, attempt counts, warnings/errors, grouping
158
+ diagnostics, versions, duration, and artifact paths. Complete, partial,
159
+ no-failure, and cancelled results are returned. Fatal failures after a run is
160
+ allocated throw `FailureAnalysisError`, whose `result` points to retained output.
161
+ Earlier input/preparation setup errors can occur before any run is allocated.
162
+ Output failures are never disguised as successful analysis.
163
+
164
+ An `AbortSignal` cancels the high-level runner, stops new work, and shuts down
165
+ its owned reader process tree and SDK runtime. Already completed evidence is
166
+ retained. Cancellation during preparation can leave incomplete raw evidence
167
+ inside that run; it is not a completed manifest.
168
+
169
+ ### Reusing prepared evidence
170
+
171
+ Applications that own report preparation and artifact lifecycle can use:
172
+
173
+ ```ts
174
+ import {
175
+ withCopilotAnalysisClient,
176
+ analyzeRun,
177
+ groupRun,
178
+ isAnalyzableEntry,
179
+ validateManifest,
180
+ } from "@andrii_kremlovskyi/playwright-failure-analyzer";
181
+
182
+ await withCopilotAnalysisClient(
183
+ { smallModel, bigModel },
184
+ optionalToken,
185
+ async (client) => {
186
+ // The application prepares/registers a fresh run here, after preflight.
187
+ const manifest = validateManifest(preparedJson, actualRunDirectory);
188
+ const analysis = await analyzeRun(
189
+ client,
190
+ actualRunDirectory,
191
+ manifest,
192
+ smallModel,
193
+ onAttemptProgress,
194
+ );
195
+ if (manifest.failures.filter(isAnalyzableEntry).length > 1) {
196
+ await groupRun(
197
+ client,
198
+ actualRunDirectory,
199
+ manifest,
200
+ analysis.records,
201
+ smallModel,
202
+ bigModel,
203
+ );
204
+ }
205
+ },
206
+ { signal },
207
+ );
208
+ ```
209
+
210
+ Prepared-run APIs write only their own evidence/grouping files and refuse
211
+ conflicting output. They do not replace/delete prior runs or manage report IDs.
212
+ The client wrapper owns runtime shutdown; when supplying another `AnalysisClient`,
213
+ the caller must arrange cancellation of active requests and client cleanup.
214
+
215
+ `copilotAccessCheck` and `copilotModels` support separate access checks and model
216
+ pickers. Pure evidence renderers, schema-v4 types, and artifact constants are also
217
+ exported. Importing the package does not start the runtime.
218
+
219
+ ## Output
220
+
221
+ ```text
222
+ failure-analysis/
223
+ run-<unique-id>/
224
+ index.json
225
+ analysis-result.json
226
+ summary.md
227
+ grouped-analysis.md
228
+ <attempt>/
229
+ failure.json
230
+ error.md
231
+ evidence.json
232
+ ai-analysis.md
233
+ ...raw reader evidence
234
+ ```
235
+
236
+ - Reader manifests keep schema version 2; canonical AI evidence keeps schema
237
+ version 4. The new run envelope has schema version 1.
238
+ - `error.md` is ground truth. Each fenced Error details block remains an exact,
239
+ ordered source issue in `evidence.json`.
240
+ - Invalid model output gets one correction; a second invalid response retains
241
+ low-confidence source-only issues with a warning and partial run status.
242
+ - Grouping uses one bounded evidence round and one reference repair, preserving
243
+ valid issues and explicitly recording provisional/unclassified results.
244
+ - `summary.md` is deterministic, including zero/single-attempt and failed runs.
245
+ It includes counts/status only, not test names, source blocks, or network bodies.
246
+ - Grouped Markdown exists only when grouping produces a valid artifact.
247
+ - `attemptUsage` contains token counts only when the SDK reports them. Grouping
248
+ usage is recorded in its diagnostics; neither is a currency/billing estimate.
249
+ - Artifact pointers are relative to the run directory. `runDir` and original
250
+ reader trace paths describe the machine that produced them; do not trust them
251
+ as filesystem authority after downloading an artifact.
252
+
253
+ ## GitHub Actions consumption
254
+
255
+ After publication, add the package to your project's manifest/lockfile and an
256
+ npm script:
257
+
258
+ ```json
259
+ {
260
+ "scripts": {
261
+ "analyze:failures": "playwright-failure-analyzer analyze"
262
+ }
263
+ }
264
+ ```
265
+
266
+ The analysis job installs dependencies, downloads the exact report artifact from
267
+ the test job, and then runs:
268
+
269
+ ```yaml
270
+ - name: Analyze failures
271
+ env:
272
+ COPILOT_GITHUB_TOKEN: ${{ github.token }}
273
+ SMALL_MODEL: ${{ vars.COPILOT_SMALL_MODEL }}
274
+ BIG_MODEL: ${{ vars.COPILOT_BIG_MODEL }}
275
+ run: |
276
+ npm run analyze:failures -- \
277
+ --report playwright-report \
278
+ --output failure-analysis \
279
+ --small-model "$SMALL_MODEL" \
280
+ --big-model "$BIG_MODEL" \
281
+ --timeout-ms 900000
282
+ ```
283
+
284
+ This is a step fragment, not a complete workflow. Give the analysis job
285
+ `contents: read` and `copilot-requests: write`, an explicit failed-prerequisite
286
+ condition, and time for artifact upload after analysis fails. Keep application
287
+ secrets and deployment permissions out of the analysis job. Retain the original
288
+ test failure. Authentication/model access must be smoke-tested with the installed
289
+ SDK in the target organization; the unit suite does not make billable requests.
290
+
291
+ ## Data handling and limitations
292
+
293
+ **Evidence is not automatically redacted.** Error Markdown, test source,
294
+ page content, and selected network data are sent to GitHub Copilot. Obtain
295
+ approval for the report content before using real regression reports. Restrict
296
+ artifact access/retention. Do not paste raw evidence into public workflow
297
+ summaries. The model can only infer causes supported by supplied evidence.
298
+
299
+ Sessions expose no tools, skip repository instructions/skills/hooks, disable
300
+ configuration discovery, and run in an isolated working directory. This limits
301
+ agent actions; it does not make sensitive evidence safe to disclose. BYOK/provider
302
+ environment overrides are not forwarded to the owned runtime.
303
+
304
+ Screenshots can be extracted for human inspection, but are not automatically
305
+ submitted for visual analysis. Global setup/infrastructure errors and failures
306
+ without trace evidence are not diagnosed by a report-only model fallback.
307
+
308
+ ## Development and publishing
309
+
310
+ ```sh
311
+ npm ci
312
+ npm test
313
+ npm pack --dry-run
314
+ npm pack
315
+ ```
316
+
317
+ Tests use generated reports and fake model clients. The runtime smoke test starts
318
+ the bundled runtime and requests local status only, using a synthetic credential;
319
+ it performs no model inference. No real reports or credentials belong in fixtures.
320
+
321
+ Release checks cover Windows (Node 22) and Linux (Node 24), including independent
322
+ tarball installation, CommonJS/ESM imports, declarations, the executable, and
323
+ owned process-tree shutdown. The declared engine range follows dependency
324
+ requirements; every Node version and processor architecture has not been tested.
325
+ Live small/big-model inference through the packaged SDK still requires a separate
326
+ target-environment smoke test before production use.
327
+
328
+ The SDK is deliberately pinned to 1.0.14: its supported Zod range can resolve a
329
+ patched release, whereas SDK 1.0.28 pins vulnerable Zod 4.3.6. The lockfile records
330
+ the tested resolution. Recheck audit and runtime compatibility when upgrading;
331
+ do not use a library-local override as a supposed fix for downstream consumers.
332
+
333
+ Only `dist/`, this README, the MIT license, and npm's package manifest are
334
+ published. The planning document, tests, local caches, and tarballs are excluded.
335
+
336
+ Publication is manual:
337
+
338
+ ```sh
339
+ npm publish --access public
340
+ ```
341
+
342
+ Publishing permissions/credentials are separate from Copilot authentication.
343
+ This command is documentation for the package owner, not an automated release
344
+ step. Consumer migration should begin only after publication is confirmed.
345
+
346
+ ## License
347
+
348
+ MIT. The extracted engine retains the copyright notice of the Playwright Report
349
+ 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>;