So nothing is forgotten, the team first lists what in the application must keep working: surfaces — screens, buttons, forms, fields — and their states. The same button behaves differently when all is well, when there is no data, and when an error happened; each such case needs to be protected separately.
Coverage is the answer to the question “what do we already have under protection, and what not”. Not “how many tests we have” but “which places of the application these tests really guard”. The difference is big: dozens of tests can walk over one screen and never visit its neighbor.
The Inventory
The coverage inventory is a list where one row means one surface in one state. For example: “checkout button — normal state”, “order list — empty”, “login form — wrong password”.
A row shows three things: which tests cover it, who owns it, and where it came from. There are three origins — added manually, found by the crawler, or suggested by the agent. This is not a formality: the team considers manual records their own, and automation does not touch them.
The Three Row States
Every row has exactly one of three states:
- Covered — there is at least one test that guards it.
- Not covered — the row exists, there are no tests.
- Deliberately uncovered — the team decided not to check it.
A deliberate refusal is not an empty cell but a recorded decision. It requires a reason and a review date: for example, the reason “an outdated screen scheduled for removal” and the date when the decision will be revisited. The product will not accept half a decision — without a reason or without a date the row will not save. Why this is needed: half a year later you can see a deliberate choice of the team in front of you, not a forgotten entry.
Progress Toward the Target
The project settings define a target — how many “surface × state” combinations the team wants to close. The tab builds a progress line against it: “covered of target 20”. It is the surface-and-state pairs that are counted, not the number of tests: one test can close several rows at once, or none. The target shows real protection, not file count.
Beside it you can see what changed since the last build: how many rows were added, how many were closed, and how many moved to deliberately uncovered. This makes it visible whether the work is moving or standing still.
Your Own Ugly States
There are states that are hard to reach: a user with a 120-character name, a feature flag turned off, an image that did not load, a declined payment. They often go untested not because it does not matter but because it is inconvenient. Such cases can be quickly dropped into a separate queue — type the surface and state as plain text — and come back to the decision later.
Until you get to them, these rows lie honestly in the inventory as uncovered. That is better than pretending they do not exist: the problem is in sight and awaits a decision.
Test Proposals
If a row has nothing to cover it, you can ask the agent to draft a covering test. It appears on the row as a proposal: you can see which test is proposed and why. Nothing is written until a human accepts the proposal; accepting creates the test and links it to the row.
A proposal can be rejected, but only with a reason — so it stays clear later why the test was not taken. And separately: a test becomes covering not at the moment of creation but after a run that proves it. Until the run, the row stays open.
What Never Gets Overwritten
The inventory is filled both by hand and by the browser crawl. The rule is simple: the crawl only adds new rows. If a row with the same surface and state was already filled in manually, the crawl will not touch it — it changes neither the tests, nor the owner, nor the decision. Otherwise automation would erase the team’s decisions, and the inventory could not be trusted.
Next: how to see which addresses the application consists of — in App Map & Crawling.