The QA automation tool test nobody runs: what do you keep when you cancel?

Every tool on the SERP ranks feature checklists. Self-healing selectors, AI test generation, CI hooks, cross-browser. None of them answer the one question that actually protects you long-term: on the day you stop paying, what files are on your disk? This guide answers that question for Assrt with three specific paths you can cat right now.

M
Matthew Diakonov
9 min read
4.9from Open-source, MIT, npm install away
Plan lives in scenario.md
Metadata in scenario.json
Results in results/latest.json

The question the SERP refuses to ask

I read the top five results for "qa automation tool" before writing this. Tricentis, Ranorex, Testim, Opkey, and a Medium listicle. Between them they covered self-healing, codeless recording, AI test generation, CI/CD integration, reporting dashboards, and cross-browser support. Not one of them asked the exit question. If you adopt this and it does not work out, what do you walk away with? The answer for most of those tools is nothing, or a zip file of JSON that only their renderer understands.

The exit question is not an edge case. It is the first thing every careful engineering lead should ask before approving a QA automation tool budget, because a test suite is the kind of asset that accumulates slowly and then matters enormously. Six months of regression cases is a year of engineer-time saved per quarter. If the definitions of those cases live in a vendor dashboard, you are renting your own work back from the vendor.

/tmp/assrt/scenario.md/tmp/assrt/scenario.json/tmp/assrt/results/latest.json/tmp/assrt/<runId>/video.webm/tmp/assrt/<runId>/screenshots//tmp/assrt/<runId>/events.json

The anchor fact: three paths

Every assrt_test run writes to three canonical locations on your local disk. The rule is defined in plain English inside the MCP server's instructions string at assrt-mcp/src/mcp/server.ts lines 294-298. You can read the source on GitHub, or you can run one test and verify all three paths exist with a single cat.

Anchor fact

After any test, run cat /tmp/assrt/scenario.md, cat /tmp/assrt/scenario.json, and cat /tmp/assrt/results/latest.json. If all three return content, the whole ownership claim is true.

Verify the three files exist

File one: scenario.md is the plan

This is the file your test suite is. It is markdown with a tiny YAML front-matter block and one or more #Case sections. Each step inside a #Case is a sentence a human would say to a careful junior tester: navigate, type, click, assert. The agent reads this file, calls the matching Playwright MCP tool for each step, and writes the result. If you edit this file before a re-run, the next run uses your edits and auto-syncs the new plan to cloud storage.

---
name: Signup flow
url: https://staging.example.com
scenarioId: 7b4e1f2a-91c3-4d6e-a8f0-2c5d9e3a6b10
---

#Case 1: A new user can sign up and reach the dashboard
1. Navigate to /signup
2. Call create_temp_email to obtain a disposable address
3. Type that address into the Email field
4. Type "correct-horse-staple" into the Password field
5. Click the Create account button
6. Wait for the "Check your email" banner
7. Call wait_for_verification_code to fetch the 6-digit code
8. Type the code into the Verification code field
9. Click Verify
10. Assert the heading "Welcome" is visible on /dashboard

Rename a step with sed. Diff two versions with git. Share one with a teammate over Slack. These are all first-class operations on a text file, and all of them are inaccessible when your plan lives in a vendor dashboard.

File two: scenario.json is the metadata

A small sibling file that records the scenario's UUID, its display name, and the URL it targets. The UUID is how you replay a scenario by ID instead of by plan text. Pass it back to assrt_test as the scenarioId argument and you re-run the exact same thing. This matters for CI: you author the plan once, commit the ID, and your pipeline replays it on every push.

The UUID lifecycle

1

First run

plan text in, UUID out

2

Commit

UUID lands in your repo

3

CI replay

scenarioId in, same run out

4

Same artifacts

all three files, same shape

File three: results/latest.json is the audit log

The third file is where proof lives. Every step the agent took, the tool name it called, the arguments, the result, pass/fail, milliseconds, and paths to the screenshot and video frame at that moment. It is large enough to be useful and small enough to commit as a CI artifact. Below is a trimmed real shape.

