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.
What a profile is
Section titled “What a profile is”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.
How Ranger logs into your app
Section titled “How Ranger logs into your app”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:
- 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.
- 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.
- 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.
No login
Section titled “No login”For sites without authentication, just point Ranger at the URL:
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.
Headed login
Section titled “Headed login”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.
ranger profile add alice@example.com --url http://localhost:3000A 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.
Limits of headed login
Section titled “Limits of headed login”- 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.
Automated login
Section titled “Automated login”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:
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.
Does this fit my app?
Section titled “Does this fit my app?”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.
What --base-url does and doesn’t change
Section titled “What --base-url does and doesn’t change”--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.
Multi-factor authentication
Section titled “Multi-factor authentication”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.
Bypassing bot protection during login
Section titled “Bypassing bot protection during login”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:
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.
Login instructions
Section titled “Login instructions”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:
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.
Limits of login instructions
Section titled “Limits of login instructions”- 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.
Browser settings
Section titled “Browser settings”Once a profile exists, fine-tune browser behavior with ranger profile config:
ranger profile config set <profile> <key> <value>| Key | What it does |
|---|---|
baseUrl | Override the profile’s URL for this directory (useful when one profile’s session works against multiple endpoints — local + staging, etc.) |
headless | true/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. |
userAgent | Override the browser user agent. Useful for bypassing bot protection. |
loginInstructions | Plain-language login steps. See Login instructions. |
allowInsecureLocalhost | true/false. Allow localhost content in deployed environments (micro frontends, single-spa). Relaxes browser security; use only in dev. |
cdpEndpoint | Chrome DevTools Protocol endpoint for Electron / desktop apps. |
ranger profile config list <profile> # show what's setranger profile config unset <profile> <key> # remove one keyranger profile config reset <profile> # clear all overridesPicking which profile a run uses
Section titled “Picking which profile a run uses”ranger go uses the active profile by default. Switch with:
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.
Multiple profiles
Section titled “Multiple profiles”You’ll want more than one profile when:
Different environments for the same app
Section titled “Different environments for the same app”Local dev, staging, preview deploys — each with its own URL but possibly the same login.
ranger profile add alice@example.com --url http://localhost:3000 # initial setupranger 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.
Different accounts on the same app
Section titled “Different accounts on the same app”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.
ranger profile add free@example.com --url http://localhost:3000ranger profile add admin@example.com --url http://localhost:3000Then in your prompt: “Verify scenario 1 with --profile free@example.com and scenario 2 with --profile admin@example.com.”
Multiple apps that talk to each other
Section titled “Multiple apps that talk to each other”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.
Electron and desktop apps
Section titled “Electron and desktop apps”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:
your-electron-app --remote-debugging-port=9222Any port works. The app must be running before Ranger connects.
2. Add a profile pointing at the CDP endpoint:
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:
ranger go --scenario 1The agent connects to your running app, takes a snapshot, and starts interacting.
Limits of CDP profiles
Section titled “Limits of CDP profiles”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.
Refreshing authentication
Section titled “Refreshing authentication”When a saved session expires, the next ranger go will fail to authenticate. Refresh the session with:
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.
Deleting a profile
Section titled “Deleting a profile”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.