skeptic-cli 0.2.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/AGENTS.md +303 -0
- package/LICENSES.md +327 -0
- package/README.md +393 -0
- package/agent-skills/skeptic/SKILL.md +99 -0
- package/agent-skills/skeptic/agents/openai.yaml +4 -0
- package/bin/launcher.mjs +18 -0
- package/dist/index.d.ts +1252 -0
- package/dist/index.mjs +1748 -0
- package/dist/skeptic.mjs +1750 -0
- package/dist/templates/example.spec.ts +20 -0
- package/dist/templates/guidance/accessibility.md +41 -0
- package/dist/templates/guidance/animation.md +35 -0
- package/dist/templates/guidance/design.md +41 -0
- package/dist/templates/guidance/performance.md +37 -0
- package/dist/templates/guidance/react.md +50 -0
- package/dist/templates/guidance/responsive.md +46 -0
- package/dist/templates/guidance/security.md +42 -0
- package/dist/templates/guidance/seo.md +43 -0
- package/dist/templates/skeptic.config.yaml +31 -0
- package/dist/templates/tsconfig.json +15 -0
- package/dist/web-vitals.iife.js +1 -0
- package/dist/worker.mjs +724 -0
- package/package.json +110 -0
- package/scripts/install-agent-skills.mjs +145 -0
package/README.md
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# skeptic
|
|
2
|
+
|
|
3
|
+
CLI-first end-to-end testing for TypeScript specs. Skeptic runs Playwright tests,
|
|
4
|
+
adds agent-friendly page discovery, and captures QA evidence that is useful in
|
|
5
|
+
local debugging, CI, and coding-agent workflows.
|
|
6
|
+
|
|
7
|
+
> Agent authors should also read [AGENTS.md](./AGENTS.md) for the recommended
|
|
8
|
+
> inspect → author → run loop and the full fixture API.
|
|
9
|
+
|
|
10
|
+
## Install For Development
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
git clone https://github.com/iamjr15/skeptic
|
|
14
|
+
cd skeptic/cli
|
|
15
|
+
npm install
|
|
16
|
+
npm run build
|
|
17
|
+
node dist/skeptic.mjs --help
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
To use the local checkout as a command:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm link
|
|
24
|
+
skeptic --help
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Initialize a project
|
|
31
|
+
skeptic init
|
|
32
|
+
|
|
33
|
+
# Discover stable selectors before authoring a test
|
|
34
|
+
skeptic inspect https://example.com
|
|
35
|
+
|
|
36
|
+
# Capture an ad hoc QA evidence bundle without writing a spec
|
|
37
|
+
skeptic observe https://example.com
|
|
38
|
+
|
|
39
|
+
# Run TypeScript specs with full QA evidence
|
|
40
|
+
skeptic run tests/homepage.spec.ts --observability --video --trace
|
|
41
|
+
|
|
42
|
+
# Generate a validated TypeScript spec with AI
|
|
43
|
+
skeptic generate -m "test the login page"
|
|
44
|
+
|
|
45
|
+
# Check local setup
|
|
46
|
+
skeptic doctor
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`skeptic init` creates:
|
|
50
|
+
|
|
51
|
+
- `package.json` when missing, or adds a `test:e2e` script and `skeptic-cli` dev dependency when present
|
|
52
|
+
- `tests/`
|
|
53
|
+
- `tests/package.json` with `type: "module"` so specs can use ESM without changing your app package mode
|
|
54
|
+
- `tests/example.spec.ts`
|
|
55
|
+
- `skeptic.config.yaml`
|
|
56
|
+
- `tsconfig.json`
|
|
57
|
+
- `.skeptic/.gitignore`
|
|
58
|
+
- root `.gitignore` entries for `.skeptic/` and `skeptic-output/`
|
|
59
|
+
|
|
60
|
+
## Agent Skills
|
|
61
|
+
|
|
62
|
+
The npm package includes a `skeptic` skill for Claude Code, Codex, Cursor, and
|
|
63
|
+
OpenCode. During `npm install`, Skeptic installs that skill into user-level agent
|
|
64
|
+
skill directories when possible:
|
|
65
|
+
|
|
66
|
+
| Agent | User skill directory |
|
|
67
|
+
|---|---|
|
|
68
|
+
| Claude Code | `~/.claude/skills/skeptic` |
|
|
69
|
+
| Codex | `${CODEX_HOME:-~/.codex}/skills/skeptic` |
|
|
70
|
+
| Cursor | `~/.cursor/skills/skeptic` |
|
|
71
|
+
| OpenCode | `~/.opencode/skills/skeptic` |
|
|
72
|
+
|
|
73
|
+
The installer only replaces skills previously managed by `skeptic-cli`; existing
|
|
74
|
+
custom skills are left untouched. To skip automatic installation, set
|
|
75
|
+
`SKEPTIC_SKIP_AGENT_SKILL_INSTALL=1` or `SKEPTIC_INSTALL_AGENT_SKILLS=0`.
|
|
76
|
+
Automatic installation is skipped in CI unless `SKEPTIC_INSTALL_AGENT_SKILLS=1`
|
|
77
|
+
is set. To install only selected agents, set
|
|
78
|
+
`SKEPTIC_AGENT_SKILLS=claude,codex`.
|
|
79
|
+
|
|
80
|
+
For a repository-scoped skill that should be committed with a project, run:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
skeptic add skill --agent all --scope project
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For an explicit user-level reinstall, run:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
skeptic add skill --agent all --scope user
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Test Format
|
|
93
|
+
|
|
94
|
+
Skeptic specs are ordinary TypeScript files that import from `skeptic-cli`.
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { test, expect } from "skeptic-cli";
|
|
98
|
+
|
|
99
|
+
test("homepage smoke", async ({ page, snapshot, screenshot, observability }) => {
|
|
100
|
+
await page.goto("https://example.com");
|
|
101
|
+
await expect(page).toHaveTitle(/Example Domain/);
|
|
102
|
+
|
|
103
|
+
const tree = await snapshot(page);
|
|
104
|
+
await expect(tree.byRole("heading", { name: "Example Domain" })).toBeVisible();
|
|
105
|
+
|
|
106
|
+
await screenshot("homepage", { fullPage: true });
|
|
107
|
+
await observability.expectNoConsoleErrors();
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The fixture exposes:
|
|
112
|
+
|
|
113
|
+
| Member | Purpose |
|
|
114
|
+
|---|---|
|
|
115
|
+
| `page` | Playwright `Page`, wrapped for cursor/action markers when video is enabled |
|
|
116
|
+
| `snapshot` | ARIA + cursor-interactive discovery with refs and locator helpers |
|
|
117
|
+
| `screenshot` | PNG screenshots, including annotated numbered-ref captures |
|
|
118
|
+
| `settle` | Network-idle settle helper |
|
|
119
|
+
| `observability` | Performance, network, console, and accessibility assertions |
|
|
120
|
+
| `ai` | Vision-backed assertions, defect checks, and text extraction |
|
|
121
|
+
| `ctx` | Per-test execution context and artifact paths |
|
|
122
|
+
|
|
123
|
+
`expect` is re-exported from Playwright Test, so matchers like
|
|
124
|
+
`toHaveURL`, `toBeVisible`, and `toHaveText` are available without a second
|
|
125
|
+
import.
|
|
126
|
+
|
|
127
|
+
## Discovery
|
|
128
|
+
|
|
129
|
+
`skeptic inspect <url>` opens the page, captures an ARIA/cursor snapshot, and
|
|
130
|
+
prints stable `selectorHint:` lines.
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
skeptic inspect https://example.com --interactive --compact
|
|
134
|
+
skeptic inspect https://example.com --json
|
|
135
|
+
skeptic inspect https://example.com --annotated --annotate-output inspect.png
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Useful flags:
|
|
139
|
+
|
|
140
|
+
| Flag | Purpose |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `--interactive` | Show only ref-bearing entries |
|
|
143
|
+
| `--compact` | Show interactive entries with minimal ancestors |
|
|
144
|
+
| `--selector <css>` | Scope discovery to part of the page |
|
|
145
|
+
| `--json` | Emit machine-readable refs, hints, and stats |
|
|
146
|
+
| `--device <id>` | Inspect under a configured device profile |
|
|
147
|
+
| `--connect <url>` | Attach to an existing browser over CDP |
|
|
148
|
+
| `--with-playwright-hints` | Emit equivalent Playwright locator snippets |
|
|
149
|
+
| `--annotated` | Save a numbered-ref screenshot |
|
|
150
|
+
|
|
151
|
+
Refs like `e3` are runtime handles. Copy `selectorHint` strings into durable
|
|
152
|
+
tests, or use `tree.byRef("e3")` only after a matching `snapshot(page)` call in
|
|
153
|
+
the same test.
|
|
154
|
+
|
|
155
|
+
## Running Tests
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
skeptic tui
|
|
159
|
+
skeptic tui tests/login.spec.ts
|
|
160
|
+
skeptic run
|
|
161
|
+
skeptic run tests/login.spec.ts
|
|
162
|
+
skeptic run tests/**/*.spec.ts --tag smoke
|
|
163
|
+
skeptic run --parallel 4
|
|
164
|
+
skeptic run --shard-split 4 --shard-index 1
|
|
165
|
+
skeptic run --watch
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`skeptic tui` is the discoverable interactive entrypoint. `skeptic run` opens
|
|
169
|
+
the same TUI automatically in an interactive terminal when the console reporter
|
|
170
|
+
is active; use `skeptic run --no-tui` for plain console output.
|
|
171
|
+
|
|
172
|
+
Important flags:
|
|
173
|
+
|
|
174
|
+
| Flag | Purpose |
|
|
175
|
+
|---|---|
|
|
176
|
+
| `--headed` | Show the browser |
|
|
177
|
+
| `--ci` | Force headless CI behavior |
|
|
178
|
+
| `--bail` | Stop after the first failing test |
|
|
179
|
+
| `--retries <n>` | Retry failed tests |
|
|
180
|
+
| `--timeout <ms>` | Playwright default action timeout |
|
|
181
|
+
| `--hard-timeout <ms>` | Per-test ceiling enforced by the runner |
|
|
182
|
+
| `--parallel <n>` | Run up to N spec-file workers concurrently |
|
|
183
|
+
| `--shard-split <n>` | Split tests across N independent shard runs |
|
|
184
|
+
| `--shard-all <n>` | Run all tests on each shard for variance checks |
|
|
185
|
+
| `--reporter <format...>` | `console`, `json`, `junit`, `html` |
|
|
186
|
+
| `--output <dir>` | Report and artifact directory |
|
|
187
|
+
| `--list` | Discover tests without launching a browser |
|
|
188
|
+
|
|
189
|
+
`--parallel` runs different spec files concurrently. Tests inside one file stay
|
|
190
|
+
ordered so hooks, module state, and duplicate names remain predictable.
|
|
191
|
+
|
|
192
|
+
## Observability
|
|
193
|
+
|
|
194
|
+
`--observability` enables the full QA bundle:
|
|
195
|
+
|
|
196
|
+
- visual settle before screenshots
|
|
197
|
+
- full-page screenshots by default
|
|
198
|
+
- performance metrics
|
|
199
|
+
- network capture and issue detection
|
|
200
|
+
- console capture
|
|
201
|
+
- accessibility audit with automatic per-test `audit.md`
|
|
202
|
+
- sidecar artifacts when report defaults allow them
|
|
203
|
+
|
|
204
|
+
Use `--observability-write-sidecars` to force sidecars even when the reporter
|
|
205
|
+
profile would not otherwise write them.
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
test("checkout stays healthy", async ({ page, observability }) => {
|
|
209
|
+
await page.goto("/checkout");
|
|
210
|
+
await observability.expectPerformance({ lcp: "<2500ms", cls: "<0.1" });
|
|
211
|
+
await observability.expectNoNetworkErrors();
|
|
212
|
+
await observability.expectNoConsoleErrors();
|
|
213
|
+
await observability.expectAccessible({ standard: "WCAG21AA" });
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Artifacts can include:
|
|
218
|
+
|
|
219
|
+
- `results.json`
|
|
220
|
+
- `report.html`
|
|
221
|
+
- `junit.xml`
|
|
222
|
+
- screenshots
|
|
223
|
+
- WebM videos
|
|
224
|
+
- Playwright trace zips
|
|
225
|
+
- `perf-trace.md`
|
|
226
|
+
- `network.json`
|
|
227
|
+
- `console.json`
|
|
228
|
+
- `accessibility.json`
|
|
229
|
+
- `audit.md`
|
|
230
|
+
|
|
231
|
+
## Observe
|
|
232
|
+
|
|
233
|
+
`skeptic observe <url>` is the one-command evidence path for exploratory QA.
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
skeptic observe https://example.com --full-page
|
|
237
|
+
skeptic observe https://example.com --no-video --no-trace
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
It writes an output directory containing an HTML report, JSON report,
|
|
241
|
+
screenshots, annotated screenshots, snapshot text/JSON, console/network data,
|
|
242
|
+
performance summary, accessibility JSON, and an accessibility markdown audit.
|
|
243
|
+
|
|
244
|
+
## AI Features
|
|
245
|
+
|
|
246
|
+
Skeptic supports Gemini, OpenAI, and Anthropic.
|
|
247
|
+
|
|
248
|
+
```yaml
|
|
249
|
+
ai:
|
|
250
|
+
provider: openai
|
|
251
|
+
model: gpt-4o
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Set the matching provider key with `GEMINI_API_KEY`, `OPENAI_API_KEY`, or
|
|
255
|
+
`ANTHROPIC_API_KEY`. You can also use `SKEPTIC_AI_PROVIDER` and
|
|
256
|
+
`SKEPTIC_AI_API_KEY` to override config in CI.
|
|
257
|
+
|
|
258
|
+
Available AI paths:
|
|
259
|
+
|
|
260
|
+
- `ai.assert("the dashboard greets the user")`
|
|
261
|
+
- `ai.assertNoDefects()`
|
|
262
|
+
- `ai.extract("the invoice total")`
|
|
263
|
+
- `skeptic generate --message "test checkout"`
|
|
264
|
+
- `skeptic generate --diff`
|
|
265
|
+
- `skeptic run --analyze`
|
|
266
|
+
|
|
267
|
+
Generated specs are typechecked and imported before being written.
|
|
268
|
+
|
|
269
|
+
## MCP And ACP
|
|
270
|
+
|
|
271
|
+
`skeptic mcp` exposes testing and browser QA tools over stdio:
|
|
272
|
+
|
|
273
|
+
| Tool | Purpose |
|
|
274
|
+
|---|---|
|
|
275
|
+
| `list_tests` | Discover specs |
|
|
276
|
+
| `validate_tests` | Typecheck and import-check specs |
|
|
277
|
+
| `generate_test` | Generate a validated TypeScript spec |
|
|
278
|
+
| `run_test` | Run specs and stream progress |
|
|
279
|
+
| `browser_open` | Open a page with config-driven browser/auth/safety |
|
|
280
|
+
| `browser_snapshot` | Capture ARIA/cursor refs |
|
|
281
|
+
| `browser_playwright` | Run focused Playwright code |
|
|
282
|
+
| `browser_screenshot` | Capture PNG, annotated PNG, or snapshot-only output |
|
|
283
|
+
| `browser_console_logs` | Read console messages |
|
|
284
|
+
| `browser_network_requests` | Read requests and computed issues |
|
|
285
|
+
| `browser_performance_metrics` | Capture Web Vitals, LoAF, resources, and `perf-trace.md` |
|
|
286
|
+
| `browser_accessibility_audit` | Run axe-core plus IBM Equal Access when available |
|
|
287
|
+
| `browser_close` | Close the browser session |
|
|
288
|
+
|
|
289
|
+
`skeptic acp` exposes a testing-focused agent server for editors that support
|
|
290
|
+
Agent Client Protocol.
|
|
291
|
+
|
|
292
|
+
## Configuration
|
|
293
|
+
|
|
294
|
+
`skeptic.config.yaml` lives in the project root.
|
|
295
|
+
|
|
296
|
+
```yaml
|
|
297
|
+
url: http://localhost:3000
|
|
298
|
+
tests: "tests/**/*.spec.ts"
|
|
299
|
+
|
|
300
|
+
browser:
|
|
301
|
+
engine: chromium
|
|
302
|
+
headless: true
|
|
303
|
+
timeout: 30000
|
|
304
|
+
viewport:
|
|
305
|
+
width: 1280
|
|
306
|
+
height: 720
|
|
307
|
+
|
|
308
|
+
execution:
|
|
309
|
+
retries: 0
|
|
310
|
+
bail: false
|
|
311
|
+
parallel: 1
|
|
312
|
+
|
|
313
|
+
output:
|
|
314
|
+
dir: ./skeptic-output
|
|
315
|
+
reporters: [console]
|
|
316
|
+
|
|
317
|
+
observability:
|
|
318
|
+
collectors: []
|
|
319
|
+
defaultsForReports: passive
|
|
320
|
+
networkCaptureLimit: 500
|
|
321
|
+
duplicateWindowMs: 500
|
|
322
|
+
accessibilityDualEngine: false
|
|
323
|
+
autoAccessibilityAudit: false
|
|
324
|
+
|
|
325
|
+
safety:
|
|
326
|
+
allowedDomains: []
|
|
327
|
+
confirmActions: []
|
|
328
|
+
maxOutputChars: 120000
|
|
329
|
+
|
|
330
|
+
env:
|
|
331
|
+
BASE_URL: http://localhost:3000
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Cookie Injection
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
skeptic cookies list
|
|
338
|
+
skeptic run --cookies
|
|
339
|
+
skeptic run --cookies-from chrome
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Cookie extraction is opt-in. Cookies are injected into local test browser
|
|
343
|
+
contexts and are not sent to Skeptic services.
|
|
344
|
+
|
|
345
|
+
## CI
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
skeptic add github-action
|
|
349
|
+
skeptic add github-action --ai --provider openai
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
The generated workflow installs dependencies, installs Chromium, starts your dev
|
|
353
|
+
server, runs Skeptic, uploads artifacts, and posts a PR comment with
|
|
354
|
+
`skeptic comment`.
|
|
355
|
+
|
|
356
|
+
## Notifications
|
|
357
|
+
|
|
358
|
+
Optional Slack and webhook notifications are configured under `notifications`.
|
|
359
|
+
Notification failures warn but do not fail the test run.
|
|
360
|
+
|
|
361
|
+
```yaml
|
|
362
|
+
notifications:
|
|
363
|
+
slack:
|
|
364
|
+
webhookUrl: ${SLACK_WEBHOOK_URL}
|
|
365
|
+
onFailure: true
|
|
366
|
+
onSuccess: false
|
|
367
|
+
|
|
368
|
+
webhook:
|
|
369
|
+
url: ${SKEPTIC_WEBHOOK_URL}
|
|
370
|
+
onFailure: true
|
|
371
|
+
onSuccess: false
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Webhook payloads use a `tests` array with name, file, status, duration, error,
|
|
375
|
+
and optional shard metadata.
|
|
376
|
+
|
|
377
|
+
## Diagnostics
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
skeptic doctor
|
|
381
|
+
skeptic doctor --json --quick
|
|
382
|
+
skeptic browsers install chromium
|
|
383
|
+
skeptic daemon status
|
|
384
|
+
skeptic daemon stop
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
`skeptic doctor` checks config, output directories, browser installs, optional
|
|
388
|
+
accessibility/cookie engines, daemon state, cookie profiles, and AI provider
|
|
389
|
+
setup.
|
|
390
|
+
|
|
391
|
+
## License
|
|
392
|
+
|
|
393
|
+
MIT
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skeptic
|
|
3
|
+
description: Use Skeptic for CLI-first browser QA and TypeScript E2E tests. Use when asked to inspect pages, write or run skeptic-cli specs, validate UI changes, capture observability evidence, or use Skeptic MCP tools. Not for unit-only logic with no browser behavior.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- skeptic-agent-skill: managed by skeptic-cli -->
|
|
7
|
+
|
|
8
|
+
# Skeptic
|
|
9
|
+
|
|
10
|
+
Use Skeptic when a coding agent needs browser evidence: page inspection, TypeScript E2E specs, one-off QA captures, AI-backed checks, or MCP browser validation. Do not claim a UI/browser change works until you have run a relevant Skeptic command or MCP tool and checked the evidence.
|
|
11
|
+
|
|
12
|
+
## Choose The Surface
|
|
13
|
+
|
|
14
|
+
- One-off QA or bug hunt: run `skeptic observe <url> --full-page`.
|
|
15
|
+
- Persistent regression coverage: run `skeptic inspect <url> --interactive --compact --with-playwright-hints`, write a `tests/*.spec.ts`, then run `skeptic run`.
|
|
16
|
+
- Changed-code verification: run `skeptic run --diff` when the project has specs, or use `skeptic generate --diff` to create one.
|
|
17
|
+
- Agent-integrated browser work: if Skeptic MCP tools are available, use `browser_open`, `browser_snapshot`, `browser_playwright`, `browser_screenshot`, `browser_console_logs`, `browser_network_requests`, `browser_performance_metrics`, `browser_accessibility_audit`, and `browser_close`.
|
|
18
|
+
|
|
19
|
+
If the `skeptic` binary is not on PATH, try `npx skeptic-cli` or `npx --yes skeptic-cli@latest`.
|
|
20
|
+
|
|
21
|
+
## Fast Loop
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
skeptic doctor --quick
|
|
25
|
+
skeptic inspect <url> --interactive --compact --with-playwright-hints
|
|
26
|
+
skeptic run tests/<scenario>.spec.ts --observability --video --trace
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For a page with no existing spec:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
skeptic observe <url> --full-page --video --trace
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Use the generated `results.json`, `report.html`, screenshots, videos, traces, `network.json`, `console.json`, `accessibility.json`, and `perf-trace.md` as the evidence source. Reference artifact paths from `results.json` instead of guessing filenames.
|
|
36
|
+
|
|
37
|
+
## Writing Specs
|
|
38
|
+
|
|
39
|
+
Skeptic specs import from `skeptic-cli`.
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { test, expect } from "skeptic-cli";
|
|
43
|
+
|
|
44
|
+
test("homepage smoke", async ({ page, snapshot, screenshot, observability }) => {
|
|
45
|
+
await page.goto("https://example.com");
|
|
46
|
+
await expect(page).toHaveTitle(/Example Domain/);
|
|
47
|
+
|
|
48
|
+
const tree = await snapshot(page, { interactive: true, compact: true });
|
|
49
|
+
await tree.byRole("link", { name: "More information..." }).click();
|
|
50
|
+
|
|
51
|
+
await screenshot("homepage", { fullPage: true });
|
|
52
|
+
await observability.expectNoConsoleErrors();
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Rules:
|
|
57
|
+
|
|
58
|
+
- Put browser side effects inside `test(...)`, hooks, or helper functions called from tests.
|
|
59
|
+
- Prefer role, label, text, and test-id locators over CSS.
|
|
60
|
+
- Use `snapshot(page)` before interacting through refs or snapshot helpers.
|
|
61
|
+
- Re-snapshot after navigation, route changes, modal open/close, or major DOM mutation.
|
|
62
|
+
- Do not paste CLI `@eN` refs directly into specs. Use `selectorHint` from `inspect`, or use `tree.byRef("eN")` only for refs returned by the same in-test `snapshot(page)` call.
|
|
63
|
+
- Add `screenshot("name")` for states that would help debug a failure.
|
|
64
|
+
|
|
65
|
+
## Observability Checks
|
|
66
|
+
|
|
67
|
+
Use `--observability` for real QA evidence. In specs, assert the signals that match the risk:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
await observability.expectNoConsoleErrors();
|
|
71
|
+
await observability.expectNoNetworkErrors({ allow: [/analytics/] });
|
|
72
|
+
await observability.expectPerformance({ lcp: "<2500ms", cls: "<0.1" });
|
|
73
|
+
await observability.expectAccessible({ standard: "WCAG21AA" });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If an observability artifact reports a failure, fix the product or the test and re-run the same flow immediately.
|
|
77
|
+
|
|
78
|
+
## MCP Workflow
|
|
79
|
+
|
|
80
|
+
When Skeptic is exposed through MCP:
|
|
81
|
+
|
|
82
|
+
1. `browser_open` the target URL.
|
|
83
|
+
2. `browser_snapshot` or `browser_screenshot` with snapshot mode to get refs.
|
|
84
|
+
3. Use one `browser_playwright` call for actions that share the same DOM state. Use the `ref` helper for snapshot refs and `return` structured evidence.
|
|
85
|
+
4. After DOM-changing actions, request a fresh snapshot.
|
|
86
|
+
5. Check `browser_console_logs`, `browser_network_requests`, `browser_accessibility_audit`, and `browser_performance_metrics`.
|
|
87
|
+
6. `browser_close` when done so video and trace artifacts flush.
|
|
88
|
+
|
|
89
|
+
Batch fills, clicks, and data collection when the DOM is stable. Do not take a new snapshot between plain text fills unless the page structure changed.
|
|
90
|
+
|
|
91
|
+
## Verification Standard
|
|
92
|
+
|
|
93
|
+
Before reporting completion for browser-facing work:
|
|
94
|
+
|
|
95
|
+
- Run the smallest Skeptic command or MCP workflow that actually exercises the changed behavior.
|
|
96
|
+
- Test at least one adjacent or negative path when forms, routing, validation, auth, persistence, or shared components changed.
|
|
97
|
+
- Read the full command/tool output. Passing navigation alone is not enough.
|
|
98
|
+
- If there are console errors, network failures, serious accessibility issues, poor Web Vitals, or visible regressions, fix and re-run.
|
|
99
|
+
- State the exact command/tool run and the main artifact path in the final report.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Skeptic"
|
|
3
|
+
short_description: "Use Skeptic to inspect pages, write TypeScript E2E tests, run browser QA, and collect observability evidence."
|
|
4
|
+
default_prompt: "Use Skeptic to verify this UI or browser behavior with real evidence and report the relevant artifacts."
|
package/bin/launcher.mjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// JS package launcher.
|
|
3
|
+
//
|
|
4
|
+
// The published package always includes the JS bundle at `dist/skeptic.mjs`.
|
|
5
|
+
//
|
|
6
|
+
// This file is intentionally NOT processed by tsup — it's hand-written and
|
|
7
|
+
// stays under `bin/` in the published tarball (declared in package.json
|
|
8
|
+
// `files`). tsup output goes to `dist/skeptic.mjs`.
|
|
9
|
+
|
|
10
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
|
|
13
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const entrypoint = join(here, "..", "dist", "skeptic.mjs");
|
|
15
|
+
|
|
16
|
+
// ESM `import()` rejects raw Windows paths like `C:\...`; convert to
|
|
17
|
+
// `file://` URL first.
|
|
18
|
+
await import(pathToFileURL(entrypoint).href);
|