{
  "scenarioId": "7b4e1f2a-91c3-4d6e-a8f0-2c5d9e3a6b10",
  "ranAt": "2026-04-19T18:42:11.004Z",
  "passed": true,
  "durationMs": 11832,
  "steps": [
    { "tool": "navigate", "args": { "url": "/signup" }, "passed": true, "ms": 412 },
    { "tool": "snapshot", "passed": true, "ms": 188 },
    { "tool": "type_text", "args": { "ref": "e7", "text": "aQ9mZ2cP7r@1secmail.net" }, "passed": true, "ms": 204 },
    { "tool": "click", "args": { "ref": "e12", "description": "Create account" }, "passed": true, "ms": 176 },
    { "tool": "wait_for_stable", "passed": true, "ms": 2113 },
    { "tool": "wait_for_verification_code", "args": { "timeoutMs": 60000 }, "result": { "code": "482197" }, "passed": true, "ms": 5284 },
    { "tool": "assert", "args": { "description": "Dashboard Welcome heading visible" }, "passed": true, "ms": 92 }
  ],
  "artifacts": {
    "video": "/tmp/assrt/7b4e1f2a.../video.webm",
    "screenshots": "/tmp/assrt/7b4e1f2a.../screenshots/",
    "events": "/tmp/assrt/7b4e1f2a.../events.json"
  }
}

grep, jq, and a tiny node script are all you need to build a dashboard from these files. You do not need an API, a webhook, or a session token. A failed build is a failed JSON file, and a failed JSON file is git-blame-able.

How the three files get written

The sequence is straightforward. The MCP client calls assrt_test. assrt-mcp boots an agent that drives @playwright/mcp, which drives a real Chromium. Between steps, the agent writes the evolving plan back to scenario.md so an outside observer can read progress mid-run. When the agent calls complete_scenario, the final results land in results/latest.json.

What happens when assrt_test runs

Youassrt-mcpAgentPlaywright MCP/tmp/assrtcall assrt_test(url, plan)write scenario.md + scenario.jsonspawn agent with plansnapshot / click / typea11y tree with [ref=eN]append step to resultscomplete_scenario(passed)flush results/latest.jsonreturn structured JSON

The sequence is simple because the architecture is simple. assrt-mcp is a thin Typescript layer that owns the file I/O; Playwright MCP is the browser driver. Both are open-source. Neither is yours to get locked into.

The three MCP tools you can call from any agent

Because Assrt ships as an MCP server, any agent that speaks MCP (Claude Code, Cursor, Windsurf, a custom loop) can drive it. The surface area is three tools. That is the entire public contract for automating the suite.

MCP tool surface (assrt-mcp/src/mcp/server.ts)

  • assrt_test — run a plan or a saved scenarioId, return structured pass/fail
  • assrt_plan — visit a URL, snapshot it, auto-write #Case blocks for what it sees
  • assrt_diagnose — post-mortem a failed scenario and return a corrected plan
  • assrt_analyze_video — optional, needs GEMINI_API_KEY, parses the run video

The numbers that describe a single run

Concrete defaults, all readable in the source. The viewport is 1600x900 (browser.ts line 296). The navigation timeout is 0s (NAV_TIMEOUT_MS). The stability poll default is 0s. The MCP tool count that makes up the agent's universe is 0 (agent.ts lines 16-196). The files your suite reduces to is 0.

line 282

After implementing a feature or bug fix that touches UI, routes, forms, or user flows: run assrt_test against the local dev server to verify the change works end-to-end.

assrt-mcp/src/mcp/server.ts line 282 (agent instructions)

Ownership vs. the rest of the category

This is not a feature comparison. Feature comparisons are solved; everyone has "AI test generation" now. This is a portability comparison, and it looks different. A single row matters: where does the plan live?

