@@ -246,16 +246,24 @@ def detect_fw():
246246 except : return None
247247
248248def parse_junit (path ):
249- """Parse junit XML for pass/fail per test method. Returns {method_name: 'pass'|'fail'|'error'|'skip'}"""
249+ """Parse junit XML for pass/fail. Returns dict keyed by both 'classname.method' and 'method'.
250+ When names collide, pass wins over fail (avoids false negatives from unrelated test classes)."""
250251 if not path or not os .path .exists (path ): return {}
251252 import xml .etree .ElementTree as ET
252253 results = {}
253254 for tc in ET .parse (path ).iter ('testcase' ):
254- name = tc .get ('name' ,'' )
255- if tc .find ('failure' ) is not None : results [name ] = 'fail'
256- elif tc .find ('error' ) is not None : results [name ] = 'error'
257- elif tc .find ('skipped' ) is not None : results [name ] = 'skip'
258- else : results [name ] = 'pass'
255+ name = tc .get ('name' , '' )
256+ cls = tc .get ('classname' , '' )
257+ if tc .find ('failure' ) is not None : status = 'fail'
258+ elif tc .find ('error' ) is not None : status = 'error'
259+ elif tc .find ('skipped' ) is not None : status = 'skip'
260+ else : status = 'pass'
261+ # Key by classname.method (precise) and method-only (fallback)
262+ if cls :
263+ results [f'{ cls } .{ name } ' ] = status
264+ # For method-only key, pass wins over fail (avoid collision false negatives)
265+ if name not in results or status == 'pass' :
266+ results [name ] = status
259267 return results
260268
261269# ---------------------------------------------------------------
@@ -512,10 +520,9 @@ def parse_junit(path):
512520 'Sign multi-input BTC tx' ,
513521 'Two inputs, two outputs. Verifies correct fee calculation across multiple inputs.' ,
514522 []),
515- ('B12' , 'test_msg_signtx' , 'test_lots_of_inputs' ,
516- 'Sign tx with many inputs' ,
517- 'Stress test with many UTXOs. Verifies the device handles the serialization and memory '
518- 'correctly without truncation or overflow.' ,
523+ ('B12' , 'test_msg_signtx' , 'test_spend_coinbase' ,
524+ 'Sign coinbase spend' ,
525+ 'Spending a coinbase (mining reward) output. Coinbase outputs have special maturity rules.' ,
519526 []),
520527 ('B13' , 'test_msg_signtx' , 'test_lots_of_outputs' ,
521528 'Sign tx with many outputs' ,
@@ -628,8 +635,8 @@ def parse_junit(path):
628635 'MakerDAO generate DAI' , 'Complex DeFi contract interaction (MakerDAO CDP).' , []),
629636 ('E13' , 'test_msg_ethereum_sablier' , 'test_sign_salarywithdrawal' ,
630637 'Sablier salary withdrawal' , 'Streaming payment protocol contract call.' , []),
631- ('E14' , 'test_msg_ethereum_erc20_uniswap_liquidity ' , 'test_sign_uni_add_liquidity_ETH ' ,
632- 'Uniswap add liquidity ' , 'DEX liquidity provision contract interaction .' , []),
638+ ('E14' , 'test_msg_ethereum_erc20_0x_signtx ' , 'test_sign_0x_swap_ETH_to_ERC20 ' ,
639+ '0x swap ETH to ERC-20 ' , 'DEX aggregator swap via 0x protocol .' , []),
633640 ('E15' , 'test_msg_ethereum_cfunc' , 'test_sign_execTx' ,
634641 'Contract function call' , 'Generic contract call signing.' , []),
635642 ]),
@@ -712,9 +719,9 @@ def parse_junit(path):
712719 [
713720 ('M1' , 'test_msg_mayachain_getaddress' , 'test_mayachain_get_address' ,
714721 'Derive Maya address' , 'Bech32 maya1... address.' , []),
715- ('M2' , 'test_msg_mayachain_signtx' , 'test_mayachain_sign_tx ' ,
716- 'Sign Maya tx ' , 'Native CACAO transfer .' , ['Maya confirm' ]),
717- ('M3' , 'test_msg_mayachain_signtx' , 'test_sign_btc_eth_swap ' ,
722+ ('M2' , 'test_msg_mayachain_signtx' , 'test_sign_btc_eth_swap ' ,
723+ 'Sign BTC-ETH swap via Maya ' , 'Cross-chain swap via Maya memo routing .' , []),
724+ ('M3' , 'test_msg_mayachain_signtx' , 'test_sign_eth_add_liquidity ' ,
718725 'Sign swap via Maya' , 'Cross-chain swap via Maya memo routing.' , []),
719726 ]),
720727
0 commit comments