ReviewOS

also looking at this

craft-native/craft

test(mobile-e2e): prove iOS location settles, and that Zig served it

#213
Merged glennmichael123 wants to merge fix/ios-location-settles into main
6 files +157 -28
scripts/mobile-e2e/protocol.test.tsmodified+20-5
Changes to scripts/mobile-e2e/protocol.test.ts
@@ -1,7 +1,7 @@
11import { describe, expect, it } from 'bun:test'
22import { readFileSync } from 'node:fs'
33import { join } from 'node:path'
4import { ANDROID_DECLINE_PHRASES, androidDeclines, awaitedNeeds, DISMISS_SHARE_MENU, evaluateRun, hasTerminated, parseDriverOutput, REQUIRED_CASES, requiredCaseProblems, shareMenuInFront, ZIG_REFUSED_ACTIONS, ZIG_TESTED_ACTIONS, zigDispatchedActions, zigRefusals } from './protocol'
4import { ANDROID_DECLINE_PHRASES, androidDeclines, awaitedNeeds, DISMISS_SHARE_MENU, evaluateRun, hasTerminated, parseDriverOutput, REQUIRED_CASES, requiredCaseProblems, shareMenuInFront, ZIG_REFUSED_ACTIONS, ZIG_SERVED_ACTIONS, ZIG_TESTED_ACTIONS, zigDispatchedActions, zigHandBacks, zigRefusals } from './protocol'
55
66const ESC = String.fromCharCode(27)
77
@@ -138,7 +138,7 @@ describe('evaluateRun', () => {
138138 it('fails when the suite is hollowed out to the easy cases', () => {
139139 const verdict = evaluateRun('ios', iosTranscript({ cases: ['bridge.ready'] }))
140140 expect(verdict.ok).toBe(false)
141 expect(verdict.failures).toContain('required case geolocation.disabled.rejects is not in the suite the page ran')
141 expect(verdict.failures).toContain('required case share.disabled.rejects is not in the suite the page ran')
142142 expect(verdict.failures).toContain('required case clipboard.roundTrip is not in the suite the page ran')
143143 })
144144
@@ -270,11 +270,26 @@ describe('zig attribution', () => {
270270 })
271271
272272 it('reads the refusal Zig writes through its own capability gate', () => {
273 const text = 'info: ios: refusing share; enableShare is not enabled in craft.config.json'
274 expect(zigRefusals(text)).toEqual(ZIG_REFUSED_ACTIONS)
275 })
276
277 it('reads both ways Zig hands an action back to Swift', () => {
273278 const text = [
274 'info: ios: refusing share; enableShare is not enabled in craft.config.json',
275 'info: ios: refusing getCurrentPosition; enableGeolocation is not enabled in craft.config.json',
279 'info: craft-bridge dispatch t=mobile a=requestPermission i=9',
280 'info: ios: requestPermission is not served here; handing it back to the host',
281 `${ESC}[32minfo: ios: openSettings is declared unavailable; leaving it to the host${ESC}[0m`,
282 'info: craft-bridge dispatch t=mobile a=getCurrentPosition i=10',
276283 ].join('\n')
277 expect(zigRefusals(text)).toEqual(ZIG_REFUSED_ACTIONS)
284
285 expect(zigHandBacks(text)).toEqual(['openSettings', 'requestPermission'])
286 expect(zigHandBacks(iosTranscript())).toEqual([])
287 })
288
289 // The one deliberate hand-back. Swift owns location authorization, and
290 // listing it as served would fail every run for doing what it was designed to.
291 it('expects Zig to serve every tested action except the one it leaves to Swift', () => {
292 expect(ZIG_TESTED_ACTIONS.filter(action => !ZIG_SERVED_ACTIONS.includes(action))).toEqual(['requestPermission'])
278293 })
279294
280295 it('expects refusals only for actions the suite actually exercises', () => {