# Reuse flows & seed data

> For the complete documentation index, see [llms.txt](/llms.txt)

Keep scenarios short and reliable by extracting repetition into
[helpers](/concepts/helpers/).

## Extract a flow

Move a repeated journey into a `flow_*` helper:

```js
// _helpers/flows.js
function flow_signin(email, password) {
  goto("/login");
  fill(getByLabel("Email"), email);
  fill(getByLabel("Password"), password);
  click(getByRole("button", { name: "Sign in" }));
}
```

Call it from a scenario:

```js
function test_orders() {
  step("Sign in", () => {
    flow_signin(TEST_USER_EMAIL, TEST_PASSWORD);
  });
  step("Orders page loads", () => {
    assertVisible(getByRole("heading", { name: "Your orders" }));
  });
}
```

## Seed data with mocks

Put the backend into a known state before the test, and clean up after:

```js
// _helpers/mocks.js
function seed_order(userId) {
  dbExec("INSERT INTO orders (uid, status) VALUES ($1, 'paid')", userId);
}
```

`dbQuery` / `dbExec` use the `database` URL from config; `apiCall` uses
`apiBaseUrl`; `shell` runs a binary. These are pinned in
[config](/reference/config/) — scenarios can't point them elsewhere.

:::tip[Cache login instead of repeating it]
For auth specifically, prefer a cached session over running `flow_signin` in
every test — see [Auth & cached login](/guides/auth/).
:::
