Fixtureframedocs
Adapters

Signing in

How a run reaches an application that requires authentication, and why the credential never leaves your machine.

A flow describes what to do inside your application. It does not describe how to get in — that is an adapter's job, and it is kept separate on purpose.

Two reasons, and both matter more than the tidiness:

  • A credential is not content. A flow is versioned, reviewed and shared. A password typed as a step would be in that document, in every copy of it, for ever.
  • A login is one fact about an environment, not about a walkthrough. Staging signs in one way, a demo tenant another, and the same flow should replay against both.

So the runner opens the environment's address, hands the page to its adapter, and only then starts step one. Whatever the adapter did is not in the flow, and the secrets it read stay in the process that ran it.

What ships

AdapterUse it when
form-loginThe application has a sign-in form with a username and a password.
tokenYou can ask your own auth endpoint for a bearer token.
api-keyA long-lived key was issued once and is sent with every request.
Your ownAnything else — ff adapter init scaffolds one in the workspace.

token and api-key never touch a login screen. They are the better choice whenever they are available: nothing is typed, so nothing can be photographed by a capture, and there is no form to break when the sign-in page is redesigned.

Choosing one

Does the application have a username-and-password form?
├── yes → is there a second factor, or a code, or a push approval?
│         ├── no  → form-login
│         └── yes → a session or a token. Never automate a second factor.
└── no  → can you ask an endpoint for a token, or were you issued a key?
          ├── yes → token / api-key
          └── no  → a workspace adapter, or a saved session

The last leaf is the honest one for SSO, magic links and anything with a one-time code. See what cannot be automated.

Attaching one to an environment

An adapter is named on the environment, and its secrets are read from the process that runs the flow — so the same flow replays anywhere, and the credentials belong to the machine rather than to the definition:

ADAPTER_LOGIN_USERNAME=demo@example.com \
ADAPTER_LOGIN_PASSWORD=…               \
ff run --flow "Submit an expense" --environment staging

ff doctor lists the variables the enabled adapters declare, so a machine can be set up before anything is run rather than after a run fails on step one.

Recording is separate

Recording never uses your credentials silently. ff record signs in with the adapter when one is configured; when it cannot, it starts paused so that you can sign in yourself with nothing being captured. A script driving the browser does the same thing explicitly with pause() and resume().

That is not politeness. The recorder writes down what is typed, and a password typed while recording becomes a value in the flow file.

On this page