Most test tooling assumes the app under test lives on a public URL. But the version you actually change every day is the one running on localhost:3000. If you can only generate and run tests against staging, you find out about broken flows after you push — not before.
TestVibe closes that gap. You can point a project at the build running on your own machine, capture a journey in your own browser, and have the AI generate and verify Playwright tests against it. This guide walks through the pieces that make local testing work.
Why localhost needs one extra step
TestVibe generates and runs tests in isolated cloud sessions. That is what keeps AI-generated code from touching your infrastructure, and it is why a public or staging URL "just works": the cloud session opens it directly.
Your dev build is different. A cloud session has no route to http://localhost:3000 on your laptop. The docs are blunt about it:
Avoid
localhost— a cloud session cannot reach your machine without a tunnel device running on it.
So the whole trick to testing your local app is giving the cloud a reachable path back to it. That path is a tunnel device.
Connect a tunnel device
A tunnel device is a machine on your network running the small tvtunnel agent. Once it is connected, cloud sessions (generation, runs, and assistant browsing alike) reach your app through the tunnel instead of over the public internet. The app URL stays exactly what it is, and traffic is end-to-end encrypted. Nothing inbound is opened on your firewall.
Setup is one command on the machine running your dev build (Node 20+):
# Windows PowerShell: the Tunnels panel fills in the real values
iwr <agent-tarball-url> -OutFile tvtunnel.tgz; npx --yes ./tvtunnel.tgz --token <your-api-key> --server <your-testvibe-url>
# macOS / Linux
curl -fsSL <agent-tarball-url> -o tvtunnel.tgz && npx --yes ./tvtunnel.tgz --token <your-api-key> --server <your-testvibe-url>
Grab the token from Settings → CLI & API keys, then open Settings → Tunnels and copy the exact command shown for your OS. It pre-fills the tarball URL, token, and server so you do not retype anything. The device shows up in the list on its own the moment the agent connects.

Two things to keep in mind. Flip Route this project through a tunnel on for the project so its sessions use the device rather than direct cloud egress. And keep tvtunnel running as a service on a stable machine: a laptop that goes to sleep takes the tunnel down mid-run.
Point the project at your dev build
With a tunnel in place, add your local URL as an environment. A project can hold several test site URLs (staging, QA, preview) with one marked default; runs, recordings, and automations each pick which one to use, and generation asks you to confirm the site URL before it starts.
Add http://localhost:3000 (or whatever port your dev server binds to) under Settings → Environments. Start the server the way you normally would:
npm run dev
# ▲ Ready on http://localhost:3000
Now the same project can target staging when you want a shared run and your local build when you are mid-change. You choose the environment per generation or per run — no second project to maintain.
Capture the flow in your own browser
You can describe a feature in plain language and let generation explore it, but for a flow with a lot of clicks it is often faster to just perform it once. That is what the TestVibe Recorder browser extension is for.
From a feature's editor, choose Record, install the extension if prompted, and pick which environment to record against, selecting your local one. Then walk the journey in your own browser: click, type, navigate. Each action streams live into the recorder timeline back in TestVibe, and full-page or cross-origin navigation is captured as a step rather than lost.
Because the recorder runs in your browser, it reaches localhost natively. No tunnel needed for the capture itself. When you finish, TestVibe turns the steps into a reviewable Gherkin scenario:
Scenario: Checkout with a saved card
Given I am signed in as a returning customer
When I add "Wireless Keyboard" to the cart
And I complete checkout with my saved card
Then I see an order confirmation number
Review it before saving. The recorder output is a first draft, not a finished test: tighten the feature name, keep each scenario to one behavior, make sure there is a real Then assertion, and strip any sensitive values that slipped in.
Generate, verify, and catch it pre-deploy
Saving the feature is where the cloud comes back in. When you generate Playwright code or hit Verify on a recording, the cloud session replays each step against your app. Because the project routes through the tunnel, "your app" is the build on your machine.
Verify replays every recorded step and swaps any flaky selector for the most stable one that resolves, reporting the outcome per step:
| Chip | Meaning |
|---|---|
| selector OK | The recorded selector resolved as-is. |
| AI updated | AI picked a better selector for this step. |
| needs review | The selector didn't resolve — check it before relying on the test. |
The honest part of the pitch is that nothing is assumed to work. Generated code is confirmed by actually running it against the live app, so a green result means the test really passed against the build in front of you. Run one scenario first, read the result, then run the group.
This is what makes local generation worth the tunnel setup: you author and prove a test against the exact change you are working on, and you find the broken flow while it is still on your machine — not after it ships to staging. When the feature looks right locally, switch the run to your staging environment and the same test runs there unchanged.
Local testing is one workflow among several: the same project also runs on cloud sandboxes and private runners. To wire up your first tunnel, see the Tunnel devices and Choose an execution target guides, or get early access and try it against your own dev build.