Flows

A flow is a single user journey through your app — for example “Log in with valid credentials” or “Add an item to the cart”. Flows are what Qassandra actually runs.

Anatomy of a flow

Every flow has the following parts:

  • Name — a short, descriptive title (e.g. “Reset password via email link”).
  • Category — a hierarchical path used to organise flows in the UI (e.g. ["Authentication", "Login"]). Both manual edits and AI discovery contribute categories.
  • Instructions — a plain-English explanation of what the flow does and what success looks like.
  • Steps — the executable actions, in order. Each step has a CSS selector (for fast Playwright execution) and a human description (used by AI recovery if the selector breaks).
  • Assertions — verification checks the AI evaluates after the steps run (e.g. “the dashboard greeting shows the user's first name”).

How flows are created

You don't write flows by hand — they come from three sources:

  1. Bootstrap discovery — the first check on a new app explores the app breadth-first and creates a starter set of flows automatically.
  2. Suggestion-based discovery — every check can discover new flows during its crawl. They show up as suggestions you approve or reject.
  3. Manual creation — for niche journeys discovery doesn't reach, you can write a flow from a description in the Flows tab.

Two-phase execution

Flows are intentionally cheap to run. Each step uses a CSS selector and is executed directly with Playwright — no AI involvement, no LLM calls, sub-second per step.

If a step fails (element not found, click intercepted, navigation timeout), Qassandra invokes an AI recovery agent. The agent looks at the live page and decides one of three things:

  • Update — the element moved or got a new selector. The agent finds the new selector, the step is updated for future runs, and execution continues.
  • Retry — the failure looks transient (e.g. the element is still loading). Qassandra waits and tries again.
  • Fail — the flow is genuinely broken. The check records a failure and stops the flow.

This “fast first, AI on failure” model is typically 10–50× faster than AI-in-the-loop execution while keeping the resilience of an autonomous agent.

Flow events

Qassandra keeps an append-only history of important changes to a flow in the flow_events log. You'll see entries for:

  • Discovery (which check found the flow)
  • Manual creation and edits
  • Reorganisation (renames, recategorisation)
  • Archive, restore, delete
  • Suggestion approvals and rejections

This history is visible on the flow detail page and is useful when you're trying to understand why a flow changed.

Archiving vs deleting

Use archive when you want to stop running a flow but keep its history and baseline screenshots. Archived flows can be restored. Use delete when the flow is genuinely obsolete — this also removes its events and screenshots.

Flows are reusable

A single flow can be referenced by many checks. The flow itself isn't pinned to any one run — checks just record their own results, screenshots, and assertion outcomes against it.