Skip to content

test(ios): wait for a key, foreground-active window before presenting in RunnerTests - #9275

Merged
matt2e merged 2 commits into
mainfrom
mtoohey/flake-ios-runner-tests
Nov 9, 2026
Merged

matt2e merged 2 commits into
mainfrom
mtoohey/flake-ios-runner-tests

Conversation

@matt2e

@matt2e matt2e commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Split out of the flakey-monday flake-fix series. Two iOS RunnerTests acted right after makeKeyAndVisible() 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 tests
  • test(mobile): wait for a foreground-active scene in the key-window helper

These 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 for parent.presentedViewController is UIDocumentPickerViewController, which never became true.

  • Root cause (inferred from the code paths and CI symptoms; not reproduced): 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, so pick() presented on a different window's controller and the expectation on parent could never be met. The community-entry test also attached its window to the first connected scene rather than the foreground-active one, swapped rootViewController and presented immediately; UIKit silently drops a presentation from a controller whose view is not yet in a window.
  • 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 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 the XCTUnwrap of 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 became async; 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-monday confirmed the keyWindowReady shape 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

matt2e and others added 2 commits November 9, 2026 15:41
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)
@matt2e
matt2e requested a review from a team as a code owner November 9, 2026 04:44
@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Nov 9, 2026
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Note: This is an automated, security-focused review generated by Codex.
Use it as a supplement to human review; false positives are possible.

Scope

  • Exact PR diff: 65e864301d2e51a93003816b45e77cae96be901f...01c224e68ff423b8e22e4fd74364c24dfa8f1b31
  • Model: gpt-6.1-sol

💡 Click "edited" above to see earlier reviews for this PR.


Review Summary

Overall Risk: NONE

The PR only changes iOS test window readiness and asynchronous presentation waits. No concrete security, correctness, or reliability regressions were found after tracing the affected tests and native presentation paths.

Findings

No concrete security, correctness, or reliability findings were identified.

Notes

  • Review used read-only inspection. Builds and tests were not executed, as requested.

Generated by Codex Security Review |
Requested by: @matt2e |
Workflow run

@kazemek21 kazemek21 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

@matt2e
matt2e merged commit ea548da into main Nov 9, 2026
53 checks passed
@matt2e
matt2e deleted the mtoohey/flake-ios-runner-tests branch November 9, 2026 21:39
wpfleger96 added a commit that referenced this pull request Nov 10, 2026
…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]>

This branch was previously deployed

1 inactive deployment
codex-review — 01c224e6 Deployed Nov 9, 2026 by matt2e via Run Codex Security Review #13952
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex-security-review-current The posted Codex security review matches its recorded range.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants