Skip to main content
Some single sign-on (SSO) providers block automated browsers. When that prevents UI login, authenticate with a test account manually, save the browser state, and load it in tests. Use a live login module when the provider permits automation and the login flow is part of the behavior under test.

The pattern

Save the session once

Write a test whose only job is to hold a browser open while you log in manually, then save the state:
tests/setup/capture-sso.test.yaml
Run it headed (from the local editor, not headless CI), finish the SSO sign-in in the opened browser, and let the save step write sso-state.json. The file holds the cookies, localStorage, and IndexedDB state the session needs.
The state file is a live credential. Do not commit it to a public repo. Keep it out of git, deliver it to CI as a secret, and rotate it on the same schedule as the account’s sessions.

Load it in every test

tests/reports.test.yaml
authLoad restores the browser state and refreshes the active page. The app then sees the restored session; the initial page load may have occurred before the state was applied.

Keeping the session fresh

State files expire with the IdP session. Two options keep the session valid.

Continuous refresh

Add authSave to a test’s after: section so each run rolls the state forward:
Continuous refresh works when the app uses sliding session expiry, but only where the file persists. In CI the save lands in the runner’s checkout and disappears when the job ends; to keep refreshed state across jobs, write it back yourself (upload it as an artifact a later job restores, or push it to your secret store from a scheduled workflow).

Re-capture on failure

When the saved session expires, run the capture test locally, complete the manual sign-in, and replace the state supplied to CI. A headless scheduled job cannot complete this manual login. If the provider permits an automated test-account login, a cached auth module (autoAuth: true) can store and reuse the session within a configured TTL. It does not bypass provider restrictions. See cache authenticated sessions.

Automating the IdP

Sometimes there is no state shortcut: for example, testing the login flow itself. If you must drive the provider’s UI:
  • Use a dedicated test account with 2FA that accepts TOTP, not SMS or push. Generate codes in a javascript step with OTPAuth; see authenticator-app codes.
  • Check the provider’s automation and account policies. Use a dedicated test tenant where available.
  • Keep the login in one module so when it breaks, one file breaks.