Skip to content

docs(ios-ui-tests): add Patterns and pitfalls section for terminate-after-navigation race#321

Merged
auerbachb merged 2 commits into
mainfrom
issue-320-ios-uitest-patterns-doc
May 1, 2026
Merged

docs(ios-ui-tests): add Patterns and pitfalls section for terminate-after-navigation race#321
auerbachb merged 2 commits into
mainfrom
issue-320-ios-uitest-patterns-doc

Conversation

@auerbachb
Copy link
Copy Markdown
Owner

@auerbachb auerbachb commented May 1, 2026

User description

Summary

Closes #320

Test plan

  • ios/StillPointAppUITests/README.md renders cleanly on GitHub (headings, code blocks, links)
  • All in-doc links resolve (PR fix(ios-e2e): wait for session root before terminate to avoid launchd race #319, run 25218186115, the helper file)
  • No code or product files changed (single-file docs-only diff)
  • CI lanes (ios-e2e-smoke, ios-e2e-critical, e2e-policy, build, web lanes) pass — should be a no-op for these since this PR doesn't change any test or product code

🤖 Generated with Claude Code


CodeAnt-AI Description

Add iOS UI test guidance for navigation timing races

What Changed

  • Added a new “Patterns and pitfalls” section to the iOS UI test README
  • Explains that terminating the app immediately after a navigation can hang the simulator with a “Failed to terminate” error
  • Recommends waiting for the destination screen to appear before terminating, with a do/don’t example
  • Clarifies when the tap-and-wait helper is safe to use and when it can miss a tap during a fresh transition
  • Links both the failing and passing CI runs for the navigation flow

Impact

✅ Fewer simulator terminate hangs
✅ Clearer iOS UI test guidance
✅ Fewer missed taps during fresh transitions

🔄 Retrigger CodeAnt AI Review

Details

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

…fter-navigation race

Documents the launchd race that PR #319 fixed: terminating right after
a navigating tap can hang the simulator with "Failed to terminate ... :0".
Records the canonical "direct .tap() + explicit waitForExistence on
root.currentView.<slug>" pattern, and explains when the existing
tap(_:thenWaitForRoot:in:) helper is appropriate vs when its
tapByStableCenter gating silently skips the tap.

Closes #320

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

CodeAnt AI is reviewing your PR.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
still-point Ignored Ignored Preview May 1, 2026 6:04pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Warning

Rate limit exceeded

@auerbachb has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 32 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b1a7bf6e-7d33-404f-9375-92a717b36cca

📥 Commits

Reviewing files that changed from the base of the PR and between 7cb8b7d and 811b19e.

📒 Files selected for processing (1)
  • ios/StillPointAppUITests/README.md
📝 Walkthrough

Walkthrough

This change adds documentation to the iOS UI tests README, detailing a race condition that occurs when calling app.terminate() immediately after navigation, and provides guidance on when to use direct .tap() with explicit destination-root waiting versus the tap(_:thenWaitForRoot:in:) helper method.

Changes

Cohort / File(s) Summary
iOS UI Test Documentation
ios/StillPointAppUITests/README.md
Added "Patterns and pitfalls" section documenting the launchd terminate-after-navigation race condition, the recommended pattern of direct .tap() followed by explicit waitForExistence() before termination, and the limitations of the tap(_:thenWaitForRoot:in:) helper when source element frames are unstable post-navigation.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • codeant-ai

Poem

🐰 A doc so clear, a pitfall caught—
Don't terminate when nav's been fought!
Wait for root, then safely close,
Future tests will reap what wisdom grows. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: adding a documentation section about the terminate-after-navigation race pattern to the iOS UI tests README.
Linked Issues check ✅ Passed The PR fully satisfies all coding-related objectives from issue #320: adds the 'Patterns and pitfalls' section documenting the race condition, provides do/don't code snippets, explains helper vs direct tap patterns, and includes relevant PR/run citations.
Out of Scope Changes check ✅ Passed The PR contains only documentation changes to ios/StillPointAppUITests/README.md; no code changes to test files or product code, fully aligned with stated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #320

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-320-ios-uitest-patterns-doc

Review rate limit: 0/5 reviews remaining, refill in 32 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label May 1, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

CodeAnt AI finished reviewing your PR.

@auerbachb
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

✅ Actions performed

Full review triggered.

@auerbachb
Copy link
Copy Markdown
Owner Author

@cursor review

@auerbachb
Copy link
Copy Markdown
Owner Author

@graphite-app re-review

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ios/StillPointAppUITests/README.md`:
- Around line 108-109: Update the README entry to include the passing CI run(s)
that verify the fix for commit ddf7b69 (or else reword to state only the failing
run is documented); specifically, for the concrete case mentioning the test
testLaunchLoginCompleteSessionAndHistoryPersistence and commits d9e69aa →
ddf7b69, add the URL(s) of the passing GitHub Actions run(s) that confirm the
fix (or change the sentence to note that only the failing run is shown) so the
acceptance criteria "failing/passing run IDs" are satisfied.
- Around line 76-100: Add language identifiers to the two unlabeled fenced code
blocks in the README: change the failure signature block containing "Failed to
terminate <bundle>:<pid>" to a text-fenced block (e.g., ```text) and mark the
"Don't do this" snippet that shows beginButton.tap() and
terminateAppReliably(app) as Swift (```swift); update the two fences only so the
failure signature and the code sample use explicit language tags to satisfy
markdownlint MD040.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2a585cae-d8c4-4c02-ac3e-866fc485ed30

📥 Commits

Reviewing files that changed from the base of the PR and between ddf7b69 and 7cb8b7d.

📒 Files selected for processing (1)
  • ios/StillPointAppUITests/README.md

Comment thread ios/StillPointAppUITests/README.md Outdated
Comment thread ios/StillPointAppUITests/README.md Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 7cb8b7d. Configure here.

- Add `text` language tag to the unlabeled fenced block showing the
  Failed-to-terminate output (markdownlint-friendly).
- Cite the passing CI run alongside the failing one to document both
  ends of the d9e69aaddf7b69 transition.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@auerbachb
Copy link
Copy Markdown
Owner Author

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 811b19e. Configure here.

@auerbachb auerbachb merged commit 07f01f9 into main May 1, 2026
16 checks passed
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 1, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

Sequence Diagram

This diagram illustrates the recommended pattern for navigating to a new screen before terminating the app in iOS UI tests, and contrasts it with the helper-based pattern that can silently skip the tap when the source view is still settling.

sequenceDiagram
    participant UITest
    participant App
    participant Simulator

    rect rgb(230, 255, 230)
    note over UITest,App: Recommended pattern
    UITest->>App: Tap navigation control
    App->>App: Navigate to destination screen
    UITest->>App: Wait for destination root element
    UITest->>Simulator: Call terminateAppReliably
    Simulator-->>UITest: App terminates without hang
    end

    rect rgb(255, 230, 230)
    note over UITest,App: Fragile helper pattern
    UITest->>App: Call tap thenWaitForRoot helper
    App->>App: tapByStableCenter sees unstable frame
    App-->>UITest: Tap skipped
    UITest->>App: Wait for destination root element
    App-->>UITest: Root never appears, assertion failure
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 1, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

Sequence Diagram

This PR documents a safe pattern for iOS UI tests that navigate to a new screen and then terminate the app, contrasting the recommended "tap, wait for destination root, then terminate" flow with the fragile pattern that terminates during an in-flight transition.

sequenceDiagram
    participant Test
    participant App
    participant Simulator

    Test->>App: Tap navigation button
    App->>App: Begin transition to destination screen

    alt Recommended pattern
        Test->>App: Wait for destination root element
        App-->>Test: Destination root is visible
        Test->>Simulator: Request app termination
        Simulator-->>Test: App terminates cleanly
    else Pitfall pattern
        Test->>Simulator: Request termination immediately
        Simulator-->>Test: Termination hangs and reports failure
    end

    Note over Test,App: Use tap and wait helper on stable screens; use direct tap plus explicit wait after recent transitions
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

A review was recently triggered for this PR. Please wait 42s before retriggering.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 8, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

Sequence Diagram

This PR documents the canonical pattern for iOS UI tests that navigate to a new screen and then terminate the app, emphasizing that tests should wait for the destination root view before calling terminate to avoid simulator termination hangs and clarifying when a tap then wait helper is appropriate.

sequenceDiagram
    participant UITest
    participant App

    UITest->>App: Tap navigation button
    UITest->>App: Wait for destination root view to exist
    UITest->>App: terminateAppReliably
    note over UITest,App: On already stable screens UITest may use tap then wait helper instead of direct tap plus explicit wait
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 9, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

Sequence Diagram

This PR documents safe patterns for tapping to navigate, waiting for the destination screen, and then terminating the app to avoid simulator hangs, and clarifies when a tap then wait helper can silently skip the tap and cause test failures.

sequenceDiagram
    participant UITest
    participant Helper
    participant App
    participant Simulator

    alt Already quiescent flow
        UITest->>Helper: tap then wait for root
        Helper->>App: Tap when element frame stable
        App-->>Helper: Destination root appears
        Helper-->>UITest: Root appeared
        UITest->>Simulator: terminateAppReliably
        Simulator-->>UITest: App terminated without hang
    else Right after a transition
        UITest->>App: Direct tap begin button
        UITest->>App: Wait for destination root element
        App-->>UITest: Destination root exists
        UITest->>Simulator: terminateAppReliably
        Simulator-->>UITest: App terminated without hang
    else Misuse helper after transition
        UITest->>Helper: tap then wait for root
        Helper->>App: Check element frame stability
        App-->>Helper: Frame unstable, skip tap
        Helper-->>UITest: Root never appears, assertion failure
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 10, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

Sequence Diagram

This diagram illustrates the recommended iOS UI test flow: waiting for the destination root view after a navigation tap before terminating the app to avoid simulator termination hangs. It also contrasts this with the racy pattern the new documentation warns against.

sequenceDiagram
    participant UITest
    participant App
    participant Simulator

    UITest->>App: Tap navigation control
    App->>App: Navigate to destination screen
    UITest->>App: Wait for destination root element
    UITest->>Simulator: Terminate app
    Simulator-->>UITest: Fast clean shutdown

    alt Racy terminate pattern
        UITest->>App: Tap navigation control
        UITest->>Simulator: Terminate app immediately
        Simulator-->>UITest: Delayed failure to terminate
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 10, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

Sequence Diagram

This PR documents the recommended flow for iOS UI tests that navigate and then terminate the app, to avoid simulator terminate hangs, and clarifies when a tap-and-wait helper is safe versus when a direct tap plus explicit wait is preferred.

sequenceDiagram
    participant UITest
    participant App
    participant Simulator

    UITest->>App: Tap button to navigate to next screen
    UITest->>App: Wait for destination root element to exist
    App-->>UITest: Destination root is visible and stable
    UITest->>Simulator: Terminate app reliably
    Simulator-->>UITest: Clean and timely termination

    Note over UITest,App: On already stable screens UITest may use a tap and wait helper; after fresh transitions use direct tap plus explicit wait
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 10, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

Sequence Diagram

This PR documents a safe pattern for iOS UI tests that navigate and then terminate the app, showing how explicit waiting for the destination root view avoids simulator terminate hangs and when the tap helper can silently skip a tap after fresh transitions.

sequenceDiagram
    participant UITest
    participant App
    participant Simulator

    UITest->>App: Tap navigation control
    App-->>UITest: Start transition to destination screen

    alt Direct tap with explicit wait
        UITest->>App: Wait for destination root element
        App-->>UITest: Destination root becomes visible
        UITest->>Simulator: Terminate app reliably
        Simulator-->>UITest: App terminates without hang
    else Tap helper after fresh transition
        UITest->>App: Call tap then wait helper
        App-->>UITest: Tap skipped due to unstable frame
        UITest->>Simulator: Terminate app while transition not complete
        Simulator-->>UITest: Terminate hang and error
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 10, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

Sequence Diagram

This PR documents the recommended flow for terminating the iOS app after navigation in UI tests and explains when a tap-and-wait helper can silently skip a tap on unstable views.

sequenceDiagram
    participant UITest
    participant Helper
    participant App
    participant Simulator

    UITest->>App: Tap navigation button
    App->>App: Navigate to destination screen
    UITest->>App: Wait for destination root element to exist
    UITest->>Simulator: Terminate app after destination is ready
    Simulator-->>UITest: App terminates cleanly

    UITest->>Helper: Call tap then wait helper on unstable element
    Helper->>App: Skip tap because frame is unstable
    Helper-->>UITest: Wait for destination root that never appears
    UITest-->>UITest: Assert failure about missing transition
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI finished running the review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(ios-ui-tests): document terminate-after-navigation race + when to use direct tap vs helper

1 participant