Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Launch the app and hands-on verify that it works by interacting with it. Falls back to an existing integration test suite when there is no interactive surface in scope. Use when the user asks to "smoke test", "test it manually", "verify it works", "try it out", "run a smoke test", "check it in the browser", or "does it actually work". Not a unit test runner.
.claude/skills/tobihagemann-smoke-test/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 53% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 100% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 36% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 88% | 0% |
Launch the app and hands-on verify that it works by interacting with it. Every smoke test is a concrete interaction with the running app: navigating a screen, clicking a control, filling a form, running a CLI command, and observing the result.
Resolve scope using the first match:
Always check for project-specific testing skills or MCP tools first. Use the fallbacks below when nothing project-specific is available:
browser-use@openai-bundled plugincomputer-use@openai-bundled pluginBefore drafting tests, check whether there is something to exercise:
Otherwise, design targeted smoke tests. Each test should:
Output the plan as text:
Smoke Test Plan:
1. [Interaction with the running app] — what the interaction verifies
2. [Interaction with the running app] — what the interaction verifies
3. [Interaction with the running app] — what the interaction verifies
Approach: [browser-use@openai-bundled / computer-use@openai-bundled / terminal]
Dev server command: [command]When another agent will execute this plan, append a Setup contract capturing what the executor needs and cannot safely rediscover:
Include an item when the executor would otherwise derive it from application source, or when it is state this run generated that the executor cannot rediscover safely; omit anything the running app makes self-evident. Require these details when the chosen testing approach prohibits reading application source as setup documentation.
Write each precondition as an observation the executor makes rather than a fact it can rely on, and say what to do when it does not hold: name the substitute setup, or direct the executor to report the precondition as wrong rather than the scenario as failed.
When the scope's happy path writes to a shared external system and those writes are not cleanly undoable, scope the plan to a path that provably cannot write: choose fixture data with nothing to act on, so the run still exercises wiring, auth, queries, guards, and failure isolation while writing nothing. Treat writes as not cleanly undoable whenever restoring the records leaves downstream effects the writes triggered in place. State that scoping choice in the plan so the executor does not widen it back. When the writing path must run, work through it in order. Determine the full write set without executing it: use a dry-run mode when one exists, otherwise trace the code path and enumerate every record it writes, including those reached through triggers, cascades, and hooks. State what the enumeration cannot settle rather than presenting it as complete. Pick the target whose writes are incidental to what the run verifies, weighing each candidate's write set against the coverage it adds. Then request approval via request_user_input, presenting the enumeration as what is being consented to, and request it again whenever the enumeration changes. When request_user_input does not reach the user, write nothing and report the approval as unresolved. Capture a pre-run manifest and write an ordered revert procedure; when another agent will execute the plan, carry the enumeration, the manifest, and the revert procedure in the Setup contract's Seed/reset item.
When a scenario's pass condition is that nothing happens — no write, no call, no state change — pair it with a control that differs only in the dimension under test and whose expected outcome is that the effect does occur. A lone negative scenario cannot distinguish the behavior under test from a harness that never reached it. Run the control through a stub that intercepts the mechanism, introducing one when the negative scenario was scoped by fixture data alone, so observing the effect there establishes that the interception point is reached. When no stub can intercept the mechanism, carry the control through the write enumeration and approval sequence above, and record it in the plan as authorized scope rather than a widening. When neither control can run, plan the negative scenario as inconclusive and say so. Pair each guard separately.
If a project-specific testing skill or MCP tool was identified in Step 2, use that. The paths below are fallbacks.
Reuse a running dev server only when this session started it. Otherwise start one on a port this run selected and wait for it to be ready. Confirm it bound to that port before sending it traffic — a failed bind leaves another agent's service answering. Move to another port when the port is taken; report the error and stop when the server itself failed to start. Use the browser-use@openai-bundled plugin to interact with the app.
Core verification loop per test:
Close the browser session and stop the dev server when done.
Launch the app. Use the computer-use@openai-bundled plugin to interact with the UI.
Core verification loop per test:
Run commands directly.
Core verification loop per test:
Fallback when Step 3 routed here because nothing was interactive. Run the discovered target. Run multiple integration targets sequentially when they reset or mutate a shared test database, even when the checks are otherwise independent. Tail output in a background shell for long-running suites so failures surface as they happen.
Core verification loop per run:
Do not invent a target if none was found in Step 3 — that gate already stopped.
Before reporting a planned test as unverified, retry its setup with the Step 3 techniques for blocked infrastructure and for privileged state, unless Step 3 already tried them and they failed. When the setup succeeds, run the test and record its result. Report a test as unverified only after that attempt, naming what was tried and what blocked it. Treat an existing unit test over the same behavior as no substitute: it leaves the interactive path unexercised.
Report a negative test and its control together: the negative reads as passed only when its control produced the effect, and as inconclusive otherwise.
Present a summary:
Smoke Test Results:
- [PASS] Test 1: description
- [FAIL] Test 2: description — [what went wrong]
- [UNVERIFIED] Test 3: description — [what was tried, what blocked it]
- [INCONCLUSIVE] Test 4: description — [why the result cannot be read]
Overall: X/Y passed, Z unverified, W inconclusiveIf any test failed, include the relevant snapshot, screenshot, or output showing the failure.
Then call update_plan to mark this step completed and continue with the next step of the active workflow.
tmux -L <name>), give each browser session a unique name so cleanup can target only its own, and write screenshots and other scratch state to absolute paths under a unique scratch directory outside the repository under test. Derive each such identifier once and reuse that exact value in every later command, writing it as a literal or reading it back from a note under the run's scratch directory. A value recomputed per shell, such as $$, differs between the command that creates a resource and the command that releases it, so cleanup releases something it never created and reports success while the real resource leaks. A port picked as unique may already be held by a concurrent agent, so check it before binding and move to another when it is taken, leaving the incumbent running.$investigate skill on the smoke test report.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | pass→pass | 11,370 | 13,760 | +21% | 1 | 1 | 0% | 2,139 | 4,416 | +106% | 0 | 0 | — |
case-01 | fail→fail | 4,791 | 39,790 | +731% | 1 | 1 | 0% | 314 | 3,202 | +920% | 0 | 0 | — |
case-02 | fail→fail | 4,036 | 4,790 | +19% | 1 | 1 | 0% | 222 | 3,256 | +1367% | 0 | 0 | — |
case-03 | fail→fail | 19,638 | 4,276 | -78% | 1 | 1 | 0% | 3,271 | 3,147 | -4% | 0 | 0 | — |
case-04 | fail→fail | 14,040 | 6,467 | -54% | 1 | 1 | 0% | 2,680 | 3,163 | +18% | 0 | 0 | — |
case-05 | fail→fail | 13,263 | 6,548 | -51% | 1 | 1 | 0% | 2,368 | 4,241 | +79% | 0 | 0 | — |
case-06 | fail→pass | 14,254 | 9,364 | -34% | 1 | 1 | 0% | 2,842 | 4,834 | +70% | 0 | 0 | — |
case-07 | fail→pass | 16,312 | 41,850 | +157% | 1 | 1 | 0% | 2,833 | 4,346 | +53% | 0 | 0 | — |
case-09 | fail→pass | 9,579 | 2,653 | -72% | 1 | 1 | 0% | 1,702 | 3,405 | +100% | 0 | 0 | — |
case-10 | fail→pass | 26,267 | 7,582 | -71% | 1 | 1 | 0% | 3,139 | 4,273 | +36% | 0 | 0 | — |
case-11 | fail→fail | 12,017 | 3,178 | -74% | 1 | 1 | 0% | 2,209 | 3,549 | +61% | 0 | 0 | — |
case-12 | pass→pass | 9,868 | 5,035 | -49% | 1 | 1 | 0% | 1,768 | 3,932 | +122% | 0 | 0 | — |
case-13 | pass→fail | 3,584 | 2,795 | -22% | 1 | 1 | 0% | 566 | 3,445 | +509% | 0 | 0 | — |
case-14 | fail→fail | 11,552 | 6,116 | -47% | 1 | 1 | 0% | 1,937 | 4,082 | +111% | 0 | 0 | — |
case-15 | pass→pass | 9,364 | 22,218 | +137% | 1 | 1 | 0% | 2,057 | 7,486 | +264% | 0 | 0 | — |
case-16 | pass→fail | 6,653 | 5,711 | -14% | 1 | 1 | 0% | 1,341 | 3,238 | +141% | 0 | 0 | — |
case-17 | pass→fail | 13,769 | 13,163 | -4% | 1 | 1 | 0% | 2,626 | 4,850 | +85% | 0 | 0 | — |
case-18 | pass→pass | 13,518 | 5,085 | -62% | 1 | 1 | 0% | 2,329 | 3,871 | +66% | 0 | 0 | — |
case-19 | pass→pass | 8,948 | 4,300 | -52% | 1 | 1 | 0% | 1,368 | 3,783 | +177% | 0 | 0 | — |
case-20 | pass→pass | 13,253 | 5,622 | -58% | 1 | 1 | 0% | 2,035 | 3,950 | +94% | 0 | 0 | — |
case-21 | pass→pass | 9,501 | 2,158 | -77% | 1 | 1 | 0% | 1,434 | 3,265 | +128% | 0 | 0 | — |
case-22 | fail→pass | 18,979 | 2,219 | -88% | 1 | 1 | 0% | 1,727 | 3,250 | +88% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 17 counted toward the lift figure. The other 5 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +9 percentage points is the difference between those two pass rates over the 17 comparable cases. 4 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/21/2026 | +18% |
Other measured skills in the registry, with their headline benchmark lift.