Repository navigation
test(ios): wait for a key, foreground-active window before presenting in RunnerTests - #9275
Conversation
Fixes two iOS RunnerTests flakes on main: - RunnerTests.testRejectedCommunityEntryPresentationCompletesAndAllowsRetry (RunnerTests.swift) timed out after 2 s waiting for "Temporary native modal appeared". - IdentityFilePluginTests.testPickerResolvesPresenterAtRequestAndCancelsExactlyOnce (IdentityFilePluginTests.swift) waited 5 s for `parent.presentedViewController is UIDocumentPickerViewController`, and it never became true. Root cause: both tests acted right after makeKeyAndVisible() and never established the state the code under test depends on. NativeCommunityEntryCoordinator and IdentityFilePlugin.pick() both resolve their presenter as the root of the isKeyWindow window in a .foregroundActive scene. makeKeyAndVisible() can return before key status moves to the new window. When that happens, pick() presents the picker on a different window's controller, and the expectation on `parent` can never be met. The community-entry test also attached its window to the first connected scene rather than the foreground-active one. It swapped rootViewController and presented immediately, and UIKit silently drops a presentation from a controller whose view is not yet in a window. That fits the missing completion. I could not reproduce either flake, because there is no Xcode or simulator on this Linux workstation. The cause is inferred from the code paths and the CI symptoms. Fix: a shared XCTestCase helper in RunnerTests.swift, internal so IdentityFilePluginTests can use it without changing the Xcode project. - keyWindow(showing:) attaches a window to the .foregroundActive scene, makes it key, and returns once a predicate expectation sees window.isKeyWindow and root's view in that window. - keyWindowReady(_:showing:) is that predicate. The community-entry test waits on it again after swapping the root, before presenting. Both tests now await these conditions, and the community-entry test became async to do so. Its fixed 2 s presentation wait became 5 s, the budget the picker test already uses. The new readiness waits are the fix; the longer timeout is not. Assertions are unchanged. Not run locally: Swift tests need Xcode and an iOS simulator, which this workstation lacks. iOS CI is the first place they run. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: mtoohey <[email protected]> (cherry picked from commit 285310fe9b6ec8fa0df7fb02f6cad301d8fcdae0)
…lper Follow-up to 285310fe9, from review. keyWindow(showing:) unwrapped the .foregroundActive scene with XCTUnwrap, so the first test to run could fail outright if its scene was still activating. That is the same launch race the helper exists to absorb for key status. Fix: wait for a foreground-active scene with the helper's existing pattern, an XCTNSPredicateExpectation awaited through fulfillment(of:timeout:) with the same 5 s budget, then unwrap it. The scene lookup moves into a small foregroundActiveScene() helper used by both the predicate and the unwrap. The tests themselves are unchanged. Not run locally: Swift tests need Xcode and an iOS simulator, which this Linux workstation lacks. The new code follows the shape of keyWindowReady, which review confirmed compiles. iOS CI is the first place it builds and runs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: mtoohey <[email protected]> (cherry picked from commit 01cd42939780abb16b8c7645217d5a14178c9333)
🔐 Codex Security Review
Review SummaryOverall Risk: NONE
FindingsNo concrete security, correctness, or reliability findings were identified. Notes
Generated by Codex Security Review | |
kazemek21
left a comment
There was a problem hiding this comment.
I reviewed the PR and the Nexus review-tracker notes. Approved with no comments.
Posted by Codex (gpt-6.1-sol) on behalf of kylez
…e-mode * origin/main: ci(docker): skip relay image publishes for main pushes outside the build context (#9310) Add manual-only relay image publishing (#9303) fix(mobile): bump Flutter to 3.47.9 for Android TLS fix (#9309) Serve video and poster previews for invite links (#9306) docs: point the README to Buzz 1.0 in block/buzz-app (#9296) fix(db): give the replica-fence probe its own pool and instrument it (#9297) fix(relay): never close connections when cross-node fan-out falls behind (#9302) test: fix timing-dependent unit tests in buzz-cli, buzz-agent and buzz-admin (#9273) fix(ci): classify hermit retry timeouts by watchdog kill, not whole seconds (#9274) test(ios): wait for a key, foreground-active window before presenting in RunnerTests (#9275) test(desktop): wait on real readiness signals in audience and community-rail specs (#9277) Signed-off-by: Will Pfleger <[email protected]>
Summary
Split out of the
flakey-mondayflake-fix series. Two iOS RunnerTests acted right aftermakeKeyAndVisible()without waiting for the window to become key in a foreground-active scene, which is the state the code under test resolves its presenter from. A shared test helper now waits for that state before the tests present anything.Commits (cherry-picked from
flakey-monday, original messages kept):test(mobile): wait for a key window before presenting in iOS teststest(mobile): wait for a foreground-active scene in the key-window helperThese Swift changes were NOT compiled or run locally. The fixes were written on a Linux workstation without Xcode or an iOS simulator, and this split branch was not built either. iOS CI on this PR is the first place they compile and run.
Root cause and fix per test
RunnerTests.testRejectedCommunityEntryPresentationCompletesAndAllowsRetry(mobile/ios/RunnerTests/RunnerTests.swift): timed out after 2 s waiting for "Temporary native modal appeared".IdentityFilePluginTests.testPickerResolvesPresenterAtRequestAndCancelsExactlyOnce(mobile/ios/RunnerTests/IdentityFilePluginTests.swift): waited 5 s forparent.presentedViewController is UIDocumentPickerViewController, which never became true.NativeCommunityEntryCoordinatorandIdentityFilePlugin.pick()both resolve their presenter as the root of theisKeyWindowwindow in a.foregroundActivescene.makeKeyAndVisible()can return before key status moves to the new window, sopick()presented on a different window's controller and the expectation onparentcould never be met. The community-entry test also attached its window to the first connected scene rather than the foreground-active one, swappedrootViewControllerand presented immediately; UIKit silently drops a presentation from a controller whose view is not yet in a window.XCTestCasehelper inRunnerTests.swift, internal soIdentityFilePluginTestscan use it without changing the Xcode project.keyWindow(showing:)attaches a window to the.foregroundActivescene, makes it key, and returns once a predicate expectation seeswindow.isKeyWindowand the root's view in that window.keyWindowReady(_:showing:)is that predicate; the community-entry test waits on it again after swapping the root. The follow-up commit replaces theXCTUnwrapof the foreground-active scene with the same predicate-expectation wait (5 s budget), since the first test to run could otherwise fail while its scene is still activating. The community-entry test becameasync; its fixed 2 s presentation wait became 5 s, the budget the picker test already uses. The readiness waits are the fix, not the longer timeout. Assertions are unchanged.Related issue
N/A (flake fixes; none found).
Testing
Human testing is still required. This PR does not carry
buzz-review-completed; the author has not yet run RunnerTests themselves on this branch.Verification
Not run locally at any point: Swift tests need Xcode and an iOS simulator, which the authoring workstation lacked, and nothing was built on this split branch either (the workstation was overloaded, so no tests, builds or linters were executed after cherry-picking). The review pass on
flakey-mondayconfirmed thekeyWindowReadyshape compiles; the follow-up follows that same shape. iOS CI on this PR is the verification for both the fix and the split branch.🤖 Generated with Claude Code