vibe-testing

mcp
Guvenlik Denetimi
Basarisiz
Health Uyari
  • No license — Repository has no license file
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Basarisiz
  • exec() — Shell command execution in src/cli.ts
  • process.env — Environment variable access in src/cli.ts
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

Code-aware browser testing agent — 13 MCP tools for AI editors (Claude Code, Cursor, Windsurf). Reads your codebase, opens Playwright, tests everything, reports with screenshots.

README.md

vibe-testing

npm version
Node.js
MCP
License: MIT
CI

Code-aware browser testing for AI coding agents.

vibe-testing reads your codebase so tests use your real routes and field names, runs them in a real Playwright browser, remembers what broke, and tells you what your last change fixed or regressed. It works as an MCP server that gives your editor (Claude Code, Cursor, Windsurf, VS Code Copilot, Roo Code) 13 testing tools, or as a standalone CLI.

cd /path/to/your/project
npx vibe-testing@latest init

Then open your editor and say:

"Scan this codebase and test it against http://localhost:3000"


Why not just a browser tool

Playwright MCP gives your agent hands. vibe-testing gives it a testing workflow: code-derived scenarios, memory across runs, and a report. Two things a stateless browser tool cannot do:

1. Run it twice and it tells you what you broke. Every run writes .vibe/run-snapshot.json and diffs it against the previous run. Every scan writes .vibe/route-manifest.json and diffs your routes. The second run prints regressions and fixes instead of a wall of results:

Changes since last run
  Fixed:      /login
  Regression: /checkout
  New:        /admin/users

The same diff reaches your editor as snapshot_diff on run_full_test and run_converge, and as route_changes on scan_codebase, so the agent can flag "checkout broke after that commit" without anyone scrolling a report. Flaky routes, working selectors, and measured timeouts are also remembered between runs.

2. Zero LLM calls inside the tool. Pass/fail verification is heuristic: URL changes, toast detection, API errors. Your editor's model decides what to test; vibe-testing does the browsing and checking. No API key, no per-run cost beyond the editor subscription you already pay for.


Contents


How it works

npx vibe-testing@latest init
        |
Registers 13 MCP tools in your editor
        |
You ask: "Test the checkout flow"
        |
AI calls: scan_codebase -> get_context("checkout") -> login -> explore_page -> execute_scenario -> generate_report
        |
HTML report opens in browser with screenshots of every step

No test cases to write. The AI reads your source code to understand real field names and routes, opens a browser, tests everything, and shows you what's broken.

init also:

  • Detects which AI editors you have installed
  • Registers vibe-test in global editor configs (~/.claude/settings.json, ~/.cursor/mcp.json, and so on) so the tools are available in every project, every session
  • Creates project-level MCP configs and AI instruction files
  • Auto-detects your app's URL (reads .env, vite.config, framework defaults)
  • Creates VIBE.md (edit with your test credentials) and vibe.config.json

MCP setup

Option 1: automatic (recommended)

npx vibe-testing@latest init

Detects and configures all installed editors. Done.

Option 2: manual per editor

Claude Code

Add to ~/.claude/settings.json (global, works in every project):

{
  "mcpServers": {
    "vibe-test": {
      "command": "npx",
      "args": ["-y", "vibe-testing@latest", "--mcp"]
    }
  }
}

Or add to .mcp.json in your project root (project-level only):

{
  "mcpServers": {
    "vibe-test": {
      "command": "npx",
      "args": ["-y", "vibe-testing@latest", "--mcp"]
    }
  }
}

Cursor

Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):

{
  "mcpServers": {
    "vibe-test": {
      "command": "npx",
      "args": ["-y", "vibe-testing@latest", "--mcp"]
    }
  }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "vibe-test": {
      "command": "npx",
      "args": ["-y", "vibe-testing@latest", "--mcp"]
    }
  }
}

VS Code (GitHub Copilot)

Add to .vscode/mcp.json in your project:

{
  "servers": {
    "vibe-test": {
      "command": "npx",
      "args": ["-y", "vibe-testing@latest", "--mcp"]
    }
  }
}

Roo Code / Cline

Add to .roo/mcp.json:

{
  "mcpServers": {
    "vibe-test": {
      "command": "npx",
      "args": ["-y", "vibe-testing@latest", "--mcp"]
    }
  }
}

From local build (development)

{
  "mcpServers": {
    "vibe-test": {
      "command": "node",
      "args": ["/path/to/vibe-testing/dist/mcp-server.js"]
    }
  }
}

MCP tools reference

13 tools available to your AI editor after setup:

