ghost-qa 1.3.2 β 2.0.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/README.md +77 -24
- package/SKILL.md +78 -77
- package/dist/bin/ghost-qa.d.ts +10 -2
- package/dist/bin/ghost-qa.d.ts.map +1 -1
- package/dist/bin/ghost-qa.js +106 -16
- package/dist/bin/ghost-qa.js.map +1 -1
- package/dist/src/engine/audit-runner.d.ts +6 -5
- package/dist/src/engine/audit-runner.d.ts.map +1 -1
- package/dist/src/engine/audit-runner.js +117 -60
- package/dist/src/engine/audit-runner.js.map +1 -1
- package/dist/src/engine/browser-session.d.ts +3 -3
- package/dist/src/engine/browser-session.d.ts.map +1 -1
- package/dist/src/engine/browser-session.js +18 -7
- package/dist/src/engine/browser-session.js.map +1 -1
- package/dist/src/engine/compare.d.ts +37 -0
- package/dist/src/engine/compare.d.ts.map +1 -0
- package/dist/src/engine/compare.js +63 -0
- package/dist/src/engine/compare.js.map +1 -0
- package/dist/src/engine/health-score.d.ts +14 -0
- package/dist/src/engine/health-score.d.ts.map +1 -0
- package/dist/src/engine/health-score.js +74 -0
- package/dist/src/engine/health-score.js.map +1 -0
- package/dist/src/engine/version.d.ts +14 -0
- package/dist/src/engine/version.d.ts.map +1 -0
- package/dist/src/engine/version.js +43 -0
- package/dist/src/engine/version.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/server.d.ts +24 -4
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +43 -5
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/reporter/agent-diagnostic.d.ts +6 -0
- package/dist/src/reporter/agent-diagnostic.d.ts.map +1 -1
- package/dist/src/reporter/agent-diagnostic.js +52 -2
- package/dist/src/reporter/agent-diagnostic.js.map +1 -1
- package/dist/src/reporter/html-report.d.ts.map +1 -1
- package/dist/src/reporter/html-report.js +79 -4
- package/dist/src/reporter/html-report.js.map +1 -1
- package/dist/src/reporter/terminal-summary.d.ts.map +1 -1
- package/dist/src/reporter/terminal-summary.js +6 -0
- package/dist/src/reporter/terminal-summary.js.map +1 -1
- package/dist/src/traps/a11y-trap.d.ts +23 -0
- package/dist/src/traps/a11y-trap.d.ts.map +1 -1
- package/dist/src/traps/a11y-trap.js +185 -0
- package/dist/src/traps/a11y-trap.js.map +1 -1
- package/dist/src/traps/console-trap.d.ts +3 -1
- package/dist/src/traps/console-trap.d.ts.map +1 -1
- package/dist/src/traps/console-trap.js +41 -0
- package/dist/src/traps/console-trap.js.map +1 -1
- package/dist/src/traps/layout-trap.d.ts +31 -0
- package/dist/src/traps/layout-trap.d.ts.map +1 -1
- package/dist/src/traps/layout-trap.js +173 -0
- package/dist/src/traps/layout-trap.js.map +1 -1
- package/dist/src/traps/links-trap.d.ts +34 -0
- package/dist/src/traps/links-trap.d.ts.map +1 -0
- package/dist/src/traps/links-trap.js +136 -0
- package/dist/src/traps/links-trap.js.map +1 -0
- package/dist/src/traps/network-trap.d.ts +4 -1
- package/dist/src/traps/network-trap.d.ts.map +1 -1
- package/dist/src/traps/network-trap.js +29 -2
- package/dist/src/traps/network-trap.js.map +1 -1
- package/dist/src/traps/perf-trap.d.ts +18 -0
- package/dist/src/traps/perf-trap.d.ts.map +1 -1
- package/dist/src/traps/perf-trap.js +148 -8
- package/dist/src/traps/perf-trap.js.map +1 -1
- package/dist/src/traps/seo-trap.d.ts +30 -0
- package/dist/src/traps/seo-trap.d.ts.map +1 -0
- package/dist/src/traps/seo-trap.js +98 -0
- package/dist/src/traps/seo-trap.js.map +1 -0
- package/dist/src/traps/theme-trap.d.ts +32 -0
- package/dist/src/traps/theme-trap.d.ts.map +1 -0
- package/dist/src/traps/theme-trap.js +109 -0
- package/dist/src/traps/theme-trap.js.map +1 -0
- package/dist/src/types.d.ts +55 -3
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +30 -2
- package/dist/src/types.js.map +1 -1
- package/package.json +11 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# π» ghost-qa
|
|
2
2
|
|
|
3
|
-
**Autonomous headless browser QA & self-healing verification loop for coding agents.**
|
|
3
|
+
**Autonomous headless browser QA & self-healing verification loop for coding agents.** `v2.0.0` β the 8-Trap Deep Browser Inspection Engine: 3 viewports Γ light/dark, QA Health Score (A+β¦F), interactive HTML dashboard, and regression diffing.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/avivgerz-hue/ghost-qa/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/ghost-qa)
|
|
@@ -66,60 +66,107 @@ npx -y ghost-qa init
|
|
|
66
66
|
β βΌ βΌ β
|
|
67
67
|
β βββββββββββ ββββββββββββ βββββββββββ β
|
|
68
68
|
β β CONSOLE β β NETWORK β β LAYOUT β β
|
|
69
|
-
β β A11Y β β PERF β β
|
|
69
|
+
β β A11Y β β PERF β β 8 TRAPS β β
|
|
70
70
|
β β TRAP β β TRAP β β TRAP β β
|
|
71
71
|
β βββββββββββ ββββββββββββ βββββββββββ β
|
|
72
|
-
β Desktop 1440Γ900
|
|
72
|
+
β Desktop 1440Γ900 Β· Tablet 768Γ1024 Β· Mobile 375Γ812 β
|
|
73
73
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
74
74
|
β
|
|
75
75
|
fix bugs ββββββββ re-run until β PASS
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
1. The agent writes code and starts the dev server.
|
|
79
|
-
2. `ghost-qa test` crawls every internal route on **
|
|
80
|
-
3.
|
|
81
|
-
4. Failures return as a token-efficient diagnostic; the agent fixes
|
|
82
|
-
5.
|
|
79
|
+
2. `ghost-qa test` crawls every internal route on **Desktop 1440Γ900, Tablet 768Γ1024 and Mobile 375Γ812**, in **light + dark** colour schemes, exercising interactive controls.
|
|
80
|
+
3. Eight traps capture everything the browser actually experienced, scored into a deterministic **QA Health Score (0β100, Grade A+β¦F)**.
|
|
81
|
+
4. Failures return as a token-efficient diagnostic (`GHOST-QA-REPORT.md` + `PATCH-PROMPT.md` with exact selectors); the agent fixes root causes and re-runs.
|
|
82
|
+
5. `ghost-qa compare before.json after.json` proves the fix: the loop ends only at **score 95β100 (A+)**, zero critical/major remaining, and **zero new regressions**.
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
|
86
|
-
## πͺ€ The
|
|
86
|
+
## πͺ€ The 8-Trap Deep Browser Inspection Engine *(v2.0.0)*
|
|
87
87
|
|
|
88
|
-
### 1. Console Trap β `src/traps/console-trap.ts`
|
|
88
|
+
### 1. Console & Framework Runtime Trap β `src/traps/console-trap.ts`
|
|
89
89
|
- Uncaught `pageerror` exceptions with stack traces
|
|
90
90
|
- Unhandled promise rejections
|
|
91
91
|
- **React hydration mismatches** ("Text content did not match", "A tree hydrated butβ¦")
|
|
92
|
+
- **Duplicate-key warnings** and **Content-Security-Policy violations** *(new in v2)*
|
|
92
93
|
- `console.error` (major) and `console.warning` (minor) β with dev-server noise (`[vite]`, HMR, React DevTools banners) filtered out
|
|
93
94
|
|
|
94
|
-
### 2. Network Trap β `src/traps/network-trap.ts`
|
|
95
|
+
### 2. Network & Asset Integrity Trap β `src/traps/network-trap.ts`
|
|
95
96
|
- HTTP `5xx` API crashes (critical) and `4xx` responses (major)
|
|
96
|
-
- Failed `fetch`/`XHR` requests and connection failures
|
|
97
|
-
- **CORS-blocked requests** with remediation guidance
|
|
98
|
-
- Broken static assets (
|
|
97
|
+
- Failed `fetch`/`XHR` requests, **timed-out requests**, and connection failures
|
|
98
|
+
- **CORS-blocked requests and failed CORS preflights** with remediation guidance
|
|
99
|
+
- Broken static assets, broken images (`naturalWidth === 0`), **broken inline SVGs (0Γ0)**, **>500KB unoptimized payloads**, and missing favicons (minor)
|
|
99
100
|
|
|
100
|
-
### 3. Layout Trap β `src/traps/layout-trap.ts`
|
|
101
|
+
### 3. Layout, Responsive Geometry & Collision Trap β `src/traps/layout-trap.ts`
|
|
101
102
|
- **Horizontal overflow**: `scrollWidth > innerWidth`, with the offending elements named (critical on mobile)
|
|
103
|
+
- **Overlapping interactive elements** via bounding-box collision math, with exact selectors + boxes *(new in v2)*
|
|
104
|
+
- **Touch targets < 44Γ44px** on touch viewports (WCAG 2.5.5 / Apple HIG), **clipped text**, and **off-screen interactives** *(new in v2)*
|
|
102
105
|
- Zero-dimension interactive elements β buttons rendered at 0Γ0 that no human could tap
|
|
103
|
-
- Broken images (`naturalWidth === 0`)
|
|
104
106
|
- Missing `<meta name="viewport">` on mobile
|
|
105
107
|
|
|
106
|
-
### 4. Accessibility Trap β `src/traps/a11y-trap.ts`
|
|
108
|
+
### 4. Accessibility (WCAG 2.1 AA) & Keyboard Focus Trap β `src/traps/a11y-trap.ts`
|
|
107
109
|
- Buttons and links with **no accessible name** (icon-only controls screen readers can't identify)
|
|
108
110
|
- Images **missing `alt`** attributes (descriptive alt, or `alt=""` for decorative)
|
|
109
111
|
- Form inputs with **no associated label** β a placeholder is not a label
|
|
112
|
+
- **Real computed contrast ratios** (`getComputedStyle` foreground vs effective background, WCAG formula) *(new in v2)*
|
|
113
|
+
- **Heading hierarchy** (missing `<h1>`, h1βh3 skips) and **automated Tab-order verification** β simulated Tab presses catch invisible or dead focus states *(new in v2)*
|
|
110
114
|
- Missing document `<title>` and missing `<html lang>`
|
|
111
115
|
|
|
112
|
-
### 5. Performance &
|
|
116
|
+
### 5. Performance & Core Web Vitals Trap β `src/traps/perf-trap.ts`
|
|
117
|
+
- **Core Web Vitals**: TTFB, FCP, LCP estimation, and CLS (Cumulative Layout Shift) *(new in v2)*
|
|
113
118
|
- Slow page loads via Navigation Timing (DOMContentLoaded / load budgets, 2Γ = critical)
|
|
114
|
-
- **Oversized resources** (> 1MB single asset) and excessive total payload (> 3MB)
|
|
119
|
+
- **Oversized resources** (> 1MB single asset), **unoptimized >500KB images/scripts**, and excessive total payload (> 3MB)
|
|
115
120
|
- Main-thread jank / layout-thrashing indicators from the Long Tasks API
|
|
116
|
-
- Render-blocking `<head>` resources
|
|
121
|
+
- Render-blocking `<head>` resources, excessive DOM size (>1500 nodes) and **DOM depth > 32**
|
|
122
|
+
|
|
123
|
+
### 6. Safe Interactive & Link Integrity Trap β `src/traps/links-trap.ts` *(new in v2)*
|
|
124
|
+
- Placeholder links (`href=""`, `href="#"`, `javascript:void(0)`) and **dead anchors/routes** found during crawling
|
|
125
|
+
- Buttons inside `<form>` with **no `type`** (they silently become submit buttons)
|
|
126
|
+
- Disabled/stuck interactive controls β all observational, this trap never clicks anything
|
|
127
|
+
|
|
128
|
+
### 7. SEO, Metadata & Social Graph Trap β `src/traps/seo-trap.ts` *(new in v2)*
|
|
129
|
+
- `<title>` (missing, <10 or >60 chars), meta description, `<html lang>`, viewport meta, canonical tag
|
|
130
|
+
- OpenGraph set (`og:title`, `og:description`, `og:image`) for link unfurls
|
|
131
|
+
- **Duplicate `id` attributes** in the live, post-hydration DOM
|
|
132
|
+
|
|
133
|
+
### 8. Dark / Light Theme Emulation Trap β `src/traps/theme-trap.ts` *(new in v2)*
|
|
134
|
+
- Every page also renders under `colorScheme: 'dark'` and `'light'` emulation
|
|
135
|
+
- Computed contrast is re-evaluated per scheme β invisible dark-mode text (dark-on-dark) is caught automatically and tagged with the failing scheme
|
|
117
136
|
|
|
118
137
|
Plus a **safety-first Interaction Runner**: it fills forms with inert data (`ghost-qa@example.com`), opens tabs/modals/menus, and clicks ordinary buttons β but *never* destructive ones (`delete`, `checkout`, `pay`, `logout`, `publish`β¦ are blocked by a tested safety gate).
|
|
119
138
|
|
|
120
139
|
---
|
|
121
140
|
|
|
122
|
-
##
|
|
141
|
+
## π QA Health Score, Artifacts & Interactive Dashboard *(new in v2)*
|
|
142
|
+
|
|
143
|
+
Every run computes a deterministic **QA Health Score (0β100)** and **Letter Grade (A+ β¦ F)**: each trap starts at 100 and loses 25 per critical, 10 per major, 3 per minor finding; the overall score is the mean of the eight trap sub-scores (Console, Network, Layout, A11y, Performance, Links/UX, SEO/DOM, Theme Parity).
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
npx -y ghost-qa test http://localhost:3000 --out-dir ghost-qa-out --screenshots
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
| Artifact | Contents |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `report.json` | Complete machine-readable telemetry: per-trap scores, viewport matrices, exact DOM selectors (`#id`, `data-testid`, CSS path) and bounding boxes |
|
|
152
|
+
| `GHOST-QA-REPORT.md` | Human + agent Self-Healing Bug Report with root-cause analysis and the fix playbook |
|
|
153
|
+
| `PATCH-PROMPT.md` | Copy-paste remediation prompt: every finding with selector, bounding box, parent-component hints and the compare loop |
|
|
154
|
+
| `report.html` | Self-contained, zero-dependency, dark-mode **interactive QA Dashboard**: Grade hero (A+β¦F), 8-Trap Scorecard, Route & Viewport Matrix, filterable findings (severity/trap/viewport), embedded screenshots when captured |
|
|
155
|
+
|
|
156
|
+
## π Regression Diffing β `ghost-qa compare` / `ghost_qa_compare` *(new in v2)*
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npx -y ghost-qa test http://localhost:3000 --json > before.json # baseline
|
|
160
|
+
# β¦agent fixes the bugsβ¦
|
|
161
|
+
npx -y ghost-qa test http://localhost:3000 --json > after.json # re-audit
|
|
162
|
+
npx -y ghost-qa compare before.json after.json # Regression & Verification Delta Report
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The delta matches findings by stable fingerprint id and reports **`scoreDelta`, `fixedFindings`, `newRegressions`, `remainingFindings`** β so a coding agent can *prove* its fix resolved the bug without introducing regressions. `verified` requires score β₯ 95, zero regressions and no blocking findings left. Also available as the `ghost_qa_compare` MCP tool.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## π Native MCP Server
|
|
123
170
|
|
|
124
171
|
ghost-qa ships a zero-dependency **Model Context Protocol** server (JSON-RPC 2.0 over stdio), so MCP hosts can invoke browser verification as a native tool instead of shelling out:
|
|
125
172
|
|
|
@@ -129,7 +176,8 @@ npx -y ghost-qa mcp
|
|
|
129
176
|
|
|
130
177
|
| MCP tool | What it does |
|
|
131
178
|
| --- | --- |
|
|
132
|
-
| `ghost_qa_audit_url` | Runs the full
|
|
179
|
+
| `ghost_qa_audit_url` | Runs the full 8-trap deep inspection (3 viewports Γ light/dark) and returns the Self-Healing Bug Report + QA Health Score (structured content includes the full report for baselining) |
|
|
180
|
+
| `ghost_qa_compare` | *(new in v2)* Diffs two report JSONs into the Regression & Verification Delta Report (`scoreDelta`, `fixedFindings`, `newRegressions`, `remainingFindings`) |
|
|
133
181
|
| `ghost_qa_doctor` | Verifies Node, Chromium availability, and runs a live browser smoke test |
|
|
134
182
|
|
|
135
183
|
`npx -y ghost-qa init` writes the ready-to-use `.mcp.json` entry for you (merging with any servers you already have):
|
|
@@ -166,7 +214,7 @@ Pair it with `--html ghost-qa-report.html` for a self-contained, dark-mode **vis
|
|
|
166
214
|
```
|
|
167
215
|
π» ghost-qa β autonomous browser verification
|
|
168
216
|
Target: http://localhost:3000/
|
|
169
|
-
Duration:
|
|
217
|
+
Duration: 14.2s Β· Viewports: desktop + tablet + mobile Β· Schemes: light + dark Β· Depth: 2
|
|
170
218
|
|
|
171
219
|
Routes crawled
|
|
172
220
|
/ Home [200] 3 issues
|
|
@@ -177,6 +225,7 @@ Coverage
|
|
|
177
225
|
Routes visited: 3
|
|
178
226
|
Interactions tested: 21 passed Β· 1 failed Β· 4 skipped (safety)
|
|
179
227
|
Issues: 5 total β 2 critical, 3 major, 0 minor
|
|
228
|
+
QA Health Score: 62/100 β Grade D (8 traps Β· per-trap: console 65 Β· network 75 Β· layout 90 Β· a11y 100 Β· perf 100 Β· links 100 Β· seo 100 Β· theme 65)
|
|
180
229
|
|
|
181
230
|
Failures caught
|
|
182
231
|
β CRITICAL [console] React hydration mismatch: Text content did not matchβ¦
|
|
@@ -199,7 +248,8 @@ The agent-facing report (`--report ghost-qa-report.md`) groups the same bugs by
|
|
|
199
248
|
| --- | --- |
|
|
200
249
|
| `ghost-qa test <url>` | Crawl a running app and trap browser failures. Exit `0` = PASS, `1` = blocking issues, `2` = runner error |
|
|
201
250
|
| `ghost-qa init [--force]` | Install `.claude/skills/ghost-qa/SKILL.md`, verification protocol (`CLAUDE.md`, `AGENTS.md`, `.cursorrules`) + MCP config (`.mcp.json`) β all idempotent |
|
|
202
|
-
| `ghost-qa
|
|
251
|
+
| `ghost-qa compare <before.json> <after.json>` | Regression & Verification Delta Report between two report JSONs. Exit `1` if new regressions appeared |
|
|
252
|
+
| `ghost-qa mcp` | Run the native MCP server (JSON-RPC 2.0 over stdio) exposing `ghost_qa_audit_url`, `ghost_qa_compare` and `ghost_qa_doctor` |
|
|
203
253
|
| `ghost-qa doctor` | Diagnose Node β₯ 20, Playwright and Chromium setup, with a live browser smoke test |
|
|
204
254
|
| `ghost-qa --version` / `--help` | Version / usage |
|
|
205
255
|
|
|
@@ -210,7 +260,10 @@ The agent-facing report (`--report ghost-qa-report.md`) groups the same bugs by
|
|
|
210
260
|
| `--max-depth <n>` | `2` | Link-following depth from the start URL |
|
|
211
261
|
| `--max-routes <n>` | `25` | Maximum routes to visit |
|
|
212
262
|
| `--timeout <ms>` | `15000` | Per-navigation timeout |
|
|
213
|
-
| `--viewport <name>` | `
|
|
263
|
+
| `--viewport <name>` | `all` | `all` \| `both` (desktop+mobile) \| `desktop` \| `tablet` \| `mobile` |
|
|
264
|
+
| `--color-scheme <name>` | `both` | `both` \| `light` \| `dark` β colour schemes emulated per viewport |
|
|
265
|
+
| `--screenshots` | off | Capture a screenshot per route/viewport for the HTML dashboard |
|
|
266
|
+
| `--out-dir <dir>` | β | Write `report.json` + `GHOST-QA-REPORT.md` + `PATCH-PROMPT.md` + `report.html` into this directory |
|
|
214
267
|
| `--no-interactions` | off | Load pages only; don't click or fill anything |
|
|
215
268
|
| `--headed` | off | Show the browser window (debugging) |
|
|
216
269
|
| `--fail-on <severity>` | `major` | Exit 1 on `critical` \| `major` \| `minor` issues |
|
package/SKILL.md
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ghost-qa
|
|
3
|
-
description: Verify frontend work in a real headless browser before reporting a task complete.
|
|
3
|
+
description: Verify frontend work in a real headless browser before reporting a task complete. The autonomous Staff QA Engineer protocol β doctor readiness, multi-viewport 8-Trap baseline audit (Desktop/Tablet/Mobile, light + dark), DOM-to-source root-cause mapping, surgical remediation, and closed-loop delta verification with ghost_qa_compare until QA Health Score is 95β100 (Grade A+). Use after building or changing any UI, route, form, API integration, or client-side logic.
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# π» ghost-qa β
|
|
7
|
+
# π» ghost-qa β Autonomous Staff QA Engineer Protocol
|
|
8
8
|
|
|
9
|
-
Coding agents write code blind. Code that type-checks can still ship with React hydration mismatches, uncaught exceptions, 500ing APIs, dead
|
|
9
|
+
Coding agents write code blind. Code that type-checks can still ship with React hydration mismatches, uncaught exceptions, 500ing APIs, dead links, invisible dark-mode text, 30px tap targets, and mobile layouts that scroll sideways. **The browser is the source of truth β never your mental model of the DOM.**
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
> **The Rule:** Before reporting ANY task that touches frontend code as complete, you MUST execute all five phases below, in order, and finish with a verified delta: QA Health Score 95β100 (Grade A+ band), zero critical/major findings, zero new regressions.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Unit tests, type-checking, linting and code review do **not** satisfy this rule. They cannot see hydration, layout, network or accessibility failures.
|
|
13
|
+
Unit tests, type-checking, linting and code review do **not** satisfy this rule. They cannot see hydration, layout, network, contrast or focus failures.
|
|
16
14
|
|
|
17
15
|
## When to use this skill
|
|
18
16
|
|
|
@@ -20,88 +18,91 @@ Unit tests, type-checking, linting and code review do **not** satisfy this rule.
|
|
|
20
18
|
- β
You fixed a bug that manifested in the browser
|
|
21
19
|
- β
You are about to tell the user a UI task is "done"
|
|
22
20
|
|
|
23
|
-
**Not a substitute for:** your unit/E2E
|
|
21
|
+
**Not a substitute for:** your unit/E2E suites, a full manual WCAG audit (the a11y trap covers machine-checkable WCAG 2.1 AA failures), load testing, or exploratory QA.
|
|
24
22
|
|
|
25
|
-
##
|
|
23
|
+
## The 8-Trap Deep Browser Inspection Engine
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
| --- | --- |
|
|
29
|
-
| Dev server already running | `npx -y ghost-qa test <url>` |
|
|
30
|
-
| Server not running (most common) | `npx -y ghost-qa test <url> --server-cmd "npm run dev"` β ghost-qa spawns it, waits for it, audits, and kills the process tree afterward |
|
|
31
|
-
| Your host exposes MCP tools | Call **`ghost_qa_audit_url`** with the URL (call `ghost_qa_doctor` first if it errors) β identical engine, identical report |
|
|
32
|
-
| Mobile-only bug hunt | add `--viewport mobile` |
|
|
33
|
-
| Large app | add `--max-depth 3 --max-routes 50` |
|
|
34
|
-
| Evidence for a PR/CI | add `--report ghost-qa-report.md --html ghost-qa-report.html` |
|
|
25
|
+
Every audit crawls each route on **Desktop 1440Γ900, Tablet 768Γ1024 and Mobile 375Γ812**, under **light + dark** colour schemes:
|
|
35
26
|
|
|
36
|
-
|
|
27
|
+
| # | Trap | What it catches |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| 1 | Console & Framework Runtime | `pageerror`, `console.error`, unhandled rejections, React/Next.js hydration mismatches, duplicate-key warnings, CSP violations |
|
|
30
|
+
| 2 | Network & Asset Integrity | 4xx/5xx, timed-out/aborted requests, failed CORS preflights, broken images (`naturalWidth === 0`), broken inline SVGs (0Γ0), >500KB unoptimized payloads |
|
|
31
|
+
| 3 | Layout, Responsive Geometry & Collision | Horizontal overflow, overlapping interactive elements (bounding-box collision math), <44Γ44px touch targets, clipped text, off-screen interactives |
|
|
32
|
+
| 4 | Accessibility (WCAG 2.1 AA) & Keyboard Focus | Missing accessible names/labels/alt, heading hierarchy breaks, real computed contrast ratios, automated Tab-order verification (invisible/dead focus) |
|
|
33
|
+
| 5 | Performance & Core Web Vitals | TTFB, FCP, LCP, CLS, DOM bloat (>1500 nodes), DOM depth (>32), render-blocking scripts, long tasks |
|
|
34
|
+
| 6 | Safe Interactive & Link Integrity | Placeholder hrefs (`""`, `#`, `javascript:void(0)`), dead anchors/routes, in-form buttons without `type`, stuck disabled controls |
|
|
35
|
+
| 7 | SEO, Metadata & Social Graph | Title length, meta description, `<html lang>`, viewport meta, canonical, OpenGraph set, duplicate `id`s |
|
|
36
|
+
| 8 | Dark / Light Theme Emulation | Contrast/visibility recomputed under `colorScheme: light` and `dark` β catches invisible dark-mode text |
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Scoring is deterministic: each trap starts at 100, β25 per critical, β10 per major, β3 per minor. The **QA Health Score** is the mean of the 8 trap scores, graded **A+ (97+) β¦ F (<60)**.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
---
|
|
41
41
|
|
|
42
|
-
1
|
|
43
|
-
- **Console** β uncaught errors, unhandled promise rejections, React hydration mismatches, `console.error`
|
|
44
|
-
- **Network** β HTTP 4xx/5xx, failed fetch/XHR, CORS failures, broken assets
|
|
45
|
-
- **Layout** β horizontal overflow, zero-size interactive elements, broken images, missing viewport meta
|
|
46
|
-
- **Accessibility** β buttons/links with no accessible name, images missing `alt`, inputs with no label, missing `<title>` / `<html lang>`
|
|
47
|
-
- **Performance** β slow loads, oversized assets/payloads, main-thread long-task jank, render-blocking resources, excessive DOM
|
|
48
|
-
2. **Read the Self-Healing Bug Report.** Every issue has a stable `#id`, a severity (`critical` / `major` / `minor`), the route, and the viewport. Fix **critical and major** issues. Note minors; fix them when cheap.
|
|
49
|
-
3. **Fix root causes in source** (fix guidance below). Reference issues by `#id` in your own narration so the user can follow along.
|
|
50
|
-
4. **Re-run the identical command.** A fix that breaks a different route or viewport only shows up on re-run.
|
|
51
|
-
5. **Repeat until `GHOST-QA PASS`.** If you have looped 5 times on the same `#id`, stop and report to the user what is stuck and why β do not silently give up or declare success.
|
|
52
|
-
6. **Only then** report completion, using the completion template below.
|
|
42
|
+
## Phase 1 β Environment & Server Readiness (`ghost_qa_doctor`)
|
|
53
43
|
|
|
54
|
-
|
|
44
|
+
1. Call the **`ghost_qa_doctor`** MCP tool, or run `npx -y ghost-qa doctor`.
|
|
45
|
+
2. It must report **READY**: Node β₯ 20, Chromium installed, live browser smoke test passing.
|
|
46
|
+
3. If Chromium is missing: `npx playwright install chromium` (one-time), then re-run doctor. **Never skip to Phase 2 on a red doctor** β a failed launch is not a passing audit.
|
|
47
|
+
4. Start the app (`npm run dev`) or plan to use `--server-cmd "npm run dev"` / let the audit spawn it.
|
|
55
48
|
|
|
56
|
-
|
|
57
|
-
| --- | --- | --- |
|
|
58
|
-
| Hydration mismatch | `Date.now()`/`Math.random()`/`window` during render, server/client branching, invalid HTML nesting (`<p>` in `<p>`, `<div>` in `<p>`) | Make server and client render identical markup; move time/random/client-only values into `useEffect` + state; fix the nesting |
|
|
59
|
-
| Uncaught page error | undefined data, missing null checks on async data, bad imports | Reproduce via the stack trace in the report; guard the actual data path |
|
|
60
|
-
| Console error | failed state updates, rejected promises, React warnings treated seriously by the app | Trace the first error, not the cascade after it |
|
|
61
|
-
| HTTP 5xx | API route crash, bad env var, DB down | Read the server logs for that endpoint; the browser found it, the fix is server-side |
|
|
62
|
-
| HTTP 404 / broken asset | wrong path, case-sensitivity, asset not emitted by the build | Compare the URL in the report with the actual build output / public dir |
|
|
63
|
-
| CORS failure | API missing `Access-Control-Allow-Origin` for the page origin | Fix the API's CORS config (or the dev proxy), not the fetch call |
|
|
64
|
-
| Horizontal overflow | `100vw` + scrollbar, fixed-width children, flex/grid children without `min-width: 0` | Constrain widths (`max-width: 100%`, `min-width: 0`, `overflow-wrap`); the report names the offending elements |
|
|
65
|
-
| Zero-size interactive | collapsed CSS, `display: contents` misuse, content that never rendered | Restore a real, tappable size (β₯ 24px, ideally β₯ 40px on mobile) |
|
|
66
|
-
| No accessible name | icon-only `<button>`/`<a>` | Add visible text or `aria-label` describing the action/destination |
|
|
67
|
-
| Missing `alt` | forgotten attribute | Descriptive alt; `alt=""` only if purely decorative |
|
|
68
|
-
| Input without label | placeholder used as label | Real `<label for>`, wrapping `<label>`, or `aria-label` |
|
|
69
|
-
| Slow load / oversized asset | unoptimized images, giant bundles, blocking scripts | Compress/lazy-load, `defer`/`async`, code-split; check the named resource first |
|
|
70
|
-
| Long-task jank | heavy sync JS, layout reads in loops after writes | Break up work, memoize, batch DOM reads before writes |
|
|
71
|
-
|
|
72
|
-
## Anti-cheating rules (this is the point of the skill)
|
|
73
|
-
|
|
74
|
-
- β Never silence the checker: no deleting the failing UI, no blanket `try/catch`, no `suppressHydrationWarning`, no removing the code path "so the error goes away"
|
|
75
|
-
- β Never use `--no-interactions` or narrow `--viewport`/`--max-depth` to hide failures (legitimate only when a page has side-effectful controls, and you must say so)
|
|
76
|
-
- β Never edit ghost-qa's report, thresholds, or your project's ghost-qa invocation to manufacture a PASS
|
|
77
|
-
- β
If a finding is a genuine false positive, say so explicitly in your completion message with the `#id` and why β a human can overrule the tool; you may not quietly ignore it
|
|
78
|
-
|
|
79
|
-
## Safety guarantees you can rely on
|
|
80
|
-
|
|
81
|
-
ghost-qa never clicks destructive controls (delete, checkout, pay, logout, publish, sign-inβ¦), never submits real orders/payments, fills forms only with inert data (`ghost-qa@example.com`, `ghost-qa test`), stays on same-origin links, and is designed for localhost/dev servers. **Do not point it at production systems you do not own or have permission to test.** Pages behind authentication will typically redirect to a login page β ghost-qa will audit what an anonymous visitor sees; say so if that's what happened.
|
|
49
|
+
## Phase 2 β Multi-Viewport 8-Trap Baseline Audit (`ghost_qa_audit_url`)
|
|
82
50
|
|
|
83
|
-
|
|
51
|
+
Run the baseline BEFORE changing code (or before your fix, when debugging):
|
|
84
52
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
53
|
+
- MCP: call **`ghost_qa_audit_url`** with the app URL. Save the full returned report JSON as **`before.json`**.
|
|
54
|
+
- CLI equivalent: `npx -y ghost-qa test <local-url> --out-dir ghost-qa-out` β writes `report.json` (copy to `before.json`), `GHOST-QA-REPORT.md`, `PATCH-PROMPT.md`, and the interactive `report.html` dashboard. Add `--screenshots` for embedded route screenshots; `--server-cmd "npm run dev"` if the server isn't running.
|
|
55
|
+
|
|
56
|
+
Record the baseline: **QA Health Score, grade, per-trap scores, and every finding's `#id`.** Common local URLs: Next.js/CRA `http://localhost:3000`, Vite `http://localhost:5173`, Astro `http://localhost:4321`, Angular `http://localhost:4200`. Never guess silently β state the URL you verified.
|
|
57
|
+
|
|
58
|
+
## Phase 3 β DOM-to-Source Root-Cause Mapping
|
|
59
|
+
|
|
60
|
+
For every critical/major finding, trace it back to the exact source component before editing:
|
|
93
61
|
|
|
94
|
-
|
|
62
|
+
- **Exact selectors:** findings carry `#id`, `[data-testid=β¦]`, or a CSS path, plus the live **bounding box**. Search the codebase for that id/testid/class or the element's visible text to find the React/Next.js/Vue/Svelte component that renders it.
|
|
63
|
+
- **Collisions/overflow:** the two colliding selectors + boxes tell you which siblings overlap β inspect their flex/grid/absolute layout in that component, on the failing viewport.
|
|
64
|
+
- **Console stacks:** follow the first app-owned stack frames to the throwing component/effect. Hydration mismatches mean server and client rendered different markup (Date/random/`window` at render, invalid nesting like `<p>` in `<p>`).
|
|
65
|
+
- **Dark-mode contrast:** a `theme-contrast` finding names the scheme that fails β find the hard-coded colour in that component and replace it with the theme token.
|
|
66
|
+
- **Network:** map the failing URL to its route handler/client fetch; 5xx is server code, CORS preflight is API config.
|
|
95
67
|
|
|
96
|
-
|
|
68
|
+
Write the mapping down (finding `#id` β file β root cause) before Phase 4. If you cannot map a finding, say so β do not guess-fix.
|
|
97
69
|
|
|
98
|
-
|
|
99
|
-
> Routes crawled: N Β· Interactions tested: N Β· Issues fixed this session: (list `#id`s, or "none found")
|
|
100
|
-
> Stack: desktop 1440Γ900 + mobile 390Γ844, 5 traps (console, network, layout, accessibility, performance)
|
|
70
|
+
## Phase 4 β Surgical Code Remediation
|
|
101
71
|
|
|
102
|
-
|
|
72
|
+
Fix root causes, one finding at a time, in severity order (critical β major β minor):
|
|
103
73
|
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
74
|
+
- **Hydration:** identical server/client markup; defer client-only values to effects; fix invalid HTML nesting. Never `suppressHydrationWarning` to silence it.
|
|
75
|
+
- **Responsive geometry:** `min-width: 0` on flex/grid children, `max-width: 100%`, no `100vw` + scrollbar overflow, reserve image space with width/height or `aspect-ratio` (also fixes CLS).
|
|
76
|
+
- **Tap targets:** every touch target β₯ 44Γ44px (padding or min-height/min-width).
|
|
77
|
+
- **ARIA/labels:** visible text or `aria-label` on icon controls, `<label for>` (or wrapping label) per input, `alt` on images (`alt=""` only if decorative), one `<h1>`, no heading level skips, visible `:focus-visible` rings β never `outline: none` without a replacement.
|
|
78
|
+
- **Dark-mode tokens:** CSS variables / `dark:` variants driven by `prefers-color-scheme` or the app theme β never hard-coded hex that only works in one scheme.
|
|
79
|
+
- **Links/forms:** real hrefs or `<button type="button">`; dead anchors get real targets; in-form buttons get explicit `type`.
|
|
80
|
+
- **Performance:** defer/async non-critical scripts, compress/resize/lazy-load >500KB assets, code-split, break up long tasks.
|
|
81
|
+
|
|
82
|
+
**Anti-cheating rules (absolute):** never delete failing UI, never loosen the checker, never hide elements from the traps, never stub network responses. Fixing the checker instead of the bug is a failed task.
|
|
83
|
+
|
|
84
|
+
## Phase 5 β Closed-Loop Delta Verification (`ghost_qa_compare`)
|
|
85
|
+
|
|
86
|
+
1. Re-run the identical audit (same URL/viewports) β save as **`after.json`**.
|
|
87
|
+
2. Compare: MCP **`ghost_qa_compare`** with `{ before, after }`, or `npx -y ghost-qa compare before.json after.json`.
|
|
88
|
+
3. Read the **Regression & Verification Delta Report**: `scoreDelta`, `fixedFindings`, `newRegressions`, `remainingFindings`.
|
|
89
|
+
4. **Done only when ALL hold:** QA Health Score **95β100 (Grade A+ band)** Β· zero critical/major remaining Β· **zero new regressions** (`verified: true`). Otherwise loop back to Phase 3 with the delta as your new worklist.
|
|
90
|
+
5. If the same `#id` survives 5 loops, stop and report honestly what you tried β never declare success on a red delta.
|
|
91
|
+
|
|
92
|
+
## Completion report (required format)
|
|
93
|
+
|
|
94
|
+
> β
Done. Verified in a real browser with ghost-qa: `ghost_qa_audit_url` on `<url>`
|
|
95
|
+
> Stack: Desktop 1440Γ900 + Tablet 768Γ1024 + Mobile 375Γ812, light + dark, 8 traps
|
|
96
|
+
> QA Health Score: `<before>` β `<after>` (Grade `<grade>`) Β· Delta: `<n>` fixed, 0 new regressions
|
|
97
|
+
> Routes crawled: `<n>` Β· Interactions tested: `<n>` Β· Artifacts: `report.json`, `GHOST-QA-REPORT.md`, `PATCH-PROMPT.md`, `report.html`
|
|
98
|
+
|
|
99
|
+
## Troubleshooting
|
|
100
|
+
|
|
101
|
+
| Symptom | Fix |
|
|
102
|
+
| --- | --- |
|
|
103
|
+
| "could not launch Chromium" | `npx playwright install chromium` (one-time), then `npx -y ghost-qa doctor` |
|
|
104
|
+
| Navigation failures on every route | The dev server isn't running (or wrong port) β start it, or use `--server-cmd "npm run dev"` |
|
|
105
|
+
| Score stuck below 95 | Work the delta's remaining findings by severity; re-check Phase 3 mapping before editing |
|
|
106
|
+
| A trap flags a healthy page | File an issue with `report.json` attached β false positives are the most valuable bug reports |
|
|
107
|
+
|
|
108
|
+
> All commands use the published npm package (`npx -y ghost-qa β¦`). If npm is unavailable, `npx -y github:avivgerz-hue/ghost-qa β¦` runs the identical CLI straight from GitHub.
|
package/dist/bin/ghost-qa.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { type GhostQAOptions } from '../src/types.js';
|
|
3
|
-
export declare const VERSION
|
|
4
|
-
export declare const AGENT_PROTOCOL = "<!-- ghost-qa:start -->\n## \uD83D\uDC7B ghost-qa \u2014 Browser Verification Protocol (MANDATORY)\n\nBefore reporting any task that touches frontend code as complete, you MUST verify it in a real browser:\n\n1.
|
|
3
|
+
export declare const VERSION: string;
|
|
4
|
+
export declare const AGENT_PROTOCOL = "<!-- ghost-qa:start -->\n## \uD83D\uDC7B ghost-qa \u2014 Browser Verification Protocol (MANDATORY)\n\nBefore reporting any task that touches frontend code as complete, you MUST verify it in a real browser \u2014 the closed-loop Self-Healing Browser Verification Protocol:\n\n1. **Readiness:** run `ghost-qa doctor` (or the `ghost_qa_doctor` MCP tool). Do not proceed on red.\n2. **Baseline audit:** ensure the app runs locally, then `npx -y ghost-qa test <local-url> --out-dir ghost-qa-out` (add `--server-cmd \"npm run dev\"` to let ghost-qa manage the server) \u2014 or call `ghost_qa_audit_url`. This runs the 8-Trap Engine on Desktop 1440\u00D7900, Tablet 768\u00D71024 and Mobile 375\u00D7812, light + dark. Save the baseline as `before.json` (it is `ghost-qa-out/report.json`).\n3. **Root-cause mapping:** for every critical/major finding, map the exact DOM selector, bounding box, stack trace or dark-mode contrast failure back to the component file that renders it.\n4. **Surgical remediation:** fix root causes in source (hydration, overflow, tap targets, ARIA/labels, dark-mode tokens\u2026). Never silence the checker or delete failing UI.\n5. **Delta verification:** re-run the audit to `after.json`, then `npx -y ghost-qa compare before.json after.json` (or `ghost_qa_compare`). Repeat until QA Health Score is **95\u2013100 (A+)**, zero critical/major remain, and the delta shows **zero new regressions**. Only then report done, citing score, routes, viewports and the delta.\n\nNever declare a UI task finished based only on code review, type-checking, or unit tests. The browser is the source of truth.\n<!-- ghost-qa:end -->";
|
|
5
5
|
export interface ParsedTestArgs {
|
|
6
6
|
target: string;
|
|
7
7
|
options: GhostQAOptions;
|
|
@@ -9,10 +9,18 @@ export interface ParsedTestArgs {
|
|
|
9
9
|
quiet: boolean;
|
|
10
10
|
reportFile?: string;
|
|
11
11
|
htmlFile?: string;
|
|
12
|
+
outDir?: string;
|
|
12
13
|
serverCmd?: string;
|
|
13
14
|
serverTimeoutMs: number;
|
|
14
15
|
}
|
|
15
16
|
export declare function parseTestArgs(args: string[]): ParsedTestArgs;
|
|
17
|
+
export interface ParsedCompareArgs {
|
|
18
|
+
beforeFile: string;
|
|
19
|
+
afterFile: string;
|
|
20
|
+
json: boolean;
|
|
21
|
+
outFile?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function parseCompareArgs(args: string[]): ParsedCompareArgs;
|
|
16
24
|
export declare function installSkill(targetDir: string, force?: boolean): Promise<Array<{
|
|
17
25
|
file: string;
|
|
18
26
|
action: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ghost-qa.d.ts","sourceRoot":"","sources":["../../bin/ghost-qa.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"ghost-qa.d.ts","sourceRoot":"","sources":["../../bin/ghost-qa.ts"],"names":[],"mappings":";AAYA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEvE,eAAO,MAAM,OAAO,QAAmB,CAAC;AAKxC,eAAO,MAAM,cAAc,8mDAYX,CAAC;AAoFjB,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAgG5D;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAiBlE;AAiFD,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,KAAK,UAAQ,GACZ,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAqBlD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,KAAK,UAAQ,GACZ,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAuCD,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiExE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,GAAE,MAAwB,GAClC,OAAO,CAOT"}
|