Skip to content

Commit 91a0334

Browse files
committed
fix(ci): require declared screenshots and Uniswap evidence
Resolve #516 and #529 by rejecting skipped Uniswap liquidity coverage, discarding harness wipe frames, and requiring at least one captured frame per declared screen.
1 parent b4f5f0e commit 91a0334

2 files changed

Lines changed: 21 additions & 11 deletions

File tree

scripts/generate-test-report.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3237,6 +3237,9 @@ def screenshot_filter(fw_version):
32373237
MUST_RUN_MODULES = {
32383238
'test_msg_signtx_taproot': '7.0.0',
32393239
'test_msg_getaddress_taproot': '7.0.0',
3240+
# GH #516: all three Uniswap liquidity tests used to skip together on the
3241+
# emulator, leaving a daily-driver signing path completely unexercised.
3242+
'test_msg_ethereum_erc20_uniswap_liquidity': '7.16.0',
32403243
# R-4.1. Gated on requires_message('LoadClearsignSigner'), so if provider
32413244
# loading regressed, all four would skip and the report would certify a
32423245
# feature it never exercised.
@@ -3248,22 +3251,22 @@ def screenshot_filter(fw_version):
32483251
# remains mandatory in both products, and the expected build variant comes from
32493252
# CI rather than the firmware identity being tested.
32503253
FULL_FEATURE_ONLY_MUST_RUN_MODULES = {
3254+
'test_msg_ethereum_erc20_uniswap_liquidity',
32513255
'test_msg_solana_lut_attestation',
32523256
}
32533257

32543258

32553259
def screenshot_audit(fw_version, screenshot_root, junit_path=None):
3256-
"""Which SECTIONS tests DECLARED screens but captured none?
3260+
"""Which SECTIONS tests captured fewer frames than they declared?
32573261
32583262
The CI gate was `total PNG count > 0`, which a single captured suite
32593263
satisfies. That cannot distinguish "captured everything" from "captured
32603264
something": in the 7.14.2 round, 345 PNGs were produced while every suite
32613265
the release actually changed captured zero, and the phase reported healthy.
32623266
3263-
Returns (ok, missing) where missing is a list of (module, method) that
3264-
declared a non-empty screenshot list, were not skipped, and produced no
3265-
PNG directory. Skipped tests are not missing -- a version-gated test
3266-
cannot draw.
3267+
Returns (ok, missing) where missing contains
3268+
(module, method, expected_count, captured_count). Skipped tests are not
3269+
missing -- a version-gated test cannot draw.
32673270
"""
32683271
import os as _os
32693272
skipped = set()
@@ -3287,8 +3290,10 @@ def screenshot_audit(fw_version, screenshot_root, junit_path=None):
32873290
if (mod, meth) in skipped:
32883291
continue
32893292
d = _os.path.join(screenshot_root, mod.replace('test_', '', 1), meth)
3290-
if not _os.path.isdir(d) or not [f for f in _os.listdir(d) if f.endswith('.png')]:
3291-
missing.append((mod, meth))
3293+
pngs = ([f for f in _os.listdir(d) if f.endswith('.png')]
3294+
if _os.path.isdir(d) else [])
3295+
if len(pngs) < len(scr):
3296+
missing.append((mod, meth, len(scr), len(pngs)))
32923297
return (len(missing) == 0, missing)
32933298

32943299

@@ -3348,9 +3353,10 @@ def main():
33483353
if ok:
33493354
print('screenshot audit: every declared screen was captured')
33503355
sys.exit(0)
3351-
print('screenshot audit FAILED -- declared screens with no capture:')
3352-
for mod, meth in missing:
3353-
print(' %s::%s' % (mod, meth))
3356+
print('screenshot audit FAILED -- fewer captures than declared screens:')
3357+
for mod, meth, expected, captured in missing:
3358+
print(' %s::%s (declared %d, captured %d)' %
3359+
(mod, meth, expected, captured))
33543360
sys.exit(1)
33553361
if args.screenshot_filter:
33563362
print(screenshot_filter(fw))

tests/common.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ def setUp(self):
7575
self.pin8 = '45678978'
7676

7777
self.client.wipe_device()
78+
# The wipe confirmation belongs to the test harness, not the test.
79+
# Drop it for every suite, including suites that never call one of the
80+
# setup_mnemonic_* helpers; otherwise a presence-only screenshot audit
81+
# can mistake this frame for evidence of the behavior under test.
82+
self._drop_setup_screenshots()
7883

7984
if VERBOSE:
8085
print("Setup finished")
@@ -246,4 +251,3 @@ def requires_bitcoinOnly(self):
246251
self.skipTest("Bitcoin-only firmware required to run this test")
247252

248253

249-

0 commit comments

Comments
 (0)