Tool When to call Returns
scan_codebase Always first. Reads source code, finds routes/forms/tests/gaps Routes, forms, coverage map, generated scenarios, route_changes since last scan
get_context Before writing test steps. Returns source files for a feature Actual source code with real field names and selectors
login When app requires authentication Post-login screenshot, token state, API calls observed
scan_page_elements To see all interactive elements on a page Element list with selectors plus page screenshot
explore_page Broad "does everything work?" testing Interaction results, API calls, errors, screenshot
execute_scenario Run specific test steps Step-by-step logs plus screenshots
get_coverage View coverage map and untested routes Coverage entries, gaps, available scenarios
suggest_tests Find coverage gaps after exploration Prioritized, ready-to-run scenarios with steps
take_screenshot Quick visual verification Screenshot of any URL
generate_report Build HTML report (auto-opens) Report path plus summary
run_full_test One-shot: scan, execute, explore, report Full results plus snapshot_diff vs last run
run_converge Iterative testing until thresholds Summary across all rounds plus snapshot_diff vs last run
cleanup Close browsers, free resources -

Tool inputs

scan_codebase

{
  "codebase_path": "/path/to/project",
  "url": "http://localhost:3000",
  "mode": "deep"
}

get_context

{ "feature": "login" }
{ "feature": "/checkout" }
{ "feature": "user profile form" }

login

{
  "email": "[email protected]",
  "password": "TestPass123!",
  "login_url": "/login"
}

scan_page_elements / explore_page

{
  "route": "/dashboard",
  "authenticated": true
}

execute_scenario

{
  "scenario": {
    "id": "create-item",
    "name": "Create a new item",
    "route": "/items",
    "steps": [
      { "action": "navigate", "url": "/items", "description": "Open items page" },
      { "action": "click", "selector": "text=Add Item", "description": "Open create form" },
      { "action": "fill", "selector": "[name='title']", "value": "Test Item", "description": "Fill title" },
      { "action": "fill", "selector": "[name='description']", "value": "Test description", "description": "Fill description" },
      { "action": "click", "selector": "button[type='submit']", "description": "Submit form" }
    ],
    "expected_outcome": "New item appears in the list",
    "requires_auth": true
  }
}

Step actions: navigate, fill, click, select, wait, assert, upload

take_screenshot

{ "url": "/settings", "authenticated": true, "full_page": false }

run_full_test

{ "url": "http://localhost:3000", "codebase_path": "/path/to/project", "mode": "deep" }

run_converge

{
  "url": "http://localhost:3000",
  "max_followup_rounds": 4,
  "target_pass_rate": 0.92,
  "max_high_severity_gaps": 2
}

Recommended workflow

Full test session

Tell your AI editor:

Scan this codebase and test it against http://localhost:3000.
Log in with [email protected] / pass123. Explore the dashboard and
settings pages, run the suggested tests, and generate a report.

The AI will:

  1. scan_codebase, to understand routes, forms, existing tests
  2. get_context("login"), to read the actual login form source code
  3. login, to authenticate in a real browser
  4. explore_page("/dashboard"), clicking everything and observing what breaks
  5. explore_page("/settings"), same
  6. suggest_tests, to find coverage gaps
  7. execute_scenario x N, running targeted test flows
  8. generate_report, HTML report opens automatically
  9. cleanup, closing browsers

Test a specific feature

Test the checkout flow using vibe-test. Get context for checkout,
then run the full purchase flow with card number 4242424242424242.

The AI will:

  1. scan_codebase (if not already done)
  2. get_context("checkout"), reading CheckoutForm.tsx, api/orders/route.ts and so on
  3. login
  4. execute_scenario, filling the real form fields from source code
  5. generate_report

Verify a bug fix

I fixed the login redirect bug. Use vibe-test to confirm it's working.

The AI will:

  1. login, testing the login flow
  2. take_screenshot, visual confirmation of the post-login state
  3. Report back what it sees

Find what's broken

Explore every page and tell me what's broken.

The AI will run explore_page on every route, collecting API errors, broken elements, and failed interactions, then suggest_tests with the broken items marked as high priority.


init command

npx vibe-testing@latest init [options]

What it creates:

File Where Purpose
.mcp.json Project root Claude Code MCP config (project-level)
~/.claude/settings.json Global Claude Code MCP config (all projects)
.cursor/mcp.json Project root Cursor MCP config
~/.cursor/mcp.json Global Cursor MCP config (all projects)
.cursor/rules/vibe-test.mdc Project Cursor rules, alwaysApply: true
.windsurfrules Project Windsurf instructions
~/.codeium/windsurf/mcp_config.json Global Windsurf MCP config (all projects)
.vscode/mcp.json Project VS Code Copilot MCP config
.github/copilot-instructions.md Project GitHub Copilot instructions
.roo/mcp.json Project Roo Code MCP config
CLAUDE.md Project Claude Code session instructions
AGENTS.md Project Universal agent instructions (Codex, Devin, Zed)
VIBE.md Project Test guidance, edit with your credentials
vibe.config.json Project Config, URL auto-detected from your project

