also looking at this
test(mobile-e2e): prove iOS location settles, and that Zig served it
#213
6 files
+157
-28
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | import { describe, expect, it } from 'bun:test' |
| 2 | 2 | import { readFileSync } from 'node:fs' |
| 3 | 3 | import { join } from 'node:path' |
| 4 | import { 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' | |
| 4 | import { 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' | |
| 5 | 5 | |
| 6 | 6 | const ESC = String.fromCharCode(27) |
| 7 | 7 | |
| @@ -138,7 +138,7 @@ describe('evaluateRun', () => { | ||
| 138 | 138 | it('fails when the suite is hollowed out to the easy cases', () => { |
| 139 | 139 | const verdict = evaluateRun('ios', iosTranscript({ cases: ['bridge.ready'] })) |
| 140 | 140 | 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') | |
| 142 | 142 | expect(verdict.failures).toContain('required case clipboard.roundTrip is not in the suite the page ran') |
| 143 | 143 | }) |
| 144 | 144 | |
| @@ -270,11 +270,26 @@ describe('zig attribution', () => { | ||
| 270 | 270 | }) |
| 271 | 271 | |
| 272 | 272 | 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', () => { | |
| 273 | 278 | 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', | |
| 276 | 283 | ].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']) | |
| 278 | 293 | }) |
| 279 | 294 | |
| 280 | 295 | it('expects refusals only for actions the suite actually exercises', () => { |