Skip to content

fix: speed up iOS text entry#1139

Merged
thymikee merged 2 commits into
mainfrom
fix/ios-fill-type-perf
Jul 7, 2026
Merged

fix: speed up iOS text entry#1139
thymikee merged 2 commits into
mainfrom
fix/ios-fill-type-perf

Conversation

@thymikee

@thymikee thymikee commented Jul 7, 2026

Copy link
Copy Markdown
Member

Summary

Fixes #1108 by removing unnecessary iOS text-entry waits while preserving the existing “type first letter, wait, then type the rest” behavior for reliable search fields.

Changes:

  • add runner-side AGENT_DEVICE_RUNNER_TEXT_ENTRY_PHASE markers around focus, clear, type, warmup, verify, and total phases
  • stop paying a second readiness wait after keyboard-visible focus has already been confirmed
  • for concrete text targets, use XCUIElement.typeText so visible-keyboard refills stay scoped to the tapped field without a full focus timeout
  • verify once on the normal success path and repair only after an observed mismatch

Measurements

Median wall-clock samples from iOS simulator runs:

Scenario Before After Notes
Settings search fill, no settle 5890ms 2830ms Removed duplicate post-focus wait and duplicate verify/repair.
Settings search fill, final settle comparison 3102ms no-settle 3973ms settle Settle adds about 0.9s of stabilization.
Bluesky search replacement, no settle 5998ms 3594ms Focus phase dropped from about 3.0s to about 0.57s; remaining large cost is clear-field work.
Bluesky search replacement, settle 6879ms 4523ms Settle adds about 0.85s.
Bluesky empty search fill, no settle n/a 2098ms Runner phases are about 0.6s focus plus 1.18s type/verify.

Rejected experiments:

  • private XCTest bulk typing selector: unavailable on Xcode 26.2, so the fast path never fired
  • immediate hidden-keyboard target return: failed the Settings test bed, so it was not kept

Validation

  • pnpm build:xcuitest
  • git diff --check
  • pnpm test-app:maestro:ios --close -- --udid C25DBB5B-9254-4293-A8D5-2785C78DE03A --state-dir /private/tmp/agent-device-test-app-maestro --artifacts-dir .tmp/issue-1108/maestro-ios --timeout 180000
    • The Checkout form Maestro flow passed in 22.8s.
    • The wrapper then exited non-zero only because its optional --close cleanup does not forward the custom state dir.

Follow-up note: repeated clean reruns of the stock Expo dev-client Maestro flow later hit test-app environment issues outside this text-entry path: launchApp clearState returned to the Expo dev launcher unless the runtime state was warm, and simctl get_app_container ... data eventually returned a missing simulator data-container path.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 1.6 MB 1.6 MB 0 B
JS gzip 500.0 kB 500.0 kB 0 B
npm tarball 596.9 kB 597.8 kB +898 B
npm unpacked 2.1 MB 2.1 MB +5.1 kB

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 25.9 ms 25.9 ms -0.0 ms
CLI --help 52.5 ms 52.3 ms -0.2 ms

Top changed chunks: no changes in the largest emitted chunks.

@thymikee thymikee left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reviewed the iOS text-entry speedup. The phase-marker logging, the keyboard-visible fast paths, and the switch to XCUIElement.typeText for concrete targets all look reasonable. One correctness concern on the verify/repair refactor — left it inline.


Generated by Claude Code

@thymikee

thymikee commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

Reviewed #1139 at head f862f5f against #1108. No actionable blockers found.

Checked:

  • Scope is limited to the Swift runner text-entry path: RunnerTests+TextEntry.swift and focus/timing logging in RunnerTests+CommandExecution.swift.
  • The duplicate post-focus readiness wait is removed only after a concrete target is tapped or after keyboard visibility already proves a bare first-responder path.
  • Concrete-target typing now uses XCUIElement.typeText, while bare type still falls back to app.typeText when there is no resolved target.
  • Replacement semantics still require a resolved target, keep clear-first behavior, retain first-character warmup, and verify with the existing stability window.
  • Repair now happens only after an observed mismatch, then re-verifies the repaired value through the resolved element.
  • No command-surface, daemon routing, interaction guarantee, or gesture/tap synthesis paths changed.
  • CI is green across 21 checks after rerunning the transient Linux artifact-upload failure.

Residual risk: I did not rerun the simulator benchmark locally in this coordinator worktree; I am relying on the PR-provided Settings/Bluesky/test-app evidence plus green CI for maintainer judgment.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Jul 7, 2026
@thymikee thymikee merged commit b052eb9 into main Jul 7, 2026
21 checks passed
@thymikee thymikee deleted the fix/ios-fill-type-perf branch July 7, 2026 07:50
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-07-07 07:50 UTC

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

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(ios): fill/type runs at ~700ms per character on simulator

1 participant