Skip to content

Managing Profiles

Two concepts keep your agent focused: scenarios and profiles.

Scenarios describe what to test. Profiles describe where to test and how the verification agent gets in.

A profile bundles three things:

  • An endpoint — the URL where your app runs (e.g. http://localhost:3000, https://staging.example.com).
  • An auth strategy — how the verification agent gets logged in, if your app needs that.
  • Browser settings — headers, user agent, headless mode, and other knobs.

Profiles are shared with everyone in your organization by default. That means a teammate can run ranger go --profile alice@example.com and reuse the session you captured — useful for sharing test accounts and for keeping CI in sync with what works on a developer’s laptop. Name profiles by the account they represent.

Run ranger profile ls to see what’s set up. Run ranger profile use <name> to switch which profile ranger go uses by default. Create as many as you need — common patterns are one per environment, one per persona (free / paid / admin), or one per app you test.

Ranger uses a profile to log into your app and capture a browser session it can use on every subsequent Feature Review. Three login mechanisms exist; Ranger uses them in this priority order:

  1. Automated login — Ranger logs into your app for you, headless and deterministic, on every CI run, every background agent, every machine. Best for heavy usage and complex login flows involving SSO, OAuth, MFA, passkeys, custom auth, etc. If it’s configured for your app, this is the path that runs. Enterprise customers only.
  2. Login instructions — Ranger’s verification agent follows natural-language steps in a browser. Useful for flows an agent can complete on its own: hitting a debug-auth endpoint, setting a token in localStorage, navigating a custom form. Won’t work if a step needs a human or a second factor that Ranger can’t access.
  3. Headed login — a browser opens, you log in once, Ranger captures the session. The universal default — works for any web app a person can sign into.

Captured sessions are reused on every subsequent ranger go until they expire. When that happens, Ranger captures a fresh one using the same priority order.

Two cases skip the login question entirely:

  • No login — public sites, marketing pages, logged-out flows. Pass --skip-auth.
  • Electron / desktop apps — speaks Chrome DevTools Protocol. Pass --cdp-endpoint.

For sites without authentication, just point Ranger at the URL:

Terminal window
ranger profile add my-site --url http://localhost:3000 --skip-auth

--skip-auth skips the browser auth step. The profile is ready immediately.

You can also use this for testing logged-out flows of an app that does have auth (e.g. the public landing page) — just don’t log in.


The default for local development. Works with anything: username + password, SSO (Google, Okta, GitHub, WorkOS, etc.), OAuth, MFA at login. If a real user can log in, headed login captures the session.

Terminal window
ranger profile add alice@example.com --url http://localhost:3000

A browser opens. Log in once with the account you want the agent to use. Close the browser when you’re done — Ranger saves the session.

After that, every ranger go reuses the saved session until it expires. When it expires, run ranger profile add again to refresh.

Naming tip. Use a name that’s stable for the account you’re logging in as. An email works well; for accounts identified by username, phone, or anything else, use whatever’s stable. The name is just a label you’ll type when switching between profiles.

  • A real human has to be at a keyboard to complete the initial login. For CI and background agents, see automated login or login instructions.
  • Magic-link, SMS-MFA, and hardware-key flows work if you can complete them in your browser, but the captured session is only as long-lived as the cookies your app issues.

Enterprise customers only. Ranger logs into your app for you — no browser, no human in the loop — and captures a session that’s reused across every machine, CI run, and background agent. Set credentials as env vars and run ranger go:

Terminal window
RANGER_TEST_USERNAME=alice@example.com RANGER_TEST_PASSWORD=hunter2 \
ranger go --base-url http://localhost:3000 \
--notes "user logs in and sees the dashboard"

When the session expires, Ranger logs in again automatically.

Works for any login flow — SSO (Google, Okta, GitHub, WorkOS, etc.), OAuth, MFA, passkeys, magic links, custom forms, corporate auth. Bot protection, SSO routing, expiry rules, anything quirky about your app — we tune for it during onboarding.

Setup is a call with our team. Reach out and we’ll scope your case.

While automated login is being configured:

  • For local dev, headed login works for any web app you can log into in a browser.
  • For CI, login instructions is a fast bridge if your app has a debug-auth endpoint or short-lived tokens.

--base-url controls where the verification runs — the URL the agent navigates to and interacts with. It does not control where login happens. Login runs against a stable URL we configure with you; the captured session is then reused against whatever --base-url you pass.

This is by design: one profile, many environments. Your local dev instance, a Vercel preview, staging, prod — same session across all of them. If you find a case where a session doesn’t carry over between two of your domains, let us know and we’ll tune the profile so it does.

Automated login handles MFA for any factor we can hold for your test account. Anything that needs a human in the moment with a personal device — push notifications to your phone, SMS or email codes Ranger can’t reach, a passkey registered to a personal account — won’t work for automated login. Use headed login once on your own machine for those; Ranger reuses the captured session for every subsequent run, anywhere.

If your login page is behind a bot challenge that can be bypassed with a custom header (Cloudflare Turnstile, Datadome, etc.), set it on your profile and Ranger will send it during login:

Terminal window
ranger profile config set alice@example.com setupHeaders.x-skip-turnstile "<your-bypass-token>"

setupHeaders.<name> is sent only during login, not during verification runs, so it won’t leak into third-party requests during the actual test.


Natural-language steps an LLM-driven browser follows to log in. Useful when automated login isn’t set up but the login flow is something an agent can complete — hitting a debug-auth endpoint, setting a token in localStorage, navigating a custom multi-step form.

Create a profile without capturing login state, then describe the login flow in plain language:

Terminal window
ranger profile add preview --url https://staging.example.com --skip-auth
ranger profile config set preview loginInstructions \
"Navigate to ${BASE_URL}/api/debug-auth?email=test@example.com. \
Copy the token from the JSON response. \
Run in the browser console: localStorage.setItem('auth_token', '<the-token>'). \
Refresh the page."

${VAR_NAME} resolves environment variables at runtime, so credentials don’t have to live in the instruction text.

  • Each step must be something the agent can do in a browser. Anything requiring a human (push notifications, hardware key taps, codes from inboxes Ranger can’t read) won’t work.
  • For deterministic flows that you’d want to run the same way every time, automated login is more reliable — talk to us about getting it set up.

Once a profile exists, fine-tune browser behavior with ranger profile config:

Terminal window
ranger profile config set <profile> <key> <value>
KeyWhat it does
baseUrlOverride the profile’s URL for this directory (useful when one profile’s session works against multiple endpoints — local + staging, etc.)
headlesstrue/false. Run the browser without a visible window. Headed is useful when you’re watching verification firsthand.
headers.<name>Send a custom HTTP header with every request, e.g. headers.Authorization. Supports ${VAR} for env vars.
setupHeaders.<name>Like headers.<name>, but only sent during the ranger profile add browser session — useful for bypassing login protection (Cloudflare Turnstile, etc.) without affecting third-party requests during runs.
userAgentOverride the browser user agent. Useful for bypassing bot protection.
loginInstructionsPlain-language login steps. See Login instructions.
allowInsecureLocalhosttrue/false. Allow localhost content in deployed environments (micro frontends, single-spa). Relaxes browser security; use only in dev.
cdpEndpointChrome DevTools Protocol endpoint for Electron / desktop apps.
Terminal window
ranger profile config list <profile> # show what's set
ranger profile config unset <profile> <key> # remove one key
ranger profile config reset <profile> # clear all overrides

ranger go uses the active profile by default. Switch with:

Terminal window
ranger profile use <name>

Override per run with --profile <name> (or RANGER_PROFILE=<name>). The flag wins. If you pass --profile for a name that doesn’t exist, the run fails immediately rather than falling back silently.

The active profile is tracked per directory. Two checkouts of the same repo, in different directories, can each have their own active profile — useful when you’re running parallel agents against different environments.


You’ll want more than one profile when:

Local dev, staging, preview deploys — each with its own URL but possibly the same login.

Terminal window
ranger profile add alice@example.com --url http://localhost:3000 # initial setup
ranger profile config set alice@example.com baseUrl '${PREVIEW_URL}' # in CI: PREVIEW_URL is set per-deploy

${VAR} references resolve at runtime, so one profile can target many deploys.

Free, paid, and enterprise users; admin vs. member; tenant A vs. tenant B. Add a profile per account; tell your coding agent which one to use for each scenario.

Terminal window
ranger profile add free@example.com --url http://localhost:3000
ranger profile add admin@example.com --url http://localhost:3000

Then in your prompt: “Verify scenario 1 with --profile free@example.com and scenario 2 with --profile admin@example.com.”

Customer-facing app on localhost:3000, internal admin tool on localhost:3001. One profile per app; the coding agent uses the right one per scenario.


Ranger can test Electron apps and other desktop applications that expose a Chrome DevTools Protocol (CDP) endpoint. There’s no URL to navigate to and no browser auth — Ranger attaches to the running app over CDP and starts interacting with the UI directly.

1. Start your app with remote debugging enabled:

Terminal window
your-electron-app --remote-debugging-port=9222

Any port works. The app must be running before Ranger connects.

2. Add a profile pointing at the CDP endpoint:

Terminal window
ranger profile add my-electron-app --cdp-endpoint http://localhost:9222

--cdp-endpoint skips URL reachability checks and browser auth — there’s no URL or browser to set up.

3. Run verifications normally:

Terminal window
ranger go --scenario 1

The agent connects to your running app, takes a snapshot, and starts interacting.

Saved login sessions don’t work in CDP mode. With web profiles, Ranger replays saved cookies into a fresh browser on every run. With Electron, Ranger attaches to a process that’s already running, so there’s no place to inject auth.

If your Electron app needs a logged-in user, handle that at the app level — persist credentials, use env vars at launch, or skip login in development mode.


When a saved session expires, the next ranger go will fail to authenticate. Refresh the session with:

Terminal window
ranger profile update <name>

profile update picks the right path based on how the profile is set up:

  • Automated login configured: re-runs server-side login (no browser, no human in the loop).
  • Headed login: opens a browser so you can log in again, then captures the session back to the cloud profile.
  • Login instructions: nothing to refresh — the verification agent re-runs them on every ranger go.

You can also just re-run ranger go with RANGER_TEST_USERNAME / RANGER_TEST_PASSWORD set when automated login is configured — Ranger detects the stale session and logs in again automatically.

Terminal window
ranger profile delete <name>

This deletes the shared profile for everyone in your organization. You’ll be asked to type the name to confirm; pass --yes in scripted contexts.