Skip to content

Browser Storage

OrbitTest starts every test in a brand-new browser profile: no cookies, empty localStorage, empty sessionStorage. That guarantee is what makes tests repeatable, and it means any state your test needs must be created explicitly. The orbit.storage API is how.

await orbit.open("https://example.com");
await orbit.storage.setCookie({
name: "session",
value: "abc123",
httpOnly: true,
secure: true
});
// Shorthand for simple cookies
await orbit.storage.setCookie("theme", "dark");
const cookies = await orbit.storage.cookies();
expect(cookies.some(c => c.name === "session")).toBe(true);
await orbit.storage.deleteCookie("session");
await orbit.storage.clearCookies();

The cookie API. HttpOnly cookies work because OrbitTest goes through CDP, not page JavaScript.

await orbit.storage.setLocal("token", "local-token");
await orbit.storage.setSession("view", "compact");
expect(await orbit.storage.getLocal("token")).toBe("local-token");
expect(await orbit.storage.getSession("view")).toBe("compact");
await orbit.storage.removeLocal("token");
await orbit.storage.clearSession();

Values are strings, exactly as the browser stores them. If your app keeps JSON in storage, stringify and parse it yourself so the test mirrors what the app really does.

Logging in through the UI in every single test is slow and makes every test fail when login breaks. The better pattern: one test (or setup step) logs in for real and saves the session; everything else loads it.

// Log in once, save the state
await orbit.open("https://example.com/login");
await orbit.type("Email", "user@example.com");
await orbit.type("Password", "secret");
await orbit.click("Login");
await orbit.waitForText("Dashboard");
await orbit.storage.saveSession("auth/session.json");

saveSession captures cookies plus current-origin localStorage and sessionStorage.

// Any later test: restore and go
await orbit.open("https://example.com");
await orbit.storage.loadSession("auth/session.json");
await orbit.open("https://example.com/dashboard");
expect(await orbit.hasText("Dashboard")).toBe(true);

Skip the login UI without skipping authentication.

Keep tests that verify login itself, of course. The saved session is for the dozens of tests that need a logged-in user but are not about logging in.

A saved session eventually expires, and when it does, every dependent test fails with confusing “element not found” errors on a login page nobody expected. OrbitTest gives you a direct check instead:

await orbit.storage.loadSession("auth/admin-session.json");
await orbit.storage.expectHealthySession({
minMinutes: 15,
requireCookie: true
});
await orbit.open("https://example.com/admin");

Fails with a clear “session unhealthy” error instead of a misleading element failure.

For debugging, inspect() summarizes the current browser state with values redacted, safe to print in CI logs:

const state = await orbit.storage.inspect();
console.log(state.auth.present); // auth-like signals found?
console.log(state.auth.signalCount);
console.log(state.cookies.authLikeCount);
console.log(state.recommendations); // human-readable suggestions

inspect() reports counts, key names, JWT expiry, and recommendations, never raw tokens.

Why not just disable the clean profile and reuse one browser?

Section titled “Why not just disable the clean profile and reuse one browser?”

Shared state is the top cause of tests that pass alone and fail together. The clean profile costs a little speed and buys you determinism; saved sessions give the speed back where it matters.

Yes. OrbitTest operates over the Chrome DevTools Protocol, which can read and write HttpOnly cookies that page JavaScript cannot touch.

Regenerate it at the start of each run or pipeline. Guard every load with expectHealthySession({ minMinutes: 15 }) so an expiring session fails one clear check, not fifty confusing tests.

  • Lifecycle Hooks — beforeAll, beforeEach, afterEach, and afterAll: testInfo fields, global setup files, and using hooks without hiding test intent.
  • Test Basics — How to structure readable end-to-end tests: arrange-act-assert, the orbit object, per-test options, and strong assertions.
  • CI/CD Integration — CI mode, retries and flaky detection, fail-fast, sharding across jobs, and a complete GitHub Actions workflow.
  • Environment Variables — ORBITTEST_CHROME_PATH, sharding, CI flags, ADB and device selection, and how to keep secrets out of test files.