Hyperyond/Hover

GitHub: Hyperyond/Hover

Stars: 10 | Forks: 1

# Hover Hover — the local-first, open-source way to author end-to-end tests with AI

English · 简体中文

License @hover-dev/cli on npm Covers Vite, Astro, Nuxt, Webpack, RN Web @hover-dev/core on npm

Documentation Latest release Stars Forks Last commit Local CLI Agent First

Open the floating chat in your dev page, describe what you want to verify in plain English, and watch AI operate your app for real. When the run is clean, click **Save as spec** — Hover writes a standard `@playwright/test` file that runs in CI without an agent in the loop, forever. **No API key, no per-token billing.** Hover spawns the coding-agent CLI already on your `PATH` (claude / codex) and rides on the subscription you already pay for. The differentiator: AI authors the test, but the saved artifact is plain `@playwright/test` code that runs with `npx playwright test` on a fresh machine — no agent, no model, no key. The LLM cost is a one-off you opt into at authoring time, never a recurring tax on green builds. ## See it in action

Hover demo — watch on YouTube
▶ Watch the demo on YouTube

Ten real example apps live under [`examples/`](./examples/). Four stress different **testing surfaces**; the other six exercise **bundler / framework coverage**. ### Testing surfaces
01 · basic-app — login + counter + todos
01 · basic-app — the smoke baseline. Login → counter → add a todo. The agent ran the full sequence in 11 turns at $0.16; the result card offers both Save as Skill and Save as spec.
02 · stock-registration — multi-step brokerage form
02 · stock-registration — ~50-field broker application with conditional reveals. The agent fills the text fields, then the form's validator catches required radio groups; Hover surfaces a done card so the human can finish those and re-run.
03 · e-commerce — cart and checkout
03 · e-commerce — Amazon-style storefront. "Buy two top-rated headphones, ship to my saved address, pay with card." Long action chain, real cart state, ready for Save as spec.
04 · canvas-paint — DOM toolbar amid canvas pixels
04 · canvas-paint — a drawing app whose artwork is an opaque <canvas>. Snapshots can't read pixels, but the agent navigates the DOM toolbar end-to-end — Hover's semantic-selector preference holds even when the visual surface isn't introspectable.
### Bundler coverage Each target below pairs a counter + todo smoke page with a different host bundler, so every Hover integration has a dedicated dogfood ground. | Example | Bundler / framework | Hover package | Port | |---|---|---|---| | [`examples/astro-app`](./examples/astro-app) | Astro 5 (static, `astro dev`) | [`@hover-dev/astro`](./packages/astro-integration/) | 5178 | | [`examples/nuxt-app`](./examples/nuxt-app) | Nuxt 4 (SSR, `nuxt dev`) | [`@hover-dev/nuxt`](./packages/nuxt-integration/) | 5179 | | [`examples/next-app`](./examples/next-app) | Next.js 16 App Router (Turbopack, `next dev`) | [`@hover-dev/next`](./packages/next-integration/) | 5182 | | [`examples/webpack-app`](./examples/webpack-app) | vanilla webpack 5 + `webpack-dev-server` | [`webpack-plugin-hover`](./packages/webpack-plugin/) | 5180 | | [`examples/rn-web-app`](./examples/rn-web-app) | React Native Web (Vite alias) | [`vite-plugin-hover`](./packages/vite-plugin/) | 5181 | | [`examples/payment-provider`](./examples/payment-provider) | Vite, **no Hover plugin** | n/a | 5177 | `payment-provider` is deliberately uninstrumented — e-commerce's "Pay with PayHover" button opens it in a new tab, and the agent has to discover, switch to, and drive it without a widget present. **React Native:** only the **Web** target is supported (it compiles to plain DOM). Native iOS / Android is out of scope — the CDP + Playwright + Shadow-DOM stack doesn't translate to native, and [Maestro](https://maestro.mobile.dev/) / [Detox](https://wix.github.io/Detox/) / Appium serve that space. ## Why Hover Several good tools exist in this space; Hover is what falls out when you optimise for a different axis — **artifact portability**. | Tool | What it does | The trade-off | |---|---|---| | **Playwright Codegen** | Records your clicks → `.spec.ts`. No AI | Can't think — replays what you did literally | | **Stagehand / Midscene** | AI-augmented tests; caches skip the LLM on steady-state runs. Needs an OpenAI / Anthropic key (per-token on cache misses) | Tests run **inside the vendor SDK** + a cache file. Not portable to a plain Playwright runner | | **Hover** | AI drives the browser **once** to explore, then saves a deterministic spec, a replayable skill, *and* a Jira-importable case from the same click. **No API key — spawns the CLI on your `PATH`** (claude / codex / cursor-agent / aider / gemini-cli / qwen-code) | Crystallised spec is brittle to UI changes — when it breaks, re-run the agent (it doesn't self-heal at CI time) | Hover is **not** trying to be the better test-time AI runtime — Stagehand's caching + self-healing and Midscene's vision fallback are more sophisticated than anything we'd build. Hover makes the saved artifact be plain `@playwright/test` code that runs with zero AI deps. The agent's job ends at "save"; CI is pure Playwright. **Zero AI at runtime, zero tokens in CI.** Some AI-testing tools keep a model in the loop when the test *runs* — every PR, every nightly pays for LLM calls and needs a key wired into CI. Hover spends the model once, at authoring time, on the machine of a developer who already pays for a `claude` / `codex` subscription. The saved `.spec.ts` then runs forever with no model and no per-token bill. ### Crystallise three ways A single **💾 Save as ▾** dropdown on the done card crystallises one verified session three ways. Pick one, two, or all three — every file checks into the same git repo, readable by teammates who never install Hover. | | `📜 .spec.ts` | `💾 SKILL.md` | `📋 .case.csv` | |---|---|---|---| | **Lands in** | `__vibe_tests__/` | `.claude/skills/` | `__vibe_tests__/` | | **Read by** | Node + Playwright (CI) | Claude Code / agent | Xray · Zephyr Scale · Jira importer | | **Audience** | CI, devs writing code | Future you, exploring | QA reviewing · PM tracking | | **Determinism** | Hard contract | Best-effort replay | Manual review | | **Edit with** | Code editor | Markdown editor | Spreadsheet / test-mgmt UI | The spec is `getByRole / getByLabel / getByText` semantic selectors with a JSDoc header carrying plain-English `Steps:` + `Expected:` blocks, so QA and PMs can read what a test does without opening Playwright docs. Skills replay from a future conversation (*"execute login-as-claude"*). The Jira case imports as a real, trackable Manual Test issue.

Save dropdown — Playwright spec, Claude Code Skill, Jira test case (CSV) Save as Jira case modal

## What you get today - **Five bundler integrations.** Vite, Astro, Nuxt, Next.js (Turbopack), and webpack 5 each have a dedicated package; React Native Web rides on `vite-plugin-hover`. The plugin injects a Shadow-DOM widget into your dev page, is a no-op in production, and is marked `data-hover="true"` so your own Playwright runs skip it. - **No API key, no `.env`, no per-token billing.** Hover spawns whichever coding-agent CLI is on your `PATH` and reuses the subscription you already pay for. `@hover-dev/core` contains zero LLM SDK code. - **Six agents wired.** `claude` (hard sandbox, recommended), `codex`, `cursor-agent`, `aider`, `gemini-cli`, `qwen-code` (the last five soft-sandbox — ⚠ badge in the dropdown). The service auto-detects what's on PATH; the widget header shows the active agent and switches on the fly. New agents are one file in the registry. - **Per-agent sandbox.** Hard-sandbox agents get an allow/deny list so only Playwright MCP is callable (`Bash` / `Edit` / `Write` / `Read` / `WebFetch` denied), plus a `--max-budget-usd` ceiling. Soft-sandbox agents run `--sandbox read-only` + a strict system prompt and carry a ⚠ badge. - **Three crystallisation formats** — Playwright spec, replayable Skill, Jira-importable CSV — from the same Save card (see [above](#crystallise-three-ways)). - **Visibility-guarded specs.** Every interaction in a saved spec is wrapped in `{ const el = …; await expect(el).toBeVisible(); await el.; }`, so UI drift fails loudly with a named assertion instead of a generic 30 s timeout. - **⟳ Re-record.** When the UI shifts enough to break a spec, the agent replays the spec's `Original prompt:` against the current UI and rewrites the selectors. From the widget's **Saved sessions** overlay or `pnpm hover re-record `. CI stays pure Playwright — AI only at the authoring step. - **Record mode + checks.** Toggle Record, do the flow by hand, get the same step sequence. A sub-toolbar switches the next click between `● Record / ✓ Exists / ¶ Says / = Equals`; checks bake into the same `.spec.ts`. - **CDP-attached driving.** Hover drives an isolated debug Chrome under `/hover-chrome`, never your main profile. Log in once; the profile persists across runs. - **Result & Findings cards.** The agent's verification report renders as a Result card; any `## Findings` (bugs / minor / notes) land in a severity-coded Findings card. Bug discovery is a first-class output. - **Session persistence.** Widget state survives reload via `localStorage`; the next prompt resumes the same `claude --session-id`.

Agent picker — installed vs. available agents Findings card — severity-coded bugs the agent flagged

Left: switch agents from the widget header; installed ones are live, the rest carry a copy-paste install hint. Right: the agent's bugs land in a severity-coded Findings card, kept apart from the step timeline.

### Security testing `@hover-dev/security` is Hover's first optional plugin. Install it next to the base plugin and the widget grows a **Security testing** mode (the panel turns orange to signal altered state). Hover routes the debug Chrome through a local HTTPS MITM proxy — built on [mockttp](https://github.com/httptoolkit/mockttp), zero external deps, no Python or system CA install — and the agent inspects captured API calls and replays them with mutations. **What it probes for:** IDOR, auth bypass, parameter tampering, mass assignment, missing security headers (CSP / X-Frame-Options / HSTS / SameSite), and PII leakage. **Out of scope:** SQL injection, SSRF, command injection, and fuzzing loops — run a server-side scanner for those. Confirmed findings crystallise into `.security.spec.ts` regression tests that run in CI without the proxy or agent. Full walkthrough: [docs/features/security](https://gethover.dev/docs/features/security). Wiring is in [Use it in your project](#use-it-in-your-project) below. ### Voice mode Hold the round 🎙 button next to Send (push-to-talk), speak your prompt in Chinese or English (Hover detects the language), release to fire. Key step events get read back aloud in the same language so you can keep your eyes on the page. Pure browser-native Web Speech API — no API keys; Chrome 139+ runs the recogniser on-device. Mute narration from the ⚙ settings panel. Details: [docs/features/voice](https://gethover.dev/docs/features/voice). ### Fix prompt A Vite transform stamps `data-hover-source="file:line:col"` onto every host element you authored in JSX / Vue / Svelte / Astro. Click the **⌖ Fix** button, click any element, type what you'd like to change, hit ⌘↵, and Hover assembles a fact-only prompt — your intent, the element's source `file:line:col`, the ancestor source chain, the component chain, the Playwright selector, and the outer HTML — onto your clipboard. Paste into Cursor / Claude Code / Windsurf and the agent has exact context.

Vague natural-language ask vs. a structured, source-attributed Fix prompt

The ancestor chain matters for wrapper-rendered hosts: a `` renders a `
标签:自动化攻击