Skip to content
Applied AI, product engineering, and notes from the workLearn more
Blop

Blop: Tests as Code and Agentic Browser QA

Blop drives real Playwright browsers to verify your running app. Tests live as .blop.ts files in your repo, and runs emit results.json, events.jsonl, JUnit XML, and screenshots. Here is how it works.

Hanan Choudhary Hadayat
#Blop#testsAsCode#browserQA#agentic#UnravelAI

Blop is our agent for verifying running software. It drives real Playwright browsers, walks the actual user flow, and reports what it found. This post explains how Blop treats tests as code and why intent-based browser QA earns its keep. The docs live at docs.blopai.com, and the product at blopai.com.

The problem Blop solves

Most QA breaks down into two questions that are easy to ask and hard to answer: “does the build still work?” and “does the running app still work for a user?” The first question is what your test suite answers. The second is what Blop answers.

End-to-end tests are supposed to answer the second question, but in practice they are brittle, slow, and expensive to maintain. They break on minor markup changes, they encode a script instead of an expectation, and when they fail they tell you a selector broke — not that the user can no longer complete the task. Blop takes a different shape: you describe what to verify as intent, and an agent drives a real browser to figure out how.

Tests as code

A Blop test is a TypeScript file — a .blop.ts file — that reads like intent. It exports agentTests under describe. agent.goto and agent.goal build a numbered goal list that the agent receives when the runner reaches the test. It is:

  • Version-controlled. The test lives in your repository, code-reviewed like any other code, yours to edit or delete.
  • Intent over selectors. Goals stay readable when the UI changes — no brittle data-testid chains or manual click sequences. The agent finds the element by what it should do, not by a hand-picked selector.
  • Asserts intent, not matches. “the receipt number is visible” is intent; expect(selector).toHaveCount(1) is a fragile match.
  • Runs the same way locally and in CI. One binary covers blop init, blop test, blop watch, blop list, and blop skills.

This is “tests as code” in the straightforward sense: the test is a program, it lives next to the feature, and the agent that edits the feature can also edit the test. When Khadim changes a flow, Blop can update the test that covers it in the same change.

Real Playwright browsers

Blop does not script a headless shell and call it QA. It drives real browsers through controlled native tools:

  • Chromium, Firefox, and WebKit are all supported, so the same intent runs across the engines your users actually use.
  • Controlled tools, not script execution. The agent drives the browser over Playwright with controlled tools — no shell escapes, no arbitrary script execution from the page.
  • A persistent harness. @blopai/browser-harness supports persistent CLI sessions and containers for local and CI use.

The point of using a real browser is that the test verifies what a user experiences, not a mocked approximation of it.

Agentic browser QA

A scripted end-to-end test is a recording that either passes or fails. Blop is agentic: it gets a goal, drives the browser toward that goal, and adapts when the page does not match a fixed script.

  • It reads the page it is given. When a button moves or a step is added, the agent finds it by intent, not by a stale selector.
  • It recovers from small changes. A renamed label or a new confirmation step does not stop the flow; the agent re-plans against what it sees.
  • It reports the failure, not the symptom. When a flow breaks, Blop reports which user-visible step failed and what it found instead — not a stack trace from an assertion library.

This is the practical case for an agent doing QA instead of a script doing QA: the agent’s tolerance for change is exactly what makes the test worth keeping as the product evolves.

CI-native reporters

Every run writes a fixed set of outputs to .blop/:

  • results.json — a versioned result contract, so other frameworks can emit the same schema once adapters ship.
  • events.jsonl — a structured event stream of the run.
  • JUnit XML — for CI systems that consume it.
  • Screenshots — so a human can see what the agent saw at failure.

The result payload is a versioned contract. Adapters that emit the same schema for other frameworks are planned, not shipped yet.

How Blop and Khadim work together

Blop and Khadim cover two halves of the same change. Khadim edits the code and verifies the build and unit tests. Blop starts the running app and verifies the user-visible behavior. A typical change goes:

  1. Khadim edits the code and runs deno task build.
  2. The app is started locally or in CI.
  3. Blop runs the relevant .blop.ts tests against the running app.
  4. If Blop finds a regression, Khadim reads the report and either fixes the code or updates the test as part of the same change.

The two agents share the same definition of done: the change is not done because the agent says so, it is done because the build is green and the user-visible flow holds.

Current status and what is early access

We are explicit about what is shipped and what is not:

  • CLI and .blop.ts runner, browser harness (Playwright), CI-native reporters — shipped. These are the workhorse today.
  • Control plane — early access. When you want hosted history, the same result schema uploads to the Blop platform: failures cluster across runs, tests become synthetic checks, and the agent can open fix PRs. This is early access, not generally available; auto-fix is early access, not shipped.
  • Adapters for other frameworks — planned. The result payload is a versioned contract; adapters that emit the same schema are planned, not shipped yet.

Blop is working software today: real browsers, tests as code, CI-native reporters. The hosted control plane is the part still in early access. See the Blop product page for the full status table.

For the editing side of a change, read the Khadim post. Contact us to talk about how Blop fits your QA setup.


We will keep updates factual and short. This post reflects Blop’s current behavior, not a roadmap.