lv-qa · early access

The QA compiler that tells you what it couldn't automate.

Point it at the test cases you already have — a TestRail, Xray or Zephyr export, or a Markdown guide — and it returns runnable flows, an honest count of what really runs end to end, and a reason for every step it refused to claim.

Input
One CSV export. No source, no SDK, no device access.
Output
Maestro flows, coverage map, manual remainder.
Status
Pre-release. Looking for design partners.
The one idea

Everyone reports what they automated. This reports what they didn't.

Any tool can print a coverage percentage. The number is almost always inflated, because the hard half of a QA suite quietly falls out of the denominator — the steps that need a human eye, a second device, a real charge on a real card.

This inverts it. Coverage is claimed only where a real selector can be emitted, and every step that does not make the cut comes back with a reason you can act on. Two rules hold that line.

No guessed selectors

If a test case says tap the first card, there is no label to target. A tool that guesses produces a test that passes while checking nothing — strictly worse than no test. So that step is reported as a gap, with the fix named: quote the label, or add an accessibility id.

A scenario counts only if every step compiled

A flow that silently skips its one manual step still goes green. Incomplete flows are written as .partial.yaml, carry a header saying a green run proves nothing, and are excluded from the coverage number everywhere.

Why the second rule matters. Step coverage and scenario coverage are different numbers, and they diverge a long way on real suites. The step percentage is what a vendor puts on a slide. The count of scenarios that run start to finish is what you can trust on a release night. You get both, side by side, and the gap between them is usually the finding.

Every step gets one of three verdicts

And the middle one is where the work is.

compiled

Runnable now, with a concrete target. The only category that counts toward coverage.

Nobody has to do anything.

assisted

Intent is clear, one specific thing is missing — a selector, a data fixture, a rule for a branch. Named per step.

One human edit each, then it compiles.

manual

Not automatable from a UI driver: visual judgement, hardware, an external system, real elapsed time.

Stays human. Budget it honestly.

How you would use it

Four steps, starting from a button you already have.

  1. 1

    Export your test cases to CSV

    TestRail, Xray and Zephyr Scale all ship this as a standard export. Nothing leaves your test-management tool except a spreadsheet of steps you already wrote.

    All three schemas are verified against each vendor's own published sample exports — including the parts the prose docs get wrong, like Xray naming the expected-result column Result.

  2. 2

    Confirm the columns were read correctly

    Detection is automatic, but a wrong guess here would be silent — so it is shown to you before anything compiles.

    lv-qa columns export.csv

    Anything mis-detected is overridden with -c action='Step'. Ten seconds, and it removes the one failure mode you could not otherwise see.

  3. 3

    Compile

    You get runnable .yaml flows for Maestro, clearly-marked .partial.yaml for anything with a gap, plus COVERAGE.md, MANUAL.md and a machine-readable coverage.json.

    lv-qa compile export.csv --app-id com.yourapp --out flows
  4. 4

    Read the remainder, then gate on it

    MANUAL.md is a prioritised work plan, not an apology — gaps are grouped by cause and ranked, because they cluster far harder than anyone expects.

    lv-qa compile export.csv --app-id com.yourapp --min-scenario-coverage 60

    Once you are happy with the number, that flag fails the build if end-to-end coverage regresses.

lv-qa compile export.csv --app-id com.yourapp
$ lv-qa compile export.csv --app-id com.yourapp --out flows

Release regression suite
 32 steps across 4 scenarios

 COMPILED 19 runnable now
 ASSISTED 9 needs one human edit
 MANUAL 4 stays human

 59% of steps runnable · 0/4 scenarios end to end

 Biggest blockers
 9 ( 69%) Target not named — add a quoted label or an accessibility id
 2 ( 15%) Requires a radio or network state change outside the app
 1 ( 8%) Requires an external system outside the app

 4 incomplete flow(s) written as *.partial.yaml — not coverage, do not wire into CI
 Manual remainder → flows/MANUAL.md

Illustrative output from a sample suite bundled with the tool, not from customer data.

Read the blocker list again. Most of what could not be automated traces back to a single cause — expected results written as prose, with no quotable label. That is one instruction to whoever writes your test cases, not nine separate problems. Ranking gaps by cause is usually the most useful thing in the run, and it is why the remainder is worth reading rather than filing.

What comes back

A flow you can trust, and a flow that admits it cannot be.

Both are emitted, and the difference between them is the whole point — the incomplete one keeps your manual step visible as a comment instead of dropping it and reporting a pass.

flows/offline-behaviour.partial.yaml
appId: com.yourapp
name: Offline behaviour
# INCOMPLETE — this flow has documented gaps (see below).
# A green run does NOT mean the scenario passed. Do not add
# it to CI until every gap is closed and it is renamed .yaml.
---
- launchApp
# GAP [manual] Turn off Wi-Fi and mobile data
#   why: Requires a radio or network state change outside the app
- tapOn: "Today"
- assertVisible: "You're offline"
- scroll
# GAP [assisted] Verify cached sessions are still listed
#   why: Target not named — add a quoted label or an accessibility id
What it costs you to try

One spreadsheet.

What we need

  • A CSV export of your manual test cases.
  • Your app's bundle id, to stamp the flows.
  • Ten minutes to read the remainder with us.

What we do not

  • Your source code, or any repository access.
  • An SDK, an agent, or anything inside your app.
  • Crash data, telemetry, analytics, or device access.
Straight answers

What it does not do yet.

Maestro only, for now

Flows are emitted for Maestro, which runs on both Android and iOS. XCUITest and Espresso emitters slot in behind the same interface but are not built.

No model in the loop

Classification is fully deterministic — the same input always yields the same verdict, and nothing is invented. An LLM pass to propose selectors for assisted steps is designed, and deliberately not shipped until the deterministic baseline is measured.

Accuracy is not yet proven

There is a 104-case evaluation harness, half of it adversarial, gating on the error that matters: claiming a step is runnable when it is not. Its first run caught five such cases. But the labels and the classifier share an author, so that score is regression protection — not an accuracy claim. Your export would be the first independent test.

Markdown and CSV only

Confluence and Google Docs ingest are not built. If your cases live there, exporting to Markdown works today, and a native connector is a small piece of work.

We are looking for the first few suites to point this at.

If your team owns test automation without a dedicated QA function — and the suite has collapsed more than once — that is exactly the case this was built for. Send one export, get the flows and the remainder back, and tell us where it is wrong.

Become a design partner

The compiler is deterministic and runs against a file you export. Vendor schemas for TestRail, Xray and Zephyr Scale were each verified against those vendors' own published sample exports; the sample files themselves are not redistributed. Figures shown on this page come from sample suites bundled with the tool and are illustrative of its output format, not measurements of customer results.