The form-login adapter
Configuration for signing in to an application whose login is a form — including two-step forms and single-page applications.
form-login signs in to any application that asks for a username and a password. It knows nothing
about any particular product: where the fields are and what happens around them is configuration,
which is why the same code signs in to every customer's application.
Configuration
Every value is read from the environment of the process that runs the flow. Only the first two are required.
| Variable | Required | Default | What it is |
|---|---|---|---|
ADAPTER_LOGIN_USERNAME | yes | — | Username or email to sign in with. |
ADAPTER_LOGIN_PASSWORD | yes | — | Password for that account. |
ADAPTER_LOGIN_USERNAME_SELECTOR | no | #email | The username field. |
ADAPTER_LOGIN_PASSWORD_SELECTOR | no | #password | The password field. |
ADAPTER_LOGIN_SUBMIT_SELECTOR | no | button[type=submit] | The control that submits the form. |
ADAPTER_LOGIN_CONTINUE_SELECTOR | no | the submit control | On a two-step form, the button that accepts the address. |
ADAPTER_LOGIN_PRE_STEP | no | — | Accessible name of a button to click before the fields appear. |
ADAPTER_LOGIN_PATH_PATTERN | no | /(login|signin|sign-in|auth/login) | Regex matching the login path. |
The defaults suit a form with id="email" and id="password". Applications that label their
fields rather than id-ing them usually need:
ADAPTER_LOGIN_USERNAME_SELECTOR='input[type=email]'
ADAPTER_LOGIN_PASSWORD_SELECTOR='input[type=password]'The shapes it handles
One-step
Both fields on screen together. Fill, fill, submit.
Two-step
The address is taken first, checked by the application's own backend, and only then is a password
field drawn — how Google, Microsoft and Okta all sign people in. The adapter notices the password
field is missing, clicks the continue control, waits for the field to appear, and carries on. No
configuration unless the continue button is not the submit control, in which case set
ADAPTER_LOGIN_CONTINUE_SELECTOR.
Gated
Some forms show nothing until something else is chosen — a region picker, a "sign in with email"
toggle. Name that button with ADAPTER_LOGIN_PRE_STEP and it is clicked before the fields are
looked for. Waiting for a field that a gate has not revealed yet simply deadlocks, so the ordering
matters.
Single-page applications
An application that replaces its wall with its content, at the same address, is signed in to normally. This used to be impossible: the adapter decided both "is this a login?" and "did it work?" from the URL, and a page that never navigates answers neither. It now asks the form.
How it decides
"Am I on a login?" — whichever arrives first: the login route, or the username field. If neither is there, one more question decides between the two harmless-looking possibilities:
- Nothing that resembles a login on the page → nothing to sign into, so it returns. That is a restored session, and signing in again would be wrong.
- A login is plainly there but not the configured field → an error naming the selector, because a typo that reads as "already signed in" costs a whole run to diagnose.
"Did it work?" — the password field going away, or the path leaving the login route, whichever happens first. The password field specifically, never the username: a two-step form takes the username away at step one, which would report success before a password had been offered.
The route test only counts when the route was the login to begin with. Otherwise "the path is not /login" is true from the first instant and the adapter would report success before the
credentials had been sent.
Afterwards — if signing in did not navigate, the page is reloaded once. A single-page application typically loads what it is allowed to see at boot, and signing in gives it permission it does not go back and use; without the reload the first step of a flow meets a shell that fetched its data while nobody was signed in — no workspace chosen, empty lists, nothing to click. An application that navigated has already started afresh and pays nothing for this.
When it fails
| Message | What it means |
|---|---|
ADAPTER_LOGIN_USERNAME and ADAPTER_LOGIN_PASSWORD are required | Nothing was supplied. ff doctor lists what this workspace expects. |
A sign-in page is showing, but "…" is not on it | Wrong selector, or a gated form that needs ADAPTER_LOGIN_PRE_STEP. |
…never appeared after continuing | A two-step form whose continue button or password field is not where it was looked for. |
Signing in was refused: … | The application said so itself — the text is read from its alert. |
Signing in did not complete | The password field is still there and nothing navigated. Often a second factor: see limits. |
A run that fails during sign-in fails as a run, not as step one — nothing was attempted yet, and blaming the flow for the environment sends the reader to the wrong file.