FeatureTypical closed QA SaaSAssrt
Where the test plan is storedVendor dashboardscenario.md on your disk
How you edit a stepClick-through UIAny text editor
How you version control testsExport / reimport dancegit add scenario.md
How you read run resultsLog into dashboardcat results/latest.json
What survives cancellationA zip file, maybeThree plain files on disk
Source you can auditNoneassrt-mcp on GitHub, Apache-2.0
Runner to execute tests locallyCloud-onlynpx assrt-mcp, zero cloud
Published pricingContact salesFree open-source core, hosted optional
I stopped writing Playwright selectors for the signup flow. The plan is now a paragraph of English in scenario.md and the agent figures it out. If the tool vanishes tomorrow I still have the plan.
S
Staff engineer
Early Assrt user, mid-size SaaS

What I would do on day one

If I were evaluating a QA automation tool from scratch, I would run the portability test first, before any feature check. Here is the shape of that test against Assrt. The whole exercise takes about five minutes and costs a few cents of Anthropic credit.

Five-minute portability test

Where this argument ends

I am not claiming Assrt wins every feature race. A mature enterprise suite like Tricentis has integrations Assrt does not, and a Playwright codegen suite gives you tighter control when you need it. What Assrt uniquely offers is that the artifact your team produces over months of careful QA work is always a set of text files you own. Three of them, to be specific. The rest is interchangeable runner machinery.

If the tool you are currently evaluating cannot show you the equivalent three files, the one they would leave behind after cancellation, that is the answer to the one question the SERP refuses to ask.

Want to see the three files on your own site?

Book a 20-minute call. We will run assrt_test against a page you pick and cat the artifacts together.

Book a call

Frequently asked questions

What specifically does the QA automation tool leave on my disk after a run?

Three files in /tmp/assrt/. The first is scenario.md, a plain-text markdown file containing the #Case blocks the agent executed. The second is scenario.json, a small metadata file with the scenario ID (a UUID), the target URL, and the scenario name. The third is results/latest.json, which records every step the agent took, the assertions, pass/fail, and paths to screenshots and the recorded video. These three locations are hard-coded in assrt-mcp/src/mcp/server.ts around lines 294-298, and you can cat any of them from a regular terminal the moment a run finishes. No dashboard fetch, no export button, no cloud sync required to read them.

How is that different from Testim, mabl, or testRigor?

Those tools store the test definition inside their own system. With Testim you get a proprietary JSON shape rendered inside their dashboard. With mabl you get journeys inside mabl's cloud. With testRigor you get plain-English tests but still rendered inside testRigor. If you stop paying, the tests stop executing. With Assrt the plan is a markdown file. Every step is a line you can read in a text editor, commit to git, and execute on another machine that has npx and an Anthropic API key. The runner (assrt-mcp) is open-source on npm, the engine under it (@playwright/mcp) is open-source from Microsoft, and none of it is gated behind a login.

Is scenario.md an actual file I can edit by hand?

Yes. After any assrt_test call, read /tmp/assrt/scenario.md and you will see a markdown file with a YAML front-matter block (name, url, scenarioId) and one or more #Case sections. The server.ts note at line 295-296 explicitly says 'Edit /tmp/assrt/scenario.md to modify test cases; changes auto-sync to cloud storage.' So you can edit a step, re-run with the same scenarioId, and the run uses your edits. This is the opposite of a visual recorder that emits an opaque blob; here the plan is the source of truth and the blob is generated from it.

What does results/latest.json actually contain?

A JSON object with the scenario ID, a timestamp, a steps array, and a top-level pass/fail. Each step has a description, a tool name (e.g. snapshot, click, type_text, assert, complete_scenario), the arguments, the result, and optional paths to screenshots and the accessibility tree snapshot at that step. The per-run directory (/tmp/assrt/<runId>/) also contains the raw events stream and the video recording so a human can reconstruct exactly what the agent saw. Because it is JSON, you can grep it, pipe it into jq, or feed it to a CI reporter without touching any Assrt APIs.

Why does this matter for a QA automation tool specifically?

