test: stop iPad UI tests flaking on dropped sidebar taps#19
Merged
Conversation
`goToSection` drove the iPad sidebar (a `NavigationSplitView`
`List(selection:)` row) with a single fire-and-forget tap and no
verification. Synthesized taps against a selection-driven sidebar row
are occasionally dropped before the app has quiesced (a periodic
`TimelineView` keeps it non-idle at launch), so the row never becomes
selected, the detail column stays on the previous section, and the
following content assertion fails — e.g.
`testAppListsEditableWithoutHardSession` timing out on `ruleCard-Sleep`.
iPhone is unaffected because it taps a tab-bar button instead.
Confirm the navigation landed before returning: each section's detail
names its navigation bar after the same label as the tab/row
(`navigationTitle("Rules")` -> `navigationBars["Rules"]`), so tap, wait
for that bar, and re-tap if it didn't appear. The iPhone tab-bar path is
unchanged; the happy path returns as soon as the bar appears.
Validated on iPad Pro 11-inch (M5): the previously-flaky test, both
NavigationChrome tests (all three sidebar paths), and a cross-class
batch of UI tests all pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WReTVa1zD6CHKRY8zqS9Pb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The iPad CI leg intermittently failed
AppListUITests.testAppListsEditableWithoutHardSessionwithExpected "ruleCard-Sleep" Button to exist within 5.0s. A screen recording of a failing run showed that, after thesidebarItem-rulestap, the sidebar still had Home selected and the detail column still showedHomeView— the rule list never rendered.Root cause
goToSectionnavigates differently per layout:MainTabView) taps a tab-bar button — a robust hit target, instant switch.MainSidebarView) taps aNavigationSplitViewList(selection:)sidebar row to drive the detail column.The iPad branch fired that sidebar tap once with no verification or retry. Synthesized taps against a selection-driven sidebar row are occasionally dropped before the app has quiesced (a periodic
TimelineViewkeeps it non-idle at launch — visible as the ~23s "wait for idle" in the failure log). When the tap is dropped, selection never changes, the detail stays on the previous section, and the next content assertion fails. Rare → flaky, and iPhone is unaffected.Fix
Verify the navigation actually landed before returning. Each section's detail names its navigation bar after the same label as the tab/row (
navigationTitle("Rules")→navigationBars["Rules"]), giving a device-agnostic post-condition. The iPad branch now taps, waits for that bar, and re-taps if it didn't appear (up to 5 attempts). The iPhone tab-bar path is unchanged; the happy path returns as soon as the bar appears.Test plan
All run on iPad Pro 11-inch (M5) — the CI device:
AppListUITests/testAppListsEditableWithoutHardSession(previously flaky) — passAppListUITests/testHardModeSessionLocksAppListEditing— passNavigationChromeUITests/testNavigationChromeMatchesIdiom+testEverySectionIsReachable(exercises all three sidebar paths) — passRuleCreation,RuleManagement,Settings,Usage,HardMode— 8/8 passgoToSection-using class, no regressionsFollow-up (not in this PR)
The ~23s launch "wait for idle" comes from the periodic
TimelineView(.periodic(by: 30))in Home/Rules never letting XCUITest detect quiescence — it slows the whole suite and is the underlying reason synthetic taps are racy here. Worth a separate look.🤖 Generated with Claude Code
https://claude.ai/code/session_01WReTVa1zD6CHKRY8zqS9Pb