These docs are in English. If you prefer German, write us at beta@clickprobe.ai.
Testing Your App on localhost
ClickProbe’s local proxy is what makes testing localhost possible at all: the AI’s browser
runs on your machine, not in our cloud, so it can reach anything your machine can reach —
including a dev server that was never meant to be public. This page covers what you need to
know to point a project at localhost (or any private URL) and get a clean exploration session.
How it reaches localhost
When you create a project, the Target URL (or Staging URL — see
Onboarding Guide) is just a string stored on your project. Nothing about it
is validated or reachable from our cloud. The exploration AI runs in our EU cloud, but the
browser it controls runs inside clickprobe-proxy on your machine. The proxy opens one
outbound WebSocket connection to wss://broker.clickprobe.ai/proxy/connect (port 443) — no
inbound port needs to be opened, and no tunnel or ngrok-style forwarding is required. If that
connection can’t be established, clickprobe-proxy status and the local dashboard now name which
layer failed — see Proxy Connection Troubleshooting — a hostname
that can’t be resolved is a condition on ClickProbe’s side, not a problem with your localhost
setup.
Each step the AI wants to take (navigate, click, type, screenshot) is sent down that connection as an instruction; the proxy executes it against a local headless Chromium and sends back the result. Your target URL itself — and everything that loads at it — is fetched directly by Chromium on your machine, over your own network. It is never fetched or proxied through ClickProbe’s cloud.
This is why http://localhost:3000 works exactly the same as a public staging URL: from the
proxy’s point of view, both are just “a URL Chromium can reach.”
Which dev-server ports work
Any port your dev server actually listens on and that’s reachable from the machine running the
proxy — 3000, 4200, 5173, 8000, 8080, 9000, whatever your framework defaults to.
One caveat inherited from Chromium itself, not from ClickProbe: Chrome refuses to navigate to a
small set of ports it considers “unsafe” (mail, IRC, X11, and similar legacy service ports —
6000 is the one developers occasionally hit, since it’s the classic X11 display port) and
fails with ERR_UNSAFE_PORT. None of the common dev-server defaults fall in that list, so this
almost never comes up in practice — but if you’ve picked an unusual port and see the AI report
an immediate navigation failure, try a conventional port instead.
Running the proxy on a different machine than your dev server? The target still just needs
to be reachable over the network from wherever the proxy runs — localhost only works when
they’re the same machine. If your dev server is on your laptop and the proxy runs elsewhere
(a VM, a teammate’s machine), use your laptop’s LAN IP instead of localhost in the Target URL.
Self-signed certificates
If your dev server serves HTTPS with a self-signed certificate, be aware: the proxy’s browser does not currently trust self-signed certs automatically. Chromium will show the standard “Your connection is not private” interstitial, and the exploring AI has no reliable way to click through it — a session against a self-signed HTTPS target will likely report the interstitial itself as the only “page” it found, not a bug in your app.
Two ways around it:
- Simplest: use plain HTTP for local development. Most dev servers (Vite, webpack-dev-server, Next.js, etc.) serve HTTP by default; if TLS isn’t specifically what you’re testing, this is the path of least resistance.
- If you need HTTPS locally, use a tool like mkcert to generate a certificate trusted by your machine’s system trust store (rather than self-signed) and point your dev server at that. Chromium — and therefore the proxy — trusts whatever your OS trusts.
Hot-reload / HMR while a session is running
Dev servers with hot-module-replacement (Vite HMR, webpack-dev-server, Next.js Fast Refresh) push code updates to the page over their own WebSocket while it’s open. If you edit and save code while an exploration session is actively running against that page:
- A full-page reload (as opposed to an in-place module swap) will interrupt whatever the AI was in the middle of doing — mid-form-fill, mid-navigation — and it may report the reload itself as unexpected behavior, since from its perspective the page it was interacting with just vanished.
- An in-place HMR swap that changes layout or removes an element the AI just interacted with can produce a false-positive “element disappeared” finding.
Neither is a bug in ClickProbe or in your app — it’s an artifact of testing a moving target. Recommendation: avoid editing and saving code in the app under test while a session is running. If you want to test against live-reloading code deliberately, treat any reload-adjacent finding with that context in mind before filing it as a real bug.
What actually leaves your network — the real guarantee, and its limits
Worth stating plainly and precisely, since it’s easy to worry about when pointing a SaaS tool at
localhost: every target URL is fetched by Chromium on your machine, driven by the proxy. The
cloud never opens its own connection to your target app and never receives its raw network
traffic — no request/response bytes, no headers, no cookies. That part holds regardless of
anything below, including for an internal-only target (VPN-gated, firewalled, air-gapped except
for the proxy machine itself): the proxy is the only thing that needs network access to it.
What does reach the cloud is everything the exploration produces: the structured page snapshots
the AI actually reasons from (accessibility-tree data, extracted page text, chrome.evaluate
results), screenshots captured alongside each action for your bug reports, and the structured
click/type/navigate actions it takes, relayed one step at a time over the proxy’s outbound
connection. Screenshots are persisted in our EU object storage so you can review a session’s
history later — they are not merely seen in-flight. If a page’s content matters to you, assume a
rendered copy of what the exploration touched can end up in the cloud; this is the feature
(fresh-eyes testing with a visual record), not a leak.
Two boundaries the proxy enforces on what the AI can point the browser at:
- Scheme lock (always on, cannot be disabled). Navigation and screenshots only work for
http:///https://targets.file://,data:, and every other scheme are refused before Chromium ever sees them — so a local file, a data URI, or a browser-internal page can never be the source of a screenshot or snapshot sent to the cloud. - Host scope (configurable via
nav_scope_modein your proxy’sconfig.yaml; defaultwarn). The proxy knows the session’s declared target URL, and applies this to every way the browser can move — a typed navigation, a click on a link, a form submit, a keyboard shortcut, a script-driven redirect, even atarget="_blank"popup — not only an explicitchrome.navigatecall. In the defaultwarnmode, navigation to a different host is still allowed (real apps legitimately redirect off-origin for OAuth/SSO, CDNs, and payment sandboxes — a hard block would break normal testing) but is logged and shown in your local dashboard, so an unexpected destination is visible, not silent. If you want a harder guarantee — refuse anything outside the target’s own domain (or same registrable domain, e.g.accounts.example.comwhen testingapp.example.com) — setnav_scope_mode: enforce. One known limitation, in every mode: a same-host URL that server-side-redirects to a different host is not somethingenforcecan catch (Chromium’s own redirect handling is not visible to the proxy’s interception layer at the moment the redirect fires) — the destination is still made visible via the same logging/dashboard signal, just not refused.enforceis therefore best suited to a single-origin app; an app whose sign-in flow depends on a third-party host should stay onwarn, the shipped default.
In short: your source code and any local files are never reachable at all (scheme lock); what your
app under test renders while the AI is looking at it can reach the cloud as a screenshot/snapshot
by design; and where the AI is allowed to look is visible to you and, if you choose enforce,
constrained to your app’s own origin.
Related
- Onboarding Guide — the full 7-step wizard, including proxy install and connect
- Proxy Connection Troubleshooting — corporate proxies, TLS interception, the Chromium download, and reading the local dashboard