Know what broke.
Watch it break.
QAgents writes your Test Cases, runs them in a real browser and files every Bug with the recording.
From a staging URL to your first Bug
- 1
Connect your staging app
Its URL and a test account. Add your specs or connect the repo if you have them; the Planner reads both.
Environmentstaging.acme-shop.testTest accountada@acme.test · •••••••• - 2
Approve the Suite outline
The Planner explores the live app and proposes Test Cases as Given / When / Check. You approve the outline; it writes the code.
- Search finds a product by name
- Adding a product updates the cart
- Checkout rejects an expired card
- 3
Every Run, triaged
Each Test Case gets a fresh browser and up to 3 Attempts. Every failure is judged before it reaches you.
19 passed · 3 triaged
- BugFiled, with the recording
- Stale StepRepair waiting for you
- FlakeRecorded, not filed
Every failure comes with proof
After every Step: a screenshot and an accessibility snapshot. Around them: the Step log with the element the Executor chose, the session recording and the network log. Open the Bug and watch it happen.
- Trail Mug$12.00Add to cart
- Pour-Over Kettle$45.00Add to cart
- Canvas Tote$18.00Add to cart
Stoneware, 350 ml. Keeps coffee hot on the trail.
1 result for “mug”
- Trail Mug$12.00Add to cart
- Pour-Over Kettle$45.00Add to cart
- Canvas Tote$18.00Add to cart
Stoneware, 350 ml. Keeps coffee hot on the trail.
1 result for “mug”
- Trail Mug$12.00Add to cart
- Pour-Over Kettle$45.00Add to cart
- Canvas Tote$18.00Add to cart
Stoneware, 350 ml. Keeps coffee hot on the trail.
1 result for “mug”
- Trail Mug$12.00Add to cart
- Pour-Over Kettle$45.00Add to cart
- Canvas Tote$18.00Add to cart
Stoneware, 350 ml. Keeps coffee hot on the trail.
1 result for “mug”
- Trail Mug$12.00Add to cart
- Pour-Over Kettle$45.00Add to cart
- Canvas Tote$18.00Add to cart
Stoneware, 350 ml. Keeps coffee hot on the trail.
1 result for “mug”
- 12goto"/products"
- 13actsearchbox "Search products"0.97
- 14actbutton "Add to cart"0.94
- 15expect#cart-countgot "2", expected "1"
- GET/products?q=mug20084 ms
- POST/api/cart200121 ms
- GET/api/cart/count200{"count":2}
A failure is not a Bug until it’s judged
Every failure gets up to 3 Attempts. Then it gets one of four Verdicts, and each one does something different.
- Bug
Your app is wrong.
Filed with the steps to reproduce, expected vs actual, and the recording. Seen again, it's added to the same Bug. Fixed, it closes itself.
- Stale Step
Your app changed on purpose.
QAgents proposes a Repair to the Test Case and proves it with a passing re-run. It's applied when you accept it.
- Flake
It failed, then passed on a retry.
Recorded, not filed. A Test Case that flakes in 2 of its last 5 Runs is marked Flaky, so you can deal with it.
- Environment
Your staging was down.
Not blamed on your app. After three of these in one Run, the rest of the Run is Blocked instead of piling up failures.
−await act("click Checkout")+await act("click Continue to payment")await expect(page).toHaveURL(/pay/)
Verified by a passing re-run
No Expectation changed
Nothing edits an Expectation without you. A Repair that touches an expect line waits for a Member to accept it, flagged Changes an Expectation.
Code asserts.
AI acts.
Every Test Case is a short TypeScript file you can read, edit and review. The model only chooses what to click; whether your app is right is plain Playwright.
- act
The Executor picks the element
A renamed button doesn’t break the test. It reports its choice and a confidence, and warns you with Drift when it changes.
- expect
Assertions stay deterministic
Playwright’s own
expect. No model decides whether your cart shows 1.- %pw%
Credentials stay out of the prompt
Variables are filled in at action time. The Executor chooses where a value goes, never what it is.
1import { expect } from "@qa-hub/test"23export default async ({ page, act, credential }) => {4 const cart = page.locator("#cart-count")5 await page.goto("/login")6 await act("log in with %email%
and %pw%", {7 variables: {8 email: credential("ada", "username"),9 pw: credential("ada", "password"),10 },11 })12 await page.goto("/products")13 await act("search for mugs")14 await act("add Trail Mug to cart")15 await expect(cart)16 .toHaveText("1")17}
Give it your staging URL
Add a test account, approve the Suite outline, and read your first Run’s Verdicts. No test code to write first.
Start testing your app- BugCart badge shows 2, expected 1Filed with the recording
- Stale StepCheckout button was renamedRepair verified, waiting for you
- FlakeSearch results loaded latePassed on Attempt 2 · not filed
19 passed · 3 triaged