refactor(ios): share one private-XCTest event bridge between gesture and text synthesis - #1608
Conversation
Size Report
Startup median (7 runs, lower is better):
Top changed chunks: no changes in the largest emitted chunks. |
|
Reviewed exact head One readiness requirement remains: current executed tests do not invoke the non-stubbed bridge. Before undrafting/labeling, please add exact-head simulator evidence for one synthesized coordinate tap and one private synthesized text-entry operation, followed by another command confirming runner usability. |
ba6be17 to
8b7febb
Compare
…and text synthesis RunnerSynthesizedGesture.m and RunnerSynthesizedTextEntry.m each independently reflected into XCSynthesizedEventRecord/XCPointerEventPath. Extract the common resolution (classes, addPointerEventPath:/setTargetProcessID:/ synthesizeWithError:/processID, the RunnerRequireClass/Selector/ ApplicationSelector checks, the shared objc_msgSend typedefs, and the "name: reason" exception formatter) into RunnerXCTestEventBridge.h/.m. Each caller resolves its own extras on top of the shared core: gesture resolves the 2-arg initWithName:interfaceOrientation: plus touch-path selectors, text entry resolves the 1-arg initWithName: plus text-input selectors.
8b7febb to
0dfe07a
Compare
1. Rebased onto current
|
|
Undrafting at
🤖 Addressed by Claude Code |
|
Re-reviewed exact head The conflict resolution preserves #1616’s lifecycle helpers and tap signature, while the reflected private-XCTest surface remains exactly the same 15 symbols as This head is ready for human merge review. |
|
Summary
RunnerSynthesizedGesture.mandRunnerSynthesizedTextEntry.m(added in #1588) each independently reflected into the same private XCTest event-synthesis API (XCSynthesizedEventRecord/XCPointerEventPath). A selector rename in that private surface had to be found and fixed in two files with two different failure shapes. This PR extracts the duplicated resolution into a sharedRunnerXCTestEventBridge.h/.m.Unified into the shared bridge:
RunnerXCTestEventBridgestruct holding the common core:recordClass/pathClass,addPointerEventPath:,setTargetProcessID:,synthesizeWithError:, andprocessID.RunnerResolveXCTestEventBridge, which resolves and validates that core against the live XCTest runtime.RunnerRequireClass/RunnerRequireSelector/RunnerRequireApplicationSelector— now take asurfaceparameter ("event"or"text") so each caller's existing message wording ("private XCTest event synthesis unavailable: ..." vs "private XCTest text synthesis unavailable: ...") is preserved byte-for-byte instead of being forced to one wording.RunnerMsgSend*objc_msgSend typedefs both callers use (RunnerMsgSendInteger,RunnerMsgSendSetInteger,RunnerMsgSendAddPath,RunnerMsgSendSynthesize).RunnerFormatXCTestException, the@catch (NSException *)→"name: reason"formatter that was byte-identical in both files.Deliberately kept per-caller (not force-unified):
initWithName:interfaceOrientation:(plusinterfaceOrientationand the touch-path selectorsinitForTouchAtPoint:offset:/moveToPoint:atOffset:/liftUpAtOffset:); text entry uses the 1-arginitWithName:(plus the text-input selectorsinitForTextInput/typeText:atOffset:typingSpeed:shouldRedact:/typeKey:modifiers:atOffset:, the last only required inreplacemode). These are genuinely different selectors, not a naming coincidence, so each file resolves its own extension of the shared core (RunnerGestureEventBridge/RunnerTextEventBridge, each embeddingRunnerXCTestEventBridge core).RunnerSynthesizedGesturestill returns a nullableNSString *message;RunnerSynthesizedTextEntrystill returns aRunnerSynthesizedTextEntryResultwith a status enum. Swift-visible signatures are unchanged, soAgentDeviceRunnerUITests-Bridging-Header.hdid not need a change.Pure deduplication — no behavior change. Net: +318/-202 across the 4 touched files (2 new, 2 edited).
Validation
pnpm typecheck,pnpm lint,pnpm format:check: all clean (no TS files touched).pnpm exec vitest run src/__tests__/apple-runner-package-source.test.ts: 5/5 passing — the new.h/.mfiles are picked up automatically by the packaging script's directory walk (no manifest to update).pnpm test:unit: 610 files / 5382 tests passing.objc_msgSendrefactor, so this is the load-bearing gate): built both shared targets locally with a real Xcode toolchain (Xcode 26.2) since this changes code shared between iOS and macOS perdocs/agents/testing.md:pnpm build:xcuitest:macos->** TEST BUILD SUCCEEDED **, clang compiledRunnerXCTestEventBridge.m,RunnerSynthesizedGesture.m, andRunnerSynthesizedTextEntry.mwith zero errors/warnings.pnpm build:xcuitest:ios(iphonesimulator destination) ->** TEST BUILD SUCCEEDED **, same three files compiled cleanly.pnpm check:affected --run: selects only the GitHub-authoritativeswift-runnercheck (already covered by the local builds above); reports "all runnable checks passed."PBXFileSystemSynchronizedRootGroupfor this test target, so the new files needed noproject.pbxprojedit — they were picked up automatically by both the local builds and bycheck:affected's file-based classification.Follow-up (optional, out of scope)
Unify
RunnerSynthesizedGesture's nullable-message-string error shape withRunnerSynthesizedTextEntry's status-enum shape, if a future caller needs to distinguish "unavailable" from "failed" for gestures the way text entry already can.