A green suite tells you the tests you wrote passed. It says nothing about the tests you never wrote. The harder, more useful question is which parts of your app nothing exercises at all, and that's not something you can eyeball from a list of passing scenarios.
TestVibe answers it in the App Code section: it reads your application's source, infers the areas your app is made of, and maps your existing UI tests onto them. The parts nothing tests rise to the top.
The gap a green suite hides
Line coverage from a unit runner measures which lines of code executed during your tests. That is useful, but it doesn't tell you whether a user-facing flow is exercised end to end. You can have 80% line coverage and zero tests that actually walk through checkout in a browser.
UI test coverage is a different axis: which features of the running app do your Playwright tests drive? The honest way to find blind spots is to line up every meaningful area of the app against the tests that touch it, and look for the areas with nothing next to them. That side-by-side is exactly what App Code builds.
How the app areas are derived
You don't hand-maintain a list of areas. An AI scan reads your connected source repository, detects the stack, and infers route-grounded app areas such as "Checkout" or "Login", grounded against the URLs your app actually serves rather than guessed from file names. Your existing features are then auto-mapped onto those areas.
Because the areas come from real routes, they match how you'd describe the app to a teammate: the surfaces a user can reach, not an arbitrary folder taxonomy. If the automatic mapping puts a feature in the wrong area, you re-map it by hand.
Reading the map, gaps first
App Code browses your source like a code tab: drill through folders with the breadcrumb, or jump to a file from the tree sidebar. Folders list A–Z by default, but the view is built for finding holes, so two toggles change what you look at:
- Gaps first — reorders the tree to surface untested code at the top.
- Only gaps — hides everything except files that nothing tests.
A search box filters files across the whole tree. Flip Only gaps on, and you're looking at a literal list of your blind spots instead of scrolling a full directory hoping to spot the holes.
Per-file coverage: what tests this file
Expand any file to see its Tested by panel, listing the features mapped to that file, each showing its last-run pass or fail status and an Open link. That last part matters: a file can be "covered" by a feature that is currently failing, which is a different kind of problem than a file covered by nothing. The panel shows both at a glance.
Mapping comes from two sources. The first is the AI's automatic file-to-area matching. The second is an explicit tag you put on a Gherkin scenario to pin it to a source file:
@covers:Services/CheckoutService
Scenario: Applying a valid promo code reduces the order total
Given a cart with two items totaling $80.00
When I apply the promo code "SAVE10"
Then the order total should be $72.00
The @covers: tag links that scenario straight to the file. Add a path qualifier (Services/CheckoutService rather than a bare CheckoutService) when a class name matches more than one file in your repo. If the tag is ambiguous, TestVibe leaves it unmapped rather than guessing at the wrong file.
When a mapping is wrong, fix it inline: remove a stale link, or map a test yourself. Your corrections are sticky and survive re-scans, so you're not re-doing the same fix every time the source changes.
Executed lines, where the stack supports it
Structural mapping (files, areas, gaps) works for any stack. On top of that, TestVibe collects real executed-line data for .NET and Node.js projects by running your project's own tests in its cloud sandboxes, the same fleet that runs your Playwright tests:
# .NET projects
dotnet test
# Node.js projects
node --test
Each file and folder then reports an executed-vs-tested rollup, and the hero shows an executed-lines trend as a sparkline so you can watch coverage move over time. Projects on other stacks still get the full structural files/areas/gaps mapping; they just don't get an executed-lines number attached.
Catching gaps before they merge
Coverage is most useful before code ships, not after. Pick the branch you want to inspect. On a feature branch, App Code highlights the files that are new in that branch and flags the new ones that nothing tests yet.
That turns "we'll add tests later" into a visible checklist on the branch itself. You see the untested new file while the change is still in review, which is the cheapest possible moment to write the missing test.
Turning gaps into a backlog
The point of surfacing blind spots is to act on them. A practical loop:
- Open App Code and flip on Only gaps to list untested files.
- Turn on Gaps first at the folder level to rank by where the untested code concentrates: a whole untested area matters more than one stray helper.
- For the areas that carry real user risk (checkout, auth, anything touching money or data), describe the missing behavior in plain language and let TestVibe generate the Playwright test for it.
Because generated tests are verified by actually running them against your app before they're saved, closing a gap gives you a test that demonstrably works, not a stub you'll have to babysit. The gap list shrinks with each real, passing feature you add, and the sparkline shows it moving.
Getting started
App Code needs a connected source repository. Connect one under Settings → App Repository, then run a scan to populate files, areas, and coverage. The scan reads your source read-only: connecting an app repository never gives TestVibe write access, and it's separate from where your test files live.
Once the map is built, the honest answer to "what do my tests cover?" stops being a guess. You get a ranked list of what they don't, and a fast path to fixing the parts that matter. See the App Code docs for the full walkthrough, and get early access to map your own blind spots.