11import XCTest
22
3- // The synthesized text-entry commit wait, end to end: the deadline that bounds it, the two waits
4- // that run it, the observation/pacing they poll through, and the value-free cadence line that path
5- // is allowed to log. Split from RunnerTests+SynthesizedTextEntry.swift, which keeps the
6- // private-XCTest synthesis boundary and the route policies; the pure outcome functions these wrap
7- // stay there next to the rules they encode. Everything that touches the polled field value now
8- // lives in this one file, which is the surface apple-runner-log-redaction.test.ts guards.
3+ // The synthesized replacement commit wait, end to end: the deadline that bounds it, the wait that
4+ // runs it, the observation/pacing it polls through, and the value-free cadence line that path is
5+ // allowed to log. RunnerTests+SynthesizedTextEntry.swift keeps the private-XCTest synthesis
6+ // boundary, the route policies, and the pure outcome function this wraps. Everything that touches
7+ // the polled field value lives in this one file, which is the surface
8+ // apple-runner-log-redaction.test.ts guards.
99extension RunnerTests {
1010 /// One commit wait's running deadline.
1111 ///
@@ -57,54 +57,17 @@ extension RunnerTests {
5757 }
5858 }
5959
60- /// Blocks until the synthesized bare-type text is observable in the target field, so `type`
61- /// cannot report ok while trailing characters are still uncommitted on a slow simulator.
62- ///
63- /// Observation only. A stalled prefix cannot be told apart from a suffix still queued in the
64- /// event stream, so re-synthesizing the difference risks committing it twice after the command
65- /// already reported success (#1676 rejected exactly that repair). Reporting `.notObserved` is
66- /// what the caller does instead: the partial value is the agent's to resolve, and a named
67- /// failure beats a success that misdescribes the field. Text carrying a submit key is skipped
68- /// outright: the app may clear or rewrite the field on submit, so `textBefore + typedText` is
69- /// not the value to wait for.
70- func awaitSynthesizedFirstResponderCommit (
71- app : XCUIApplication ,
72- target : TextEntryTarget ,
73- textBefore : String ? ,
74- typedText : String
75- ) -> SynthesizedTextCommitOutcome {
76- guard let textBefore , ! typedText . contains ( " \n " ) , ! typedText . contains ( " \r " ) else {
77- return . unobservable
78- }
79- let expectedText = textBefore + typedText
80- let waitStartedAt = Date ( )
81- NSLog ( " [DEBUG-1874] wait start expectedLen=%ld route=append " , expectedText . count )
82- let ingredients = synthesizedCommitPollingIngredients ( app : app , target : target , expectedText : expectedText )
83- let outcome = Self . awaitSynthesizedCommitOutcome (
84- expectedText : expectedText ,
85- placeholder : ingredients . placeholder ,
86- now : { Date ( ) } ,
87- observe : ingredients . observe ,
88- waitForNextObservation : ingredients . waitForNextObservation
89- )
90- NSLog (
91- " [DEBUG-1874] wait outcome=%@ elapsedMs=%.0f route=append " ,
92- String ( describing : outcome ) ,
93- waitStartedAt . timeIntervalSinceNow * - 1000
94- )
95- return outcome
96- }
97-
9860 /// Blocks until the synthesized replacement text (`fill`) is observable in the target field, so
9961 /// `fill` cannot report ok while the select-all-and-retype it posted is still uncommitted — or
10062 /// silently wrong — on a slow or channel-penalized simulator (this route runs only when the
101- /// XCTest channel is already penalized, and never resolves an `XCUIElement`, so it previously had
102- /// no verification at all).
63+ /// XCTest channel is already penalized, and never resolves an `XCUIElement`).
10364 ///
104- /// Unlike the append route, the expected value is the final text itself — replacement mode
105- /// clears the field first, so there is no `textBefore` prefix to account for — and unlike the
106- /// append route, a settled mismatch is always reported rather than trusted: see
107- /// `awaitSynthesizedReplacementCommitOutcome`'s doc comment.
65+ /// Observation only. A stalled prefix cannot be told apart from a suffix still queued in the
66+ /// event stream, so re-synthesizing the difference risks committing it twice after the command
67+ /// already reported success. The expected value is the
68+ /// final text itself, and a settled mismatch is always reported: see
69+ /// `awaitSynthesizedReplacementCommitOutcome`'s doc comment. Text carrying a submit key is
70+ /// skipped outright: the app may clear or rewrite the field on submit.
10871 func awaitSynthesizedReplacementCommit (
10972 app : XCUIApplication ,
11073 target : TextEntryTarget ,
@@ -160,16 +123,9 @@ extension RunnerTests {
160123 )
161124 }
162125
163- /// The placeholder/observe/pacing ingredients shared by the append route
164- /// (`awaitSynthesizedFirstResponderCommit`) and the replacement route
165- /// (`awaitSynthesizedReplacementCommit`). What must NOT be shared is which outcome function
166- /// consumes them: see `awaitSynthesizedReplacementCommitOutcome`'s doc comment for why append
167- /// mode's "trust a diverged value" rule is wrong for replacement mode. Each caller therefore
168- /// calls its own named outcome function directly, with real argument labels — deliberately not
169- /// a stored closure/function-value parameter here, which would erase those labels at the call
170- /// site and make the observe closure unrecognizable to the static content-redaction check in
171- /// `apple-runner-log-redaction.test.ts` (`extractObserveClosure` locates the labeled closure
172- /// literal by its text; a closure passed as a plain function value carries no such label).
126+ /// The placeholder/observe/pacing ingredients the commit wait polls through. The observe closure
127+ /// stays a labeled closure literal here: the static content-redaction check in
128+ /// `apple-runner-log-redaction.test.ts` (`extractObserveClosure`) locates it by that text.
173129 private func synthesizedCommitPollingIngredients (
174130 app : XCUIApplication ,
175131 target : TextEntryTarget ,
@@ -189,7 +145,7 @@ extension RunnerTests {
189145 treatingPlaceholderAsEmpty : true
190146 )
191147 // Cadence evidence stays value-free: the polled value is user content typed through
192- // `type`/` fill` and must never reach runner.log. Lengths and the expected-prefix walk
148+ // `fill` and must never reach runner.log. Lengths and the expected-prefix walk
193149 // are enough to distinguish throttling (prefix grows slowly) from a wedge (it freezes).
194150 Self . logCommitCadence (
195151 elapsedMs : Int ( waitStartedAt . timeIntervalSinceNow * - 1000 ) ,
0 commit comments