Options:

npx vibe-testing@latest init                     # auto-detect editors, register globally + project
npx vibe-testing@latest init --no-global         # project-level only, skip global registration
npx vibe-testing@latest init --editor cursor     # only configure Cursor
npx vibe-testing@latest init --editor claude-code windsurf

After init, edit VIBE.md with your login URL and test credentials.


CLI commands

# Set up in current project
npx vibe-testing@latest init

# Run tests against a URL
npx vibe-testing@latest run http://localhost:3000
npx vibe-testing@latest run https://staging.myapp.com --mode deep
npx vibe-testing@latest run http://localhost:3000 --codebase /path/to/project --scope /login /dashboard

# Iterative testing until coverage thresholds
npx vibe-testing@latest converge http://localhost:3000
npx vibe-testing@latest converge http://localhost:3000 --max-rounds 6 --target-pass-rate 0.95

# Open last report in browser
npx vibe-testing@latest report

# Reset memory and screenshots for a clean run
npx vibe-testing@latest reset

run options

Option Default Description
--mode fast|deep deep fast: quick scan. deep: full feature extraction plus exploration
--no-headed - Run browser headless (default: visible)
--codebase <path> cwd Path to project root
--scope <routes...> all Test only specific routes
-c <path> vibe.config.json Config file path

converge options

Option Default Description
--max-rounds <n> 4 Max follow-up rounds after baseline
--target-pass-rate <r> 0.92 Stop when pass rate reaches this (0-1)
--max-gaps <n> 2 Stop when critical plus important gaps fall to this

VIBE.md, project guidance

Create VIBE.md in your project root. vibe-testing reads it automatically on every run.

## Login URL
/login

## Test Credentials
- Email: [email protected]
- Password: TestPass123!

## Never Automate
- delete account
- cancel subscription
- [data-testid="danger-zone"]
- .billing-section

## Known Flaky
- /notifications (WebSocket dependent, skip or expect retry)
- /live-feed

## Notes
- Admin panel at /admin, use [email protected] / adminpass
- Dashboard data loads async, wait for [data-loaded="true"]
- Profile page: click "Edit Profile" before form fields appear

See VIBE.example.md for the full template.


Configuration

vibe.config.json

Created automatically by init with auto-detected URL. Edit as needed:

{
  "url": "http://localhost:3000",
  "mode": "deep",
  "auth": {
    "strategy": "credentials",
    "login_url": "/login",
    "credentials": {
      "email": "[email protected]",
      "password": "TestPass123!"
    }
  },
  "never_interact": [
    "delete account",
    "cancel subscription",
    "[data-testid='danger-zone']"
  ],
  "scope": {
    "include": ["/**"],
    "exclude": ["/admin/**", "/api/**"],
    "max_routes": 30,
    "seed_routes": ["/live/dev-mode-a-now"]
  },
  "browser": {
    "headed": true,
    "slowMo": 40,
    "timeout": 30000
  }
}
Key Description
url App URL, localhost or staging. Auto-detected by init.
mode fast (heuristic scan) or deep (full extraction plus exploration)
auth.strategy credentials (form login), basic (HTTP Basic Auth), or skip
auth.login_url Explicit login route for non-standard paths keyword matching would miss
auth.credentials Login credentials, used for login and for generated scenarios, persisted across runs
never_interact Text patterns or CSS selectors to skip during exploration
scope.exclude Route patterns to exclude from testing
scope.max_routes Cap how many routes are tested per run
scope.seed_routes Concrete URLs for dynamic-segment routes the parser can't enumerate (e.g. /live/[slug] becomes /live/dev-mode-a-now). Each seeded route inherits requires_auth and the source file from its dynamic parent.
browser.headed true = visible browser. CLI default true, MCP server default false (headless) so editor sessions aren't disrupted by pop-up windows.
browser.slowMo Milliseconds between actions (useful for debugging)
routes auto (default) discovers routes from the codebase. config uses only routes explicitly listed in config.

Supported frameworks

Framework Routes API endpoints Forms
Next.js App Router yes yes yes
Next.js Pages Router yes yes yes
Next.js (src/ variant) yes yes yes
React SPA (react-router) yes - yes
Vue + Vite (vue-router) yes - yes
Nuxt yes yes yes
SvelteKit yes yes yes
Express / Fastify - yes yes
Monorepos (Turborepo, pnpm, Lerna) yes yes yes

Existing test files are also read to build a coverage map: Jest, Vitest, Playwright, and Cypress suites are all parsed.


Memory and regression detection

