Skip to content

Start a test signed in

Most of what is worth testing sits behind a login. A test can log in every time, but a password in a step is a secret in a report, a magic link cannot be typed, and a login that changes breaks every test at once. A session lets a test start already signed in: cookies your app already accepts, set in the browser before the first step.

There are two ways to provide one.

A stored session belongs to an environment — the place its tests are aimed — and an owner or admin stores it once. In Marriska:

  1. Open Tests and choose the project in the project selector at the top of the explorer.
  2. Project settings → Signed-in session → Set session — the gear beside the selector opens Project settings, a set of sections that each save themselves; Signed-in session is the one above the danger zone.

The section names the environment it acts on. A project with one environment shows its name; with several, pick one in Environment — the section then reads and writes that environment’s session, and only that one.

The app’s host must already be saved in that environment’s allowed navigate hosts — a session is only ever sent to hosts the environment names. If it is not, the section shows Add the site’s host to Allowed navigate hosts first and Set session is disabled. The Environment section of the same dialog holds the default environment’s Allowed navigate hosts: add the host there and press that section’s own Save — the session section follows at once.

Sign in to your app in a private window, so the session you copy is one you will not sign out of by accident. Then open the browser’s developer tools on that tab:

  • Chrome and Edge — Application tab → Storage → Cookies → your app’s address. Leave Show URL-decoded unticked: the value must be copied exactly as stored.
  • Firefox — Storage tab → Cookies → your app’s address.
  • Safari — the developer tools are off by default. Turn them on in Safari → Settings → Advanced (Show features for web developers; older versions: Show Develop menu in menu bar), then Develop → Show Web Inspector → Storage tab → Cookies.

Each shows a table, one row per cookie. Your session is usually one or two of them, named something like session, sid, connect.sid, _yourapp_session or __Secure-authjs.session-token. If you cannot tell, note which cookies exist before you sign in; the ones that appear after are the session.

Fill one row in Marriska per cookie:

In MarriskaFrom the table
Cookie nameName, exactly
Cookie domainthe host your tests sign in to — the one in the environment’s Allowed navigate hosts — without a leading dot
Cookie valueValue, all of it; it is usually long
Secure, HttpOnlyticked where the table shows a tick
SameSiteSameSite; Lax if it is empty

Then Save session. Marriska encrypts the cookies at rest and never shows a value again: the section lists names, domains and flags, and when the session was set.

These prefixes, in any letter case, are promises to the browser: __Secure- requires Secure, and __Host- requires Secure and the path / (the section always uses /). Marriska refuses to save a cookie that breaks its promise and says which rule — because browsers disagree about such a cookie: Chromium refuses it, WebKit drops it without a word, Firefox keeps it. Let through, the same test would pass in Firefox and fail in the other two. A session saved before this check that breaks the rule is not injected; the run fails before its first step with Session not injected and the rule, and asks you to set the session again.

Every run aimed at the environment starts with its cookies — whether a person clicks Run, a schedule fires, or a coding agent queues the run — if a person created the test. What decides is who created the test, not who starts the run:

  • Tests created in the app always get the session.
  • Tests created through an API key — what a coding agent files — get it only when Allow agent-created tests to use the session is ticked, in the same section, for that environment. The box saves on its own and says Saved — there is nothing else to press. Whether an agent’s tests may run as a signed-in user is a decision a person makes, once. A person clicking Run on such a test does not change that, and neither does a person editing it.

The allowlist rule holds throughout: a cookie for a host the environment’s allowed navigate hosts do not cover is refused, and that list cannot later drop the host or be emptied while the session exists.

A stored session works for exactly as long as your app accepts it:

  • Signing out of that session in your app usually ends it on the server, and the stored copy stops working with it. That is why the copy above comes from a private window you close without signing out.
  • It expires when your app decides — the Expires column shows when the browser would discard it, and the server may end it sooner. Changing the password, or signing out everywhere, ends it on most apps.

You notice in the report. When the first page a test opens on the session’s host answers 401 or 403, or redirects to a sign-in page, the step fails with auth expired — refresh the session cookie (below). A redirect is recognised as a sign-in page by its path — /login, /signin, /sign-in, /auth and the like. If your sign-in page lives somewhere else, the test fails at the first step that needs the signed-in page instead, without that label.

To renew, copy a fresh cookie the same way, then in the same section Add cookie, fill it in, and Replace session. Replacing swaps the whole stored session for the rows you entered, so add every cookie the session needs, not only the one that changed. Clear session removes it.

When a session is short-lived — minted per run by a script, expiring within the hour — storing it makes no sense. Pass it with the run instead:

POST /api/v1/cli/cloud-runs
{
"test_ids": ["…"],
"session_cookies": [
{"name": "session", "value": "<token>", "domain": "app.example.com", "secure": true}
]
}

A coding agent does the same through the run_test tool. The cookies are set for that run only, replace the project’s stored session for it, are masked in every result, and are never stored: they wait for the worker that executes the run in encrypted, time-limited memory and are deleted the moment it takes them. The same allowlist rule applies — the run is refused (422) unless every test’s project covers the cookie’s domain.

A run that started from a session wears a Session: stored or Session: per run badge, and each test in it says which it used.

If the session no longer works — the first page the test opens on the session’s host answers 401 or 403, or bounces to a sign-in page — the step fails with:

auth expired — refresh the session cookie: the first page on the session's
host (https://app.example.com/account) answered 401 although the session
was injected.

That verdict rests on the page’s own answer, never on a missing element; a later page that logs out, or a public page, does not trigger it.

Where the session goes, and where it does not

Section titled “Where the session goes, and where it does not”
  • Cookie values count as secrets: they are masked in step results, logs and screenshots like a sensitive variable.
  • A stored session never leaves Marriska’s servers. A local agent run does not receive it. To start a local run signed in, hand the runner a session of its own: marriska-runner run --test-set "Smoke" --session-cookies ./session.json (a JSON array of cookies, same shape as above). It obeys the same rules — only where the environment’s allowlist covers the domain, masked, the run marked Session: per run — and the file’s contents never reach Marriska.
  • Clearing the session in project settings stops injecting it at once; ending it on your app’s side has the same effect, and the report says “auth expired” when the first page shows it (see How long it lasts).