Skip to content

test: fix two Trezor emulator UI test flakes - #1015

Draft
mdozhdev wants to merge 3 commits into
masterfrom
test/trezor-ui-test-fixes
Draft

mdozhdev wants to merge 3 commits into
masterfrom
test/trezor-ui-test-fixes

Conversation

@mdozhdev

@mdozhdev mdozhdev commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Blocks #923: its ai-device-tests Trezor job on the Namespace runner fails on these two tests.

This PR is a starting point for fixing TrezorBridgeDashboardUITests on the Namespace runner. It records what was found, and is handed to the suite's owner to finish.

Description

  • Waits for each prompt (PIN, passphrase, pairing, confirm on device) to close after cancelling it, so the next prompt is not requested while a sheet is still dismissing.
  • Looks for the app-wide HwPairSheet instead of the dashboard's TrezorPairingSheet, because since 02f2dfc (2026-06-22, "hardware suggestion and sheet") a pairing request opens the app-wide pairing sheet from MainNavView, and that sheet has no cancel button.
  • Clears a prefilled text field by deleting one character per character of its value instead of relying on the "Select All" menu, which the simulator does not show.
  • Removes the tapIfExists helper, which nothing else uses.

Out of Scope

  • BitkitUITests/TrezorBridgeDashboardUITests.swift: testBridgeConnectLifecycleAndPromptContracts still fails at the pairing step: TrezorTestHook-Pairing sets showPairingCode, but HwPairSheet does not appear over the dashboard within 5 s (line 54).
  • BitkitUITests/TrezorBridgeDashboardUITests.swift: clearAndType is still unreliable, because a tap leaves the cursor at the end of the text in some runs and at the start in others, so deleting backwards from the cursor sometimes deletes nothing.

Design

N/A — no UI changes.

Preview

N/A — no user-visible changes.

QA Notes

Journeys

N/A — no user-visible behaviour change.

Manual Tests

N/A

Automated Checks

  • updated TrezorBridgeDashboardUITests.swift — prompts close before the next one opens; the pairing step targets HwPairSheet
  • ran ai-device-tests with trezor-emu on a Namespace runner, with this change on top of ci: move Mac mini jobs to Namespace runners #923, as dispatches from a temporary branch: testBridgeUnavailableShowsRecoverableState passes; the two tests above still fail for the reasons in Out of Scope (39399319721)

🤖 Generated with Claude Code

mdozhdev and others added 2 commits October 19, 2026 18:04
The lifecycle test opened each prompt right after cancelling the previous
one, and SwiftUI drops a sheet presentation while another is dismissing,
so the pairing sheet never appeared. The clear helper relied on a Select
All menu that the simulator does not show, so it deleted one character
and appended the new text to the prefilled message.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Pairing prompts open the app-wide HwPairSheet, not the dashboard's own
sheet, and it has no cancel button, so the test now swipes it away. The
extra tap at the field's corner lost keyboard focus; the normal tap
already leaves the cursor at the end of the text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mdozhdev

Copy link
Copy Markdown
Collaborator Author

@ovitrif handing this one to you as the author of TrezorBridgeDashboardUITests and ai-device-tests.