Because a QA suite accumulates value over time, not all at once. You spend six months writing signup tests, regression tests, and edge-case tests, and by the end of year one that suite is one of the most valuable assets the engineering team owns. If the tool that runs it holds the definitions, the cost of switching is the cost of rewriting all of them. By keeping the plan as markdown on disk, Assrt makes the lock-in cost zero. You can grep your own tests. You can rename them with sed. You can copy them into a new repo. The tool could disappear tomorrow and you would still have the suite.

How do I actually run one of these tests from scratch?

Two ways. From Claude Code (or any MCP client), call the assrt_test tool with { url: 'http://localhost:3000', plan: 'Test the login flow' } and the agent generates a plan, runs it, and writes the three files. From the terminal, run npx assrt-mcp to start the MCP server, or npx assrt run --url http://localhost:3000 --plan 'Test the login flow' to run a one-shot. Both paths end in the same artifacts on your disk. The browser runs headless at 1600x900 by default (see assrt-mcp/src/core/browser.ts line 296); pass --headed or set ASSRT_HEADED=1 to watch it work.

Does the tool work in CI?

Yes. assrt-mcp is a npm package, not a native binary, so any CI worker with Node can install it. In GitHub Actions, install with npm install -g @mediar/assrt-mcp, set ANTHROPIC_API_KEY as a secret, and call npx assrt run --url https://staging.example.com --plan 'Signup + OTP flow'. Upload /tmp/assrt/<runId>/ as a workflow artifact for debugging. The three canonical files (scenario.md, scenario.json, results/latest.json) are all in that directory, so a failed run is fully reproducible.

Are there real MCP tool names I can call? What are they?

Three. assrt_test is the primary entry point, defined in assrt-mcp/src/mcp/server.ts starting at line 336. It accepts url (required), plan (text), scenarioId (UUID to replay a saved scenario), headed, extension, and a few other options. assrt_plan, at line 769, navigates a URL, snapshots the page, and auto-generates executable #Case blocks from what it sees. assrt_diagnose, at line 864, is the post-mortem tool: pass it the scenario and the error and it returns root cause analysis plus a corrected plan. A fourth, assrt_analyze_video, is optional and requires GEMINI_API_KEY.

What about self-healing selectors, which every QA automation tool claims?

Assrt does not use selectors in the traditional sense. Each agent step starts with a snapshot of the page's accessibility tree (via the official Playwright MCP), which returns elements keyed by a ref like [ref=e7]. The agent clicks by ref, not by CSS selector. Refs are regenerated every snapshot, so DOM reshuffling between runs does not break them; what would break a classic selector breaks nothing here because the agent re-reads the tree, finds the element by its accessible name, and clicks the fresh ref. This makes the page-object layer effectively zero.

Is there a price? Can I see it without contacting sales?

Yes. assrt-mcp is open-source on npm and GitHub, Apache-2.0 licensed, and free to run. You bring your own Anthropic or Gemini API key and pay the model cost per run (a typical scenario is cents). There is an optional hosted web app at assrt.ai with a cloud dashboard and team features, with pricing published on the site rather than hidden behind a call. Compare to Testim's published enterprise floor around $7.5K per month and mabl's contact-sales-only model and the gap is not subtle.

Can I use this with an existing Playwright suite?

Yes. They live side by side. Keep your hot regression paths in TypeScript playwright.config tests; use Assrt for flows where writing the selector plumbing is not worth it (signup, email OTP, one-off content audits). Because Assrt runs the official Playwright MCP under the hood, the browser context is the same Chromium, Firefox, or WebKit as your existing tests. You can even share a storage state JSON between the two to reuse a logged-in session.

What is the one concrete thing I should verify before I trust this?

Install the CLI, run one test, then run `cat /tmp/assrt/scenario.md /tmp/assrt/scenario.json /tmp/assrt/results/latest.json` in your terminal. If those three files exist and are human-readable, every claim in this guide is true. If not, something is broken and nothing else in this writeup matters. The whole pitch rests on those three paths; the rest is a consequence.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.