Skip to content

test: restore 100% coverage — cover the 46 snapshot.py branches left untested by #226#247

Merged
pranavz28 merged 2 commits into
masterfrom
PER-9772_fix-coverage-on-cli-from-git
Jul 3, 2026
Merged

test: restore 100% coverage — cover the 46 snapshot.py branches left untested by #226#247
pranavz28 merged 2 commits into
masterfrom
PER-9772_fix-coverage-on-cli-from-git

Conversation

@pranavz28

Copy link
Copy Markdown
Contributor

Root cause

The PER-9772 SDK-regression dispatch run (28640545663) failed make coverage with zero test failures — only the coverage gate tripped: percy/snapshot.py 564 stmts, 46 miss, 92% → TOTAL 94% < fail_under = 100 (.coveragerc).

This is not CLI-flavor dependent. The normal push-CI run for the same commit (28495875576 / 28495790591, released @percy/cli) fails with the byte-identical missing-lines list. Master has been red since #226 (feat: CORS iframes + closed shadow DOM parity) merged: it added new guard/error-fallback branches to percy/snapshot.py without tests for all of them.

Exact missing lines (identical in both the dispatch and push runs):

36-37, 247-248, 253-254, 272-274, 303-305, 316-317, 341-343, 364-366,
374, 377, 408-409, 416, 460-462, 483-484, 549, 557-560, 564-565, 605,
607-608, 613-614, 807-808, 959-963

Fix

Add deterministic, CLI-independent unit tests to tests/test_snapshot_units.py (runs as a plain unittest module, no percy exec) covering every missed branch:

Lines Branch covered
36-37 invalid PERCY_RESIZE_SETTLE_SECONDS env falls back to 0.5 (module reload)
247-248, 253-254 _should_skip_iframe: unparseable origin; cross-origin frame missing data-percy-element-id
272-274 process_frame_tree: depth > max_frame_depth cap
303-305 iframe element no longer found by data-percy-element-id
316-317 post-switch document.URL read failure treated as unsupported
341-343 empty PercyDOM.serialize result for a frame
364-366 nested-iframe enumeration failure keeps parent capture
374, 377 skipped nested child (continue); successful nested capture collected
408-409 default_content() failure swallowed at depth 1
416 PercyContextLost chains the original processing error as __cause__
460-462 _capture_cors_iframes outer error guard (malformed enumeration entry)
483-484 driver.capabilities access failure treated as non-Chromium
549, 557-560, 564-565 closed-shadow-root CDP: missing objectIds, DOM.resolveNode failure, DOM.getDocument + DOM.disable failures
605, 607-608, 613-614 get_origin no-scheme/netloc and parse-raise paths; _get_origin compat shim
807-808 driver.current_url read failure in get_serialized_dom
959-963 PERCY_DEBUG responsive snapshot dump (write path + failure path)

No production code changes and no # pragma: no cover — all branches are deterministically exercisable with mocks. Since the new tests never touch the CLI, coverage of these lines no longer depends on which @percy/cli (released or built-from-git) is installed.

Verification

Local, Python 3.9.18, mirroring the Makefile coverage target exactly (tests.test_snapshot under percy exec --testing with @percy/cli 1.32.2 + the five plain modules, coverage combine, coverage report):

percy/snapshot.py            564      0   100%
TOTAL                        759      0   100%
  • All 33 tests in tests.test_snapshot_units pass (was 8, +25 new); tests.test_snapshot unchanged and green (96 tests).
  • pylint percy/* tests/* → 10.00/10.
  • Both failing CI runs (dispatch with git-built CLI, push with released CLI) missed the exact same 46 lines, and everything else was already covered under both CLI flavors — so covering these lines with CLI-independent unit tests makes the gate pass on both the normal CI path and the PER-9772 regression-dispatch path.

🤖 Generated with Claude Code

PR #226 (CORS iframes + closed shadow DOM parity) added new guard and
error-fallback branches to percy/snapshot.py without tests for all of
them, dropping total coverage from 100% to 94% and tripping the
fail-under=100 gate in `make coverage` on every run since — both normal
push CI (released @percy/cli) and the PER-9772 regression dispatch
(@percy/cli built from git) fail with the identical missing-lines set,
so the gap is deterministic, not CLI-flavor dependent.

Add plain unit tests (no CLI needed) to tests/test_snapshot_units.py
covering every previously missed line:

- 36-37: invalid PERCY_RESIZE_SETTLE_SECONDS falls back to 0.5
- 247-248, 253-254: _should_skip_iframe invalid-origin / missing
  percyElementId skips
- 272-274, 303-305, 316-317, 341-343, 364-366, 374, 377:
  process_frame_tree depth cap, missing element, document.URL read
  failure, empty serialize result, nested-enumeration failure, skipped
  child continue, nested capture collection
- 408-409, 416: context-loss recovery (default_content failure at
  depth 1; PercyContextLost chaining the original error at depth > 1)
- 460-462: _capture_cors_iframes outer error guard
- 483-484, 549, 557-560, 564-565: expose_closed_shadow_roots
  capabilities failure, missing objectIds, resolveNode failure,
  getDocument + DOM.disable failures
- 605, 607-608, 613-614: get_origin parse failures and _get_origin shim
- 807-808: get_serialized_dom current_url read failure
- 959-963: PERCY_DEBUG responsive snapshot dump (write + failure path)

Verified locally on Python 3.9: full `make coverage` sequence
(test_snapshot under `percy exec --testing` + the five plain modules)
reports 759/759 statements, TOTAL 100%; pylint 10.00/10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pranavz28 pranavz28 requested a review from a team as a code owner July 3, 2026 06:18
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pranavz28 pranavz28 merged commit 9188fc9 into master Jul 3, 2026
9 checks passed
@pranavz28 pranavz28 deleted the PER-9772_fix-coverage-on-cli-from-git branch July 3, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants