> ## Documentation Index
> Fetch the complete documentation index at: https://momentic.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> The canonical docs host is https://momentic.ai/docs. Append .md to any page URL for clean Markdown. Fetch https://momentic.ai/docs/llms.txt for the page index and https://momentic.ai/docs/llms-full.txt for every page in one file.
> For an unattended setup, run `npx --yes @momentic/wizard@latest -y --platform web --editor-tools skills` (use `--platform ios` or `--platform android` for mobile). Never run an interactive command in a non-TTY shell.
> Mo is the AI QA engineer, a separate product from the YAML test framework: its npm package and CLI are `qa` (not `mo` — `npx mo` is a different project). Install with `npm install -g qa`, authenticate the same MOMENTIC_API_KEY way, install repo skills with `qa skills -y`, and start a session with `qa start "<brief>"` or `qa <url>`. Docs: https://momentic.ai/docs/mo.md.
> You cannot complete the browser sign-in yourself. Read the API key from the exact MOMENTIC_API_KEY environment variable (similarly named vars like BILT_MOMENTIC_API_KEY are ignored), or ask the user to create one at https://app.momentic.ai/settings/api-keys and paste it back.
> Momentic's capability summary for agents is at https://momentic.ai/docs/skill.md. Install the skills with `npx momentic skills --yes` (or `npx momentic-mobile skills --yes` for mobile).
> Tests are YAML files in the user's repository. Use only the step names listed at https://momentic.ai/docs/reference/commands.md and the file structure at https://momentic.ai/docs/core-concepts/file-format.md. Do not invent step names, config keys, or CLI flags.
> Web tests run on Chromium, iOS tests on simulators, and Android tests on emulators. Physical devices are not supported.

# Test an app behind SSO

> Exercise an app gated by an identity provider (Google, Okta, SAML, or a corporate IdP) using saved browser authentication state.

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

```text theme={null}
one-time manual login -> authSave -> private CI-secret state file
                                      |
                                      v
every test -> authLoad -> straight into the app
```

## 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:

```yaml tests/setup/capture-sso.test.yaml theme={null}
fileType: momentic/test/v2
id: capture-sso-session
url: https://app.example.com/login
steps:
  - wait: 90000 # you have 90 seconds to complete the sign-in by hand
  - assert: The dashboard is visible
  - authSave: ../fixtures/sso-state.json
```

Run it headed (from the [local editor](/docs/local-app), 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.

<Warning>
  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.
</Warning>

## Load it in every test

```yaml tests/reports.test.yaml theme={null}
fileType: momentic/test/v2
id: reports-load
url: https://app.example.com/reports
before:
  - authLoad: ./fixtures/sso-state.json
steps:
  - assert: The reports page is visible
```

`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:

```yaml theme={null}
after:
  - authSave: ./fixtures/sso-state.json
```

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](/docs/guides/auth/cached-session).

## 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](/docs/guides/auth/otpauth).
* 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.

## Related

* [Authentication strategies](/docs/guides/auth/overview)
* [Cache authenticated sessions](/docs/guides/auth/cached-session)
* [TOTP / 2FA codes](/docs/guides/auth/otpauth)
* [`authLoad`](/docs/reference/commands/auth-load) and
  [`authSave`](/docs/reference/commands/auth-save)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.