---
sidebar_position: 2
title: Browser test recipe (zibby test)
---

# `zibby test` — browser test recipe

The browser-test recipe takes a plain-English spec, drives a real browser via a coding agent (Cursor / Claude / Codex / Gemini), runs the assertions, and produces a Playwright script + verification video.

It's a worked example of what the Zibby platform does — every step is a regular agent node with Zod-validated handoff. You can read the source, fork it, or build your own variation.

## Quick start

```bash
# Inline spec
zibby test "Go to https://example.com and verify the title is 'Example Domain'"

# Spec file
zibby test test-specs/login.txt

# With a specific agent
zibby test test-specs/checkout.txt --agent claude
```

## What it produces

```
.zibby/output/sessions/<session-id>/
├── execute_live/
│   ├── result.json          ← Zod-validated assertions + agent reasoning
│   └── browser-trace/       ← Playwright trace files
├── generate_script/
│   ├── result.json          ← parsed script + metadata
│   └── generated.spec.js    ← reusable Playwright test
└── video/
    └── recording.webm       ← visual verification
```

Open the session in [Zibby Studio](https://zibby.app/studio) to scrub through the run, swap the prompt, re-execute any node.

## The graph (this is just a Zibby agent)

Under the hood, `zibby test` is a 3-node graph:

```
   ┌──────────────┐    ┌──────────────────┐    ┌─────────────────┐
   │  preflight   │ →  │   execute_live   │ →  │ generate_script │
   │              │    │                  │    │                 │
   │ extract      │    │ agent drives     │    │ produce         │
   │ assertions   │    │ browser via MCP, │    │ Playwright      │
   │ from spec    │    │ records video    │    │ test file       │
   └──────────────┘    └──────────────────┘    └─────────────────┘
        │                     │                       │
     Zod out               Zod out                 Zod out
   (Assertions)         (BrowserResult)         (PlaywrightScript)
```

Each node is a real `WorkflowGraph` node. The agent in `execute_live` does its own tool loop (browser navigation, click, assertion checking) — Zibby just defines the contract.

## Customizing

**Use a different agent per run:**
```bash
zibby test test-specs/checkout.txt --agent claude    # Claude Code
zibby test test-specs/checkout.txt --agent cursor    # Cursor (default)
zibby test test-specs/checkout.txt --agent codex     # OpenAI Codex
```

**Run only one node** (e.g. just regenerate the script from an existing run):
```bash
zibby test --session 1768974629717 --node generate_script
```

**Headless vs headed:**
```bash
zibby test test-specs/login.txt              # headed (default — see the browser)
zibby test test-specs/login.txt --headless   # headless mode (for CI)
```

**Cloud-stored test cases (run a saved execution):**
```bash
zibby test --sources <id1>,<id2> --execution <executionId>
```

## Test memory

The recipe ships with a learning loop: every run reads from and writes to a local Dolt DB at `.zibby/memory/.dolt/` (cross-spec, **per-domain**). Selectors that worked, page-element fingerprints, navigation transitions, and free-form insights are all persisted — the agent's 100th run on a site is sharper and cheaper than its first.

When `zibby test` runs and the DB exists, the agent gets 5 MCP tools auto-exposed:

- `memory_get_test_history` — recent runs (pass/fail/timing)
- `memory_get_selectors` — known selectors with stability metrics
- `memory_get_page_model` — page elements / roles / accessible names
- `memory_get_navigation` — known page-to-page transitions
- `memory_save_insight` — save observations (categories: `selector_tip | timing | navigation | workaround | flaky | general`). **Required at least once per run.**

```bash
zibby memory stats        # what's in the DB
zibby memory cost         # real LLM token spend per spec / per domain
zibby memory compact      # prune old runs + GC
```

**Team sync.** Point the DB at a remote and teammates' learnings flow back to you on the next test run:

```bash
zibby memory remote add aws://my-bucket/team/proj/main   # BYO (S3 / GCS / DoltHub / file:///)
zibby memory remote use --hosted                         # OR Zibby-managed S3 (signed-in only)
```

Or commit `memorySync.remote: 'hosted'` (or an `aws://` URL) into `.zibby.config.mjs` and `zibby init` auto-wires it for every teammate.

Auto-pull on test start, auto-push on test pass. Failing runs don't pollute team memory.

→ Full guide: [Test memory](../tests/memory). Schema and SDK: [`@zibby/ui-memory`](../packages/ui-memory).

## Forking the recipe

If the built-in recipe doesn't fit your case, scaffold a custom agent and copy the structure:

```bash
zibby agent new my-test-agent
```

Then in `graph.mjs`, define your own nodes:

```js
import { WorkflowGraph, z } from '@zibby/agent-workflow';

const AssertionsSchema = z.object({
  assertions: z.array(z.string()),
  baseUrl: z.string().url(),
});

const BrowserResultSchema = z.object({
  passed: z.boolean(),
  details: z.array(z.object({ assertion: z.string(), passed: z.boolean() })),
  videoPath: z.string().optional(),
});

const graph = new WorkflowGraph();

graph.addNode('preflight', {
  agent: 'claude',
  prompt: ({ spec }) => `Extract assertions and base URL from: ${spec}`,
  outputSchema: AssertionsSchema,
});

graph.addNode('execute_live', {
  agent: 'cursor',
  skills: ['browser'],
  prompt: ({ preflight }) => `Navigate to ${preflight.baseUrl} and verify: ${preflight.assertions.join('; ')}`,
  outputSchema: BrowserResultSchema,
});

graph.addEdge('preflight', 'execute_live');
graph.setEntryPoint('preflight');

export default graph;
```

That's the platform. The recipe is just a starter.

## CI/CD

```yaml
- name: Run Zibby test
  env:
    ZIBBY_USER_TOKEN: ${{ secrets.ZIBBY_USER_TOKEN }}
  run: |
    npx @zibby/cli test test-specs/checkout.txt --headless
```

For agents triggered remotely (rather than per-CI-run), use [`agent trigger`](../cloud/triggering) on a deployed graph.

## Why this is different from Playwright codegen / a basic LLM script

| | Playwright codegen | LLM-only script | Zibby test recipe |
|---|---|---|---|
| Plain-English input | ❌ | ✅ | ✅ |
| Real browser execution | ✅ | ❌ (just generates code) | ✅ |
| Coding-agent driven | ❌ | partial | ✅ Cursor / Claude / Codex |
| Multi-step verification | ❌ | ❌ | ✅ Zod-validated nodes |
| Replayable + debuggable | ❌ | ❌ | ✅ Studio |
| Vendor-neutral | N/A | locked to one LLM | swap agent per run |

## See also

- [Recipes overview](./)
- [Concepts: graph](../concepts/graph) — the primitives this recipe uses
- [Cloud triggering](../cloud/triggering) — fire agents from CI/CD
