My page object needs a signed-in session before goto() — where does the login belong?
Asked 8,570 views2 answers
25votes
Every one of our scenarios opens with the same three steps: go to login, fill two fields, submit. Then the real scenario starts.
It is slow — about four seconds a scenario across roughly 200 scenarios — and it is the single biggest source of flakiness we have, because a failure in the login form fails everything. I have been tempted to put the login inside the page object's open() method, which feels wrong. What is the intended shape?
It is wrong, and you do not need it. Do not sign in through the UI at all except in the scenarios that are about signing in.
Tag the scenario with a role and the browser context starts with that user's cached storage state already applied, so the first line of the scenario is the thing you actually want to test:
gherkin
@ui @smoke @user:standard
Scenario: The checkout page shows the basket
Given I am on the checkout page
Then I should see the text "Your cart"
Capture the state once per user:
bash
sdods auth capture -p demo-shop -e staging --user standard
sdods auth list -p demo-shop -e staging
It writes projects/demo-shop/.auth/staging/standard-0.json, indexed by the pool position, and the strategy that produces it is declared in the project file:
Your page object then only does await this.goto('checkout'), which is all it should ever have done. Keep exactly one scenario that drives the login form itself, otherwise you lose coverage of the door.
storageState: true has to be set, otherwise the fixture returns nothing and the context starts anonymous with no error — the scenario just redirects to the login page and the failure looks like an application bug.
maxAgeMinutes matters more than it looks. Cached form and token state is recaptured once it is older than that, so a short session lifetime in the application under test wants a short value here rather than a nightly manual capture.
The api layer skips storage state entirely, which is why an API-only run does not need any of this.