The job now runs on a Namespace Mac (#923) and the emulator and Bridge come up, but two tests still fail, and both need someone who knows the dashboard:

  • testBridgeConnectLifecycleAndPromptContracts: TrezorTestHook-Pairing sets showPairingCode, but neither the old TrezorPairingSheet nor the app-wide HwPairSheet appears over the dashboard. Pairing moved to the app-wide sheet in 02f2dfc, after this test was written.
  • testAddressPublicKeyMessageBalanceHistoryDetailAndSendFlow: clearAndType cannot reliably replace the prefilled "Hello, Trezor!", because the tap leaves the cursor at the end in some runs and at the start in others.

The PR description has the details and the run links. The funding failure in the same test is fixed separately in #923 (101 blocks mined before the emulator starts). To try a change on Namespace before #923 merges, dispatch ai-device-tests from a branch that includes #923.

@mdozhdev

Copy link
Copy Markdown
Collaborator Author

Status: the red SwiftFormat check here comes from Bitkit/Views/Wallets/Activity/ActivityRow.swift on master, not from this PR; #1040 fixes it. The two Trezor test failures described above are unchanged.

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: ⚠️ Not verified — the two documented test blockers still prevent complete QA.

Findings: No new findings. The existing blockers are documented in the author’s handoff and listed under Out of Scope.

QA for afda99d: iPhone 17 Pro simulator, iOS 26.5.

Test 1: Bridge lifecycle and prompt contracts ⏭️ PIN and passphrase dismiss; the existing pairing blocker prevents the remaining checks.

XCTest passed both new dismissal waits, then stopped at the missing HwPairSheet assertion on line 55. The full case remains unverified.

The pairing blocker has a concrete cause: AppScene.trezorEmulatorTestContent mounts TrezorRootView directly, bypassing MainNavView, which owns the app-wide pairing presenter. The test root needs that presenter before changing the selector can exercise pairing dismissal. Confirmation cancellation and disconnect/forget/reconnect were not reached.

prompts.2x.mp4

Test 2: Address, public key, message and transaction flow ⏭️ The documented text-replacement blocker prevents completing the flow.

After address generation, funding, public-key export and message signing, XCTest failed at line 266: the message was Bitkit Trezor emulator testHello, Trezor!, rather than Bitkit Trezor emulator test. This value was checked through the XCTest field assertion. The helper inserted the new text without clearing the old value.

Signature verification, balance/history/detail and send/broadcast checks were not reached. This reproduces the test-helper issue already documented in the PR; it does not establish a product failure.

wallet.2x.mp4

Test 3: Unavailable Bridge recovery ✅ Carried the author's passing result on identical app and test source.

testBridgeUnavailableShowsRecoverableState passed in the linked automated run. I compared its commit, baf879f, with afda99d: all differences are CI configuration or contributor documentation, so I did not repeat this case.

Both focused XCTest invocations failed at the acknowledged test blockers; their complete end-to-end cases are recorded as unrun. No additional manual journeys were listed.

Reviewed the full PR diff, one file. Pairing/confirmation dismissal and the later lifecycle and transaction checks remain unverified.

Android pair: none linked; this change is specific to iOS XCTest.


Reviewed by gpt-6.1-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: ⚠️ Not verified — the two documented test blockers still prevent complete QA.

Findings: No new findings. Both blockers remain as described in the author's handoff and the previous review.

QA for d18b093: iPhone 17 Pro simulator, iOS 26.5; rebuilt this head with the Trezor emulator test configuration.

Test 1: Bridge lifecycle and prompt contracts ⏭️ XCTest confirmed PIN and passphrase dismissal, then stopped at the existing pairing blocker.

testBridgeConnectLifecycleAndPromptContracts failed at BitkitUITests/TrezorBridgeDashboardUITests.swift:55: HwPairSheet never appeared. The emulator test root still mounts TrezorRootView directly, bypassing MainNavView, which owns the pairing presenter.

Pairing dismissal, confirmation cancellation, debug-log controls and disconnect/forget/reconnect were not reached. The complete case remains unrun.

prompts.2x.mp4

Bridge connection and prompt checks, recorded at 2× speed.

Test 2: Address, public key, message and transaction flow ⏭️ XCTest reproduced the existing text-replacement blocker before signature verification.

Address generation, funding, public-key export and signing completed. The assertion at BitkitUITests/TrezorBridgeDashboardUITests.swift:266 read Bitkit Trezor emulator testHello, Trezor! instead of Bitkit Trezor emulator test: clearAndType retained the prefilled suffix.

Valid/tampered signature verification, balance/history/detail, send/sign/broadcast and final log-redaction checks were not reached. The complete case remains unrun; this test-helper failure does not establish an app failure.

wallet.2x.mp4

Address generation through the verification-field assertion, recorded at 2× speed; the exact field value was checked by XCTest.

Test 3: Unavailable Bridge recovery ✅ Scanning an unavailable Bridge displayed the empty state.

testBridgeUnavailableShowsRecoverableState passed at this head, including the TrezorEmptyState assertion. I reran this case because the merge changes app code; no previous pass was carried forward.

recovery.2x.mp4

Unavailable Bridge and empty-state recovery, recorded at 2× speed.

Both incomplete cases stopped at the same acknowledged test blockers as before. No additional journeys or manual tests were listed.

Delta review of afda99d..d18b093: a contiguous merge of master, with no merge-resolution changes and no change to the PR's test file. I rechecked that file, the emulator root, prompt presenters and relevant merged Trezor code. The later lifecycle and transaction behavior listed above remains unverified.

Android twin: none linked or found; this change is specific to iOS XCTest.

Reviewer model: gpt-6.1-sol
Reasoning effort: high


Reviewed by gpt-6.1-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest

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