vibe-testing learns across runs and stores state in .vibe/:

  • Working selectors: remembers [name='email'] worked on /login, uses it next run
  • Route timings: adjusts timeouts based on measured load times
  • Auth credentials: saved after first login, reused automatically
  • Flaky routes: tracks high fail-rate routes, marks them for retry
  • Skip routes: routes that consistently error (need URL params) are auto-skipped
  • Route manifest (.vibe/route-manifest.json): every scan diffs against the previous one; new and removed routes surface as route_changes on scan_codebase results so the AI can cover them immediately
  • Run snapshot (.vibe/run-snapshot.json): every run captures per-route pass/fail and diffs against the prior run; snapshot_diff flags newly_passing (fixes), newly_failing (regressions), still_failing, plus added and removed routes
{
  "snapshot_diff": {
    "newly_passing": ["/login"],
    "newly_failing": ["/checkout"],
    "still_failing": [],
    "new_routes": ["/admin/users"],
    "removed_routes": []
  }
}

run_converge returns the same shape, so iterative runs in your editor highlight what you just broke.

Reset with npx vibe-testing@latest reset to start fresh.


What a session looks like

When you ask your editor to "test the login flow", here is what it does:

User: "Test the login flow"

AI calls:
  scan_codebase({ codebase_path: ".", url: "http://localhost:3000" })
    -> Finds /login route, LoginForm component, POST /api/auth/login endpoint
    -> Returns 8 generated test scenarios

  get_context({ feature: "login" })
    -> Returns src/app/login/page.tsx (has name="email", name="password" fields)
    -> Returns src/app/api/auth/login/route.ts (POST handler, returns { token })
    -> AI now knows the real selectors: [name='email'], [name='password']

  login({ email: "[email protected]", password: "pass123" })
    -> Opens Chromium, fills the form, clicks submit
    -> Returns: { success: true, final_url: "/dashboard", tokens_found: 2 }
    -> Returns screenshot of post-login dashboard

  execute_scenario({ scenario: { name: "Login with invalid password", ... } })
    -> Returns screenshot showing error state

  generate_report()
    -> Writes .vibe/report.html, opens in browser

AI reports: "Login works. Invalid password shows an error. All 3 login scenarios passed."

FAQ

Does vibe-testing use an LLM internally?
No. It uses heuristic verification (URL changes, toast detection, API errors). Your editor's model is the brain: it sees screenshots and decides what to test next. Runs have no API cost.

What's the difference between explore_page and execute_scenario?
explore_page is broad: it clicks every button and input it finds and reports the results. execute_scenario is precise: you give it specific steps and it follows them exactly. Use explore_page to find what's on a page, then execute_scenario to test specific flows.

What's get_context for?
It returns the actual source code for a feature, so the AI knows [name='email'] instead of guessing #email-input. Always call it before writing test steps for a specific feature.

Does it handle SPAs with client-side routing?
Yes. Playwright navigates the real browser, so client-side routing (React Router, Vue Router, and the rest) works naturally.

Does it handle login / authentication?
Yes. The login tool fills credentials in a real browser, captures auth tokens from localStorage/cookies, and keeps that session alive for authenticated tests. Credentials are persisted in .vibe/memory/ and reused automatically.

Will it click "Delete Account" or other destructive buttons?
No. Set never_interact in vibe.config.json or VIBE.md to blocklist dangerous actions. Any button whose text or selector matches is skipped during exploration.

Can I use it without an AI editor?
Yes. vibe-test run https://your-app.com runs standalone. It scans, generates scenarios, executes them, and produces an HTML report without needing an editor.

How do I test a staging environment?
Set url in vibe.config.json to your staging URL, or pass it as a CLI argument: npx vibe-testing@latest run https://staging.myapp.com.

Does it work with monorepos?
Yes. init detects Turborepo/pnpm/yarn workspaces and finds the frontend app automatically.


Requirements

  • Node.js >= 20 (the test suite uses vitest 4.x which requires Node 20+)
  • Playwright Chromium, install once with:
    npx playwright install chromium
    
    (vibe-testing will prompt you if it's missing)

Docker

A Node 20 + Chromium image is included for environments that prefer container-based MCP servers:

docker build -t vibe-test .
# wire into your editor's MCP config:
# { "command": "docker", "args": ["run", "--rm", "-i", "vibe-test"] }

Contributing

git clone https://github.com/AishwaryShrivastav/vibe-testing.git
cd vibe-testing
npm install
npx playwright install chromium
npm run build   # tsc -> dist/
npm run dev     # run CLI without building
npm run mcp     # run MCP server without building
npm test        # vitest, 63 tests

See CHANGELOG.md for version history. Bug reports and feature requests: GitHub issues.


License

MIT, Aishwary Shrivastav


Links

Yorumlar (0)

Sonuc bulunamadi