Skip to content

Multi-page flow

Long flows benefit from explicit checkpoints. Treat each page as its own verification.

tests/checkout.blop.ts
import { agentTest, describe } from "blop";
describe("checkout", () => {
agentTest("guest can complete a purchase", async ({ agent }) => {
await agent.goto("/products/widget");
await agent.goal(`
Step 1 — Add to cart:
- Click the "Add to cart" button.
- Verify the cart counter reads "1".
Step 2 — Open the cart:
- Click the cart icon.
- Verify the URL becomes /cart.
- Verify "Widget" appears in the line items.
Step 3 — Begin checkout:
- Click "Checkout".
- Verify the URL becomes /checkout.
Step 4 — Fill shipping:
- Email: "test@example.com"
- Name: "Test User"
- Address: "1 Main St"
- City: "Austin"
- Zip: "78701"
- Click "Continue to payment".
Step 5 — Pay with the test card 4242 4242 4242 4242,
any future expiry, CVC 123. Submit.
Step 6 — Verify success:
- URL becomes /checkout/thanks.
- Heading reads "Order confirmed".
Finish as passed only if every step's verification succeeds.
If any step fails, stop and finish as failed with a reason.
`);
});
});

The agent’s planner can carry context across steps as long as the goal lays them out clearly. The numbered structure also makes the eventual reason field on the test result easy to read post-mortem.

If different starting states matter — guest vs. signed-in checkout, US vs. EU shipping, different card types — model each as its own agentTest. They share describe("checkout", ...) so they’re grouped in reports and dashboards.

Multi-step flows can use up to ~15–20 agent steps. The default --max-steps budget usually provides enough headroom. If a test consistently runs out, split it.

If the agent gets stuck partway through:

  1. Run with --verbose to stream events live.
  2. Inspect .blop/screenshots/ — Blop captures images at decision points.
  3. Look for the last tool_result event in .blop/events.jsonl — that’s what the agent saw before it stopped making progress.

See Troubleshooting for the full debugging playbook.