Creating User Flow Tests
Multi-page tests that simulate real journeys. Mix UI and API steps; capture values across steps; use {{RANDOM}} for unique data.
User Flow Tests
User flow tests chain multiple pages and interactions into a single test that simulates a real user journey — sign up, log in, add to cart, check out. The opposite of a single-page test.
When to write one
Most AI-generated tests are single-page: "Cart page renders", "Login form submits". Useful, but they don't catch the bugs that matter most: the seams between pages.
User flow tests cover the seams. Examples:
- Signup → email verify → first project — the new-user activation flow.
- Login → dashboard → settings → save — verify settings persist across navigation.
- Browse → add to cart → checkout → confirmation — the e-commerce happy path.
- Search → filter → click result → detail page — the discovery flow.
One user flow that breaks tells you more than ten single-page tests that pass.
How AegisRunner generates them
The test generator's Multi-step E2E scenario family produces user flows automatically when the scanner observes consistent state transitions during the scan. If pages A → B → C show the same flow on every visit, it stitches them into a flow test.
You'll find these under each suite, marked with the e2e type tag and a multi-page badge.
Writing a flow manually
From the test suite:
- Click + Add Test on the suite.
- Choose User flow.
- Add steps in order. Each step has a target page and an action.
Step types
| Step | What it does |
|---|---|
| navigate | Go to a URL or path. |
| click | Click an element. Locator can use role + text or CSS. |
| fill | Fill an input with a value (literal or {{TOKEN}}). |
| select | Select an option from a dropdown. |
| press | Press a key (Enter, Tab, etc.) — needed for SPAs that submit on Enter. |
| wait | Wait for a condition (URL match, element visible, network idle). |
| assert | Verify something is or isn't true. Visibility, text, URL, count. |
| api-request | HTTP call mid-flow. See API Testing. |
| screenshot | Capture for visual regression. |
| a11y-check | Run axe-core at this point. |
An example flow
1. navigate /signup
2. fill input[name="email"] = {{email}}
3. fill input[name="password"] = {{password}}
4. click button:has-text("Sign Up")
5. wait url = /verify-email
6. api-request POST /api/test/verify-email-link
7. navigate /dashboard
8. assert h1:has-text("Welcome") visible
9. click a:has-text("Create Project")
10. fill input[name="name"] = First Project
11. fill input[name="baseUrl"] = https://example.com
12. click button:has-text("Create")
13. wait url matches /projects/.*
14. assert h1:has-text("First Project") visible
Variables in step values
Any {{name}} placeholder in a step's selector, value, or assertion is substituted at run time from your project's test data:
| Source | Where the value comes from |
|---|---|
| Test environment tokens | Project Config → Test Environment → Tokens. Use these for credentials, API keys, bypass tokens. |
| Form data set columns | If the test runs against a form data set, each row's column values are available by column name ({{email}}, {{name}}, etc.). |
| Built-in | {{pageUrl}} resolves to the URL associated with the test's page. Used by AI-generated navigate steps. |
Common placeholders we use today: {{email}}, {{password}}, {{username}}. Add your own as test environment tokens or as columns in a form data set.
Composite flows: combining multiple suites
If you have several smaller flows that together form a longer journey, use a composite suite to chain them. Each suite stays independent for re-use; the composite runs them as one logical sequence.
Auto-login fallback
If a flow step lands on /login unexpectedly (session expired, etc.), AegisRunner runs your project's login script and continues. Tag a flow with unauthenticated if you specifically want to test the unauthenticated state and disable auto-login.
Re-running and editing flows
Flow tests can be heavy — eight to twelve steps that take 30 seconds each. While iterating:
- Re-run a single test from the run page (don't re-run the whole suite).
- Edit a single step inline; don't regenerate the whole flow.
- Add an
a11y-checkafter every navigation if accessibility regressions are a concern.
Tips
- Use a form data set for inputs that should differ between runs (emails, slugs, names). One row per run, the same flow runs against each row's values.
- Wait for URL changes rather than fixed timeouts.
wait url = /dashboardis more robust thanwait 3 seconds. - Assert on different elements than you click. Don't click "Submit" and immediately assert "Submit" still exists — assert on the success message that appears after submit.
- Break long flows up. A 30-step flow is fragile. Split into 2–3 smaller flows + a composite suite.
Common questions
Why doesn't AI generate longer flows automatically?
The longer the flow, the more places it can break per run. The generator caps generated flows at ~10 steps. Chain multiple suites with a composite if you need longer.
Can a flow test span multiple subdomains?
Yes — navigate to any URL. Cookies and tokens scoped to the new domain need separate configuration if your app's auth crosses subdomains.
How do I test a payment flow without spending real money?
Use Stripe's test card 4242 4242 4242 4242 in a token. Most payment providers have test modes — point staging at theirs.