@delacour/warden-e2e 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/{chunk-yb1hcjqm.mjs → chunk-vs5npy59.mjs} +3370 -218
  2. package/index.mjs +247 -16
  3. package/package.json +2 -2
  4. package/preload.mjs +8264 -2387
  5. package/types/core/src/a11y/a11y.config.d.ts +47 -0
  6. package/types/core/src/affected/affected.schema.d.ts +142 -1
  7. package/types/core/src/allocate.d.ts +2 -1
  8. package/types/core/src/android-keyguard.d.ts +36 -0
  9. package/types/core/src/batch/preset.schema.d.ts +13 -1
  10. package/types/core/src/biometrics.d.ts +15 -0
  11. package/types/core/src/builds/app-option.schema.d.ts +1 -1
  12. package/types/core/src/builds/builds.defaults.d.ts +15 -0
  13. package/types/core/src/builds/config.d.ts +5 -1
  14. package/types/core/src/builds/config.schema.d.ts +275 -2
  15. package/types/core/src/builds/define-config.d.ts +159 -0
  16. package/types/core/src/builds/install-device.d.ts +37 -0
  17. package/types/core/src/builds/install.d.ts +17 -3
  18. package/types/core/src/builds/kinds.d.ts +21 -3
  19. package/types/core/src/builds/lock.d.ts +38 -0
  20. package/types/core/src/builds/resolve.d.ts +12 -2
  21. package/types/core/src/camera-mode.d.ts +17 -0
  22. package/types/core/src/camera-placeholder.d.ts +9 -0
  23. package/types/core/src/camera-profile.d.ts +12 -0
  24. package/types/core/src/claim-errors.d.ts +34 -0
  25. package/types/core/src/conditions/a11y-keys.d.ts +45 -0
  26. package/types/core/src/conditions/camera-media.d.ts +30 -0
  27. package/types/core/src/conditions/conditions.config.d.ts +141 -0
  28. package/types/core/src/conditions/conditions.d.ts +22 -0
  29. package/types/core/src/conditions/conditions.types.d.ts +171 -0
  30. package/types/core/src/conditions/inject-state.d.ts +13 -0
  31. package/types/core/src/conditions/launch-settings.d.ts +14 -0
  32. package/types/core/src/conditions/network.presets.d.ts +42 -0
  33. package/types/core/src/conditions/text-size.d.ts +19 -0
  34. package/types/core/src/golden/android-biometrics.d.ts +35 -0
  35. package/types/core/src/ios-runner/build.d.ts +28 -0
  36. package/types/core/src/ios-runner/cache.d.ts +44 -0
  37. package/types/core/src/ios-runner/classify.d.ts +7 -0
  38. package/types/core/src/ios-runner/pack.d.ts +17 -0
  39. package/types/core/src/ios-runner/runner-build.types.d.ts +76 -0
  40. package/types/core/src/ios-runner/signing.d.ts +40 -0
  41. package/types/core/src/ios-runner/sim-build.d.ts +36 -0
  42. package/types/core/src/ios-runner/stage.d.ts +26 -0
  43. package/types/core/src/lease-events.d.ts +126 -0
  44. package/types/core/src/netproxy/control.d.ts +75 -0
  45. package/types/core/src/netproxy/decide.d.ts +22 -0
  46. package/types/core/src/netproxy/handle-file.d.ts +12 -0
  47. package/types/core/src/netproxy/lease-proxy.d.ts +53 -0
  48. package/types/core/src/netproxy/netproxy.main.d.ts +40 -0
  49. package/types/core/src/netproxy/pipe.d.ts +37 -0
  50. package/types/core/src/netproxy/proxy.d.ts +48 -0
  51. package/types/core/src/netproxy/shaping.d.ts +43 -0
  52. package/types/core/src/ownership.d.ts +44 -0
  53. package/types/core/src/providers/android.d.ts +46 -2
  54. package/types/core/src/providers/provider.types.d.ts +9 -0
  55. package/types/core/src/queue.d.ts +43 -0
  56. package/types/core/src/store.d.ts +61 -5
  57. package/types/core/src/types.d.ts +57 -0
  58. package/types/core/src/xcode.d.ts +22 -0
  59. package/types/e2e/src/a11y/a11y-target.d.ts +23 -0
  60. package/types/e2e/src/a11y/a11y.types.d.ts +81 -0
  61. package/types/e2e/src/a11y/announcements.d.ts +24 -0
  62. package/types/e2e/src/a11y/audit.d.ts +22 -0
  63. package/types/e2e/src/a11y/native/atf.d.ts +51 -0
  64. package/types/e2e/src/a11y/native/xcuitest.d.ts +60 -0
  65. package/types/e2e/src/a11y/order.d.ts +5 -0
  66. package/types/e2e/src/a11y/rules/duplicate-name.d.ts +6 -0
  67. package/types/e2e/src/a11y/rules/hidden-focusable.d.ts +3 -0
  68. package/types/e2e/src/a11y/rules/image-no-name.d.ts +6 -0
  69. package/types/e2e/src/a11y/rules/label-in-name.d.ts +7 -0
  70. package/types/e2e/src/a11y/rules/missing-name.d.ts +3 -0
  71. package/types/e2e/src/a11y/rules/role-in-name.d.ts +3 -0
  72. package/types/e2e/src/a11y/rules/rule.context.d.ts +22 -0
  73. package/types/e2e/src/a11y/rules/target-size.d.ts +21 -0
  74. package/types/e2e/src/a11y/rules/text-clipped.d.ts +9 -0
  75. package/types/e2e/src/a11y/speech.d.ts +26 -0
  76. package/types/e2e/src/a11y/talkback-log.d.ts +13 -0
  77. package/types/e2e/src/alert-buttons.d.ts +9 -0
  78. package/types/e2e/src/app.d.ts +3 -2
  79. package/types/e2e/src/conditions/condition-events.d.ts +68 -0
  80. package/types/e2e/src/conditions/device-conditions.d.ts +198 -0
  81. package/types/e2e/src/conditions/geo.d.ts +15 -0
  82. package/types/e2e/src/conditions/gpx.d.ts +8 -0
  83. package/types/e2e/src/conditions/lease-recorder.d.ts +27 -0
  84. package/types/e2e/src/conditions/lease-store.d.ts +9 -0
  85. package/types/e2e/src/conditions/location-plan.d.ts +17 -0
  86. package/types/e2e/src/conditions/location-scenarios.data.d.ts +17 -0
  87. package/types/e2e/src/conditions/route-ticker.d.ts +53 -0
  88. package/types/e2e/src/conditions/scheduler.d.ts +83 -0
  89. package/types/e2e/src/device-a11y.d.ts +97 -0
  90. package/types/e2e/src/device.d.ts +67 -4
  91. package/types/e2e/src/driver/a11y-events.d.ts +30 -0
  92. package/types/e2e/src/driver/a11y-read.d.ts +12 -0
  93. package/types/e2e/src/driver/android/android-animations.d.ts +7 -0
  94. package/types/e2e/src/driver/android/android-app.d.ts +4 -0
  95. package/types/e2e/src/driver/android/android-argv.d.ts +21 -0
  96. package/types/e2e/src/driver/android/android-camera-host.d.ts +23 -0
  97. package/types/e2e/src/driver/android/android-camera.d.ts +28 -0
  98. package/types/e2e/src/driver/android/android-clock.d.ts +28 -0
  99. package/types/e2e/src/driver/android/android-device.d.ts +8 -0
  100. package/types/e2e/src/driver/android/android-driver.d.ts +22 -0
  101. package/types/e2e/src/driver/android/android-network.d.ts +66 -0
  102. package/types/e2e/src/driver/android/android-phone.d.ts +47 -0
  103. package/types/e2e/src/driver/android/android-screen-reader.d.ts +23 -0
  104. package/types/e2e/src/driver/android/android-settings.d.ts +41 -0
  105. package/types/e2e/src/driver/android/android-spoken.d.ts +18 -0
  106. package/types/e2e/src/driver/android/android-state.d.ts +10 -0
  107. package/types/e2e/src/driver/android/android-talkback.d.ts +57 -0
  108. package/types/e2e/src/driver/android/atf-device.d.ts +23 -0
  109. package/types/e2e/src/driver/android/atf-dex.generated.d.ts +7 -0
  110. package/types/e2e/src/driver/android/uiad-dex.generated.d.ts +5 -5
  111. package/types/e2e/src/driver/android/uiad-ops.d.ts +27 -1
  112. package/types/e2e/src/driver/android/uiad-protocol.d.ts +8 -0
  113. package/types/e2e/src/driver/android/uiad-screen-reader.d.ts +33 -0
  114. package/types/e2e/src/driver/clock-recorder.d.ts +9 -0
  115. package/types/e2e/src/driver/device-settings.d.ts +10 -0
  116. package/types/e2e/src/driver/driver.types.d.ts +242 -1
  117. package/types/e2e/src/driver/element-actions.d.ts +16 -0
  118. package/types/e2e/src/driver/ios/device/capabilities.d.ts +3 -0
  119. package/types/e2e/src/driver/ios/device/device-driver.d.ts +49 -0
  120. package/types/e2e/src/driver/ios/device/devicectl.d.ts +38 -0
  121. package/types/e2e/src/driver/ios/device/runner-protocol.d.ts +21 -0
  122. package/types/e2e/src/driver/ios/hid-recovery.d.ts +15 -0
  123. package/types/e2e/src/driver/ios/inject.d.ts +124 -0
  124. package/types/e2e/src/driver/ios/ios-a11y.d.ts +73 -0
  125. package/types/e2e/src/driver/ios/ios-audit.d.ts +36 -0
  126. package/types/e2e/src/driver/ios/ios-driver.d.ts +50 -1
  127. package/types/e2e/src/driver/ios/ios-network.d.ts +51 -0
  128. package/types/e2e/src/driver/ios/ios-settings.d.ts +44 -0
  129. package/types/e2e/src/driver/ios/sim-runner.d.ts +41 -0
  130. package/types/e2e/src/driver/ios/simctl.d.ts +41 -1
  131. package/types/e2e/src/driver/ios/simd-transport.d.ts +11 -2
  132. package/types/e2e/src/driver/ios/type-budget.d.ts +6 -1
  133. package/types/e2e/src/driver/native-audit.d.ts +26 -0
  134. package/types/e2e/src/driver/network-proxy.d.ts +52 -0
  135. package/types/e2e/src/driver/open.d.ts +20 -0
  136. package/types/e2e/src/driver/physical-conditions.d.ts +11 -0
  137. package/types/e2e/src/driver/requirements.d.ts +14 -0
  138. package/types/e2e/src/driver/screen-reader.d.ts +26 -0
  139. package/types/e2e/src/driver/typing.d.ts +1 -1
  140. package/types/e2e/src/env.d.ts +47 -0
  141. package/types/e2e/src/expect/a11y-matchers.d.ts +33 -0
  142. package/types/e2e/src/expect/expect.d.ts +7 -2
  143. package/types/e2e/src/expect/matchers.d.ts +14 -0
  144. package/types/e2e/src/fixture-session.d.ts +4 -0
  145. package/types/e2e/src/fixtures.d.ts +6 -1
  146. package/types/e2e/src/index.d.ts +6 -0
  147. package/types/e2e/src/runner/callsite.d.ts +3 -1
  148. package/types/e2e/src/runner/scope.d.ts +1 -0
  149. package/types/e2e/src/runner/test.d.ts +6 -0
  150. package/types/e2e/src/screen/render.d.ts +8 -0
  151. package/types/e2e/src/traced-device.d.ts +2 -1
@@ -114,6 +114,11 @@ export declare const projectConfigSchema: z.ZodObject<{
114
114
  jsInputs: z.ZodOptional<z.ZodArray<z.ZodString>>;
115
115
  }, z.core.$strict>>;
116
116
  }, z.core.$strict>>;
117
+ ios: z.ZodOptional<z.ZodObject<{
118
+ device: z.ZodOptional<z.ZodObject<{
119
+ bundleIdentifier: z.ZodOptional<z.ZodString>;
120
+ }, z.core.$strict>>;
121
+ }, z.core.$strict>>;
117
122
  cacheDirs: z.ZodOptional<z.ZodArray<z.ZodString>>;
118
123
  }, z.core.$strict>;
119
124
  export declare const wardenConfigSchema: z.ZodObject<{
@@ -202,6 +207,11 @@ export declare const wardenConfigSchema: z.ZodObject<{
202
207
  jsInputs: z.ZodOptional<z.ZodArray<z.ZodString>>;
203
208
  }, z.core.$strict>>;
204
209
  }, z.core.$strict>>;
210
+ ios: z.ZodOptional<z.ZodObject<{
211
+ device: z.ZodOptional<z.ZodObject<{
212
+ bundleIdentifier: z.ZodOptional<z.ZodString>;
213
+ }, z.core.$strict>>;
214
+ }, z.core.$strict>>;
205
215
  cacheDirs: z.ZodOptional<z.ZodArray<z.ZodString>>;
206
216
  }, z.core.$strict>>>;
207
217
  batches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -228,8 +238,8 @@ export declare const wardenConfigSchema: z.ZodObject<{
228
238
  variant: z.ZodOptional<z.ZodString>;
229
239
  kind: z.ZodOptional<z.ZodEnum<{
230
240
  release: "release";
231
- dev: "dev";
232
241
  simulator: "simulator";
242
+ dev: "dev";
233
243
  }>>;
234
244
  }, z.core.$strict>]>>;
235
245
  headless: z.ZodOptional<z.ZodBoolean>;
@@ -237,6 +247,12 @@ export declare const wardenConfigSchema: z.ZodObject<{
237
247
  except: z.ZodOptional<z.ZodArray<z.ZodString>>;
238
248
  keep: z.ZodOptional<z.ZodArray<z.ZodString>>;
239
249
  }, z.core.$strict>]>>;
250
+ biometrics: z.ZodOptional<z.ZodBoolean>;
251
+ reclaim: z.ZodOptional<z.ZodEnum<{
252
+ none: "none";
253
+ uninstall: "uninstall";
254
+ erase: "erase";
255
+ }>>;
240
256
  retry: z.ZodOptional<z.ZodNumber>;
241
257
  passes: z.ZodOptional<z.ZodNumber>;
242
258
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
@@ -275,6 +291,9 @@ export declare const wardenConfigSchema: z.ZodObject<{
275
291
  count: z.ZodDefault<z.ZodNumber>;
276
292
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
277
293
  default: z.ZodDefault<z.ZodBoolean>;
294
+ physical: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodObject<{
295
+ ids: z.ZodArray<z.ZodString>;
296
+ }, z.core.$strict>]>>;
278
297
  }, z.core.$strict>>>;
279
298
  metro: z.ZodOptional<z.ZodObject<{
280
299
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -291,6 +310,9 @@ export declare const wardenConfigSchema: z.ZodObject<{
291
310
  ios: "ios";
292
311
  android: "android";
293
312
  }>>;
313
+ physical: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodObject<{
314
+ ids: z.ZodArray<z.ZodString>;
315
+ }, z.core.$strict>]>>;
294
316
  base: z.ZodDefault<z.ZodString>;
295
317
  maxDepth: z.ZodOptional<z.ZodNumber>;
296
318
  runAll: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -321,8 +343,8 @@ export declare const wardenConfigSchema: z.ZodObject<{
321
343
  variant: z.ZodOptional<z.ZodString>;
322
344
  kind: z.ZodOptional<z.ZodEnum<{
323
345
  release: "release";
324
- dev: "dev";
325
346
  simulator: "simulator";
347
+ dev: "dev";
326
348
  }>>;
327
349
  }, z.core.$strict>]>>;
328
350
  ports: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -335,6 +357,12 @@ export declare const wardenConfigSchema: z.ZodObject<{
335
357
  except: z.ZodOptional<z.ZodArray<z.ZodString>>;
336
358
  keep: z.ZodOptional<z.ZodArray<z.ZodString>>;
337
359
  }, z.core.$strict>]>>;
360
+ biometrics: z.ZodOptional<z.ZodBoolean>;
361
+ reclaim: z.ZodOptional<z.ZodEnum<{
362
+ none: "none";
363
+ uninstall: "uninstall";
364
+ erase: "erase";
365
+ }>>;
338
366
  warmRunners: z.ZodOptional<z.ZodUndefined>;
339
367
  warmDrivers: z.ZodOptional<z.ZodBoolean>;
340
368
  headless: z.ZodOptional<z.ZodBoolean>;
@@ -347,6 +375,127 @@ export declare const wardenConfigSchema: z.ZodObject<{
347
375
  peakMemoryMb: z.ZodOptional<z.ZodNumber>;
348
376
  }, z.core.$strict>>;
349
377
  }, z.core.$strict>>;
378
+ conditions: z.ZodOptional<z.ZodObject<{
379
+ network: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
380
+ edge: "edge";
381
+ "3g": "3g";
382
+ "4g": "4g";
383
+ lte: "lte";
384
+ wifi: "wifi";
385
+ slow: "slow";
386
+ lossy: "lossy";
387
+ online: "online";
388
+ offline: "offline";
389
+ }>, z.ZodObject<{
390
+ latencyMs: z.ZodOptional<z.ZodNumber>;
391
+ jitterMs: z.ZodOptional<z.ZodNumber>;
392
+ downKbps: z.ZodOptional<z.ZodNumber>;
393
+ upKbps: z.ZodOptional<z.ZodNumber>;
394
+ lossPct: z.ZodOptional<z.ZodNumber>;
395
+ }, z.core.$strict>]>>;
396
+ location: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
397
+ "city-run": "city-run";
398
+ "city-bike": "city-bike";
399
+ freeway: "freeway";
400
+ }>, z.ZodObject<{
401
+ lat: z.ZodNumber;
402
+ lon: z.ZodNumber;
403
+ altM: z.ZodOptional<z.ZodNumber>;
404
+ }, z.core.$strict>]>>;
405
+ clock: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
406
+ at: z.ZodString;
407
+ frozen: z.ZodOptional<z.ZodBoolean>;
408
+ }, z.core.$strict>, z.ZodObject<{
409
+ offset: z.ZodString;
410
+ }, z.core.$strict>]>>;
411
+ permissions: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
412
+ location: "location";
413
+ locationAlways: "locationAlways";
414
+ camera: "camera";
415
+ photos: "photos";
416
+ photosAdd: "photosAdd";
417
+ contacts: "contacts";
418
+ contactsLimited: "contactsLimited";
419
+ notifications: "notifications";
420
+ microphone: "microphone";
421
+ calendar: "calendar";
422
+ reminders: "reminders";
423
+ motion: "motion";
424
+ mediaLibrary: "mediaLibrary";
425
+ siri: "siri";
426
+ }> & z.core.$partial, z.ZodEnum<{
427
+ granted: "granted";
428
+ denied: "denied";
429
+ unset: "unset";
430
+ }>>>;
431
+ locale: z.ZodOptional<z.ZodString>;
432
+ timezone: z.ZodOptional<z.ZodString>;
433
+ a11y: z.ZodOptional<z.ZodObject<{
434
+ textSize: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
435
+ "extra-small": "extra-small";
436
+ small: "small";
437
+ medium: "medium";
438
+ large: "large";
439
+ "extra-large": "extra-large";
440
+ "extra-extra-large": "extra-extra-large";
441
+ "extra-extra-extra-large": "extra-extra-extra-large";
442
+ "accessibility-medium": "accessibility-medium";
443
+ "accessibility-large": "accessibility-large";
444
+ "accessibility-extra-large": "accessibility-extra-large";
445
+ "accessibility-extra-extra-large": "accessibility-extra-extra-large";
446
+ "accessibility-extra-extra-extra-large": "accessibility-extra-extra-extra-large";
447
+ }>, z.ZodNumber]>>;
448
+ boldText: z.ZodOptional<z.ZodBoolean>;
449
+ contrast: z.ZodOptional<z.ZodEnum<{
450
+ increased: "increased";
451
+ normal: "normal";
452
+ }>>;
453
+ reduceMotion: z.ZodOptional<z.ZodBoolean>;
454
+ }, z.core.$strict>>;
455
+ }, z.core.$strict>>;
456
+ a11y: z.ZodOptional<z.ZodObject<{
457
+ ignore: z.ZodOptional<z.ZodArray<z.ZodObject<{
458
+ rule: z.ZodEnum<{
459
+ "missing-name": "missing-name";
460
+ "image-no-name": "image-no-name";
461
+ "target-size": "target-size";
462
+ "target-size-platform": "target-size-platform";
463
+ "duplicate-name": "duplicate-name";
464
+ "role-in-name": "role-in-name";
465
+ "label-in-name": "label-in-name";
466
+ "hidden-focusable": "hidden-focusable";
467
+ "text-clipped": "text-clipped";
468
+ native: "native";
469
+ }>;
470
+ identifier: z.ZodOptional<z.ZodString>;
471
+ }, z.core.$strict>>>;
472
+ minSeverity: z.ZodOptional<z.ZodEnum<{
473
+ error: "error";
474
+ warning: "warning";
475
+ }>>;
476
+ rules: z.ZodOptional<z.ZodArray<z.ZodEnum<{
477
+ "missing-name": "missing-name";
478
+ "image-no-name": "image-no-name";
479
+ "target-size": "target-size";
480
+ "target-size-platform": "target-size-platform";
481
+ "duplicate-name": "duplicate-name";
482
+ "role-in-name": "role-in-name";
483
+ "label-in-name": "label-in-name";
484
+ "hidden-focusable": "hidden-focusable";
485
+ "text-clipped": "text-clipped";
486
+ native: "native";
487
+ }>>>;
488
+ }, z.core.$strict>>;
489
+ camera: z.ZodOptional<z.ZodObject<{
490
+ back: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
491
+ path: z.ZodString;
492
+ loop: z.ZodOptional<z.ZodBoolean>;
493
+ }, z.core.$strict>]>>;
494
+ front: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
495
+ path: z.ZodString;
496
+ loop: z.ZodOptional<z.ZodBoolean>;
497
+ }, z.core.$strict>]>>;
498
+ }, z.core.$strict>>;
350
499
  required: z.ZodDefault<z.ZodBoolean>;
351
500
  specs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
352
501
  entries: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -364,6 +513,12 @@ export declare const wardenConfigSchema: z.ZodObject<{
364
513
  except: z.ZodOptional<z.ZodArray<z.ZodString>>;
365
514
  keep: z.ZodOptional<z.ZodArray<z.ZodString>>;
366
515
  }, z.core.$strict>]>>;
516
+ biometrics: z.ZodOptional<z.ZodBoolean>;
517
+ reclaim: z.ZodOptional<z.ZodEnum<{
518
+ none: "none";
519
+ uninstall: "uninstall";
520
+ erase: "erase";
521
+ }>>;
367
522
  perf: z.ZodOptional<z.ZodObject<{
368
523
  budgets: z.ZodOptional<z.ZodObject<{
369
524
  startupColdMs: z.ZodOptional<z.ZodNumber>;
@@ -373,9 +528,127 @@ export declare const wardenConfigSchema: z.ZodObject<{
373
528
  peakMemoryMb: z.ZodOptional<z.ZodNumber>;
374
529
  }, z.core.$strict>>;
375
530
  }, z.core.$strict>>;
531
+ conditions: z.ZodOptional<z.ZodObject<{
532
+ network: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
533
+ edge: "edge";
534
+ "3g": "3g";
535
+ "4g": "4g";
536
+ lte: "lte";
537
+ wifi: "wifi";
538
+ slow: "slow";
539
+ lossy: "lossy";
540
+ online: "online";
541
+ offline: "offline";
542
+ }>, z.ZodObject<{
543
+ latencyMs: z.ZodOptional<z.ZodNumber>;
544
+ jitterMs: z.ZodOptional<z.ZodNumber>;
545
+ downKbps: z.ZodOptional<z.ZodNumber>;
546
+ upKbps: z.ZodOptional<z.ZodNumber>;
547
+ lossPct: z.ZodOptional<z.ZodNumber>;
548
+ }, z.core.$strict>]>>;
549
+ location: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
550
+ "city-run": "city-run";
551
+ "city-bike": "city-bike";
552
+ freeway: "freeway";
553
+ }>, z.ZodObject<{
554
+ lat: z.ZodNumber;
555
+ lon: z.ZodNumber;
556
+ altM: z.ZodOptional<z.ZodNumber>;
557
+ }, z.core.$strict>]>>;
558
+ clock: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
559
+ at: z.ZodString;
560
+ frozen: z.ZodOptional<z.ZodBoolean>;
561
+ }, z.core.$strict>, z.ZodObject<{
562
+ offset: z.ZodString;
563
+ }, z.core.$strict>]>>;
564
+ permissions: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
565
+ location: "location";
566
+ locationAlways: "locationAlways";
567
+ camera: "camera";
568
+ photos: "photos";
569
+ photosAdd: "photosAdd";
570
+ contacts: "contacts";
571
+ contactsLimited: "contactsLimited";
572
+ notifications: "notifications";
573
+ microphone: "microphone";
574
+ calendar: "calendar";
575
+ reminders: "reminders";
576
+ motion: "motion";
577
+ mediaLibrary: "mediaLibrary";
578
+ siri: "siri";
579
+ }> & z.core.$partial, z.ZodEnum<{
580
+ granted: "granted";
581
+ denied: "denied";
582
+ unset: "unset";
583
+ }>>>;
584
+ locale: z.ZodOptional<z.ZodString>;
585
+ timezone: z.ZodOptional<z.ZodString>;
586
+ a11y: z.ZodOptional<z.ZodObject<{
587
+ textSize: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
588
+ "extra-small": "extra-small";
589
+ small: "small";
590
+ medium: "medium";
591
+ large: "large";
592
+ "extra-large": "extra-large";
593
+ "extra-extra-large": "extra-extra-large";
594
+ "extra-extra-extra-large": "extra-extra-extra-large";
595
+ "accessibility-medium": "accessibility-medium";
596
+ "accessibility-large": "accessibility-large";
597
+ "accessibility-extra-large": "accessibility-extra-large";
598
+ "accessibility-extra-extra-large": "accessibility-extra-extra-large";
599
+ "accessibility-extra-extra-extra-large": "accessibility-extra-extra-extra-large";
600
+ }>, z.ZodNumber]>>;
601
+ boldText: z.ZodOptional<z.ZodBoolean>;
602
+ contrast: z.ZodOptional<z.ZodEnum<{
603
+ increased: "increased";
604
+ normal: "normal";
605
+ }>>;
606
+ reduceMotion: z.ZodOptional<z.ZodBoolean>;
607
+ }, z.core.$strict>>;
608
+ }, z.core.$strict>>;
609
+ a11y: z.ZodOptional<z.ZodObject<{
610
+ ignore: z.ZodOptional<z.ZodArray<z.ZodObject<{
611
+ rule: z.ZodEnum<{
612
+ "missing-name": "missing-name";
613
+ "image-no-name": "image-no-name";
614
+ "target-size": "target-size";
615
+ "target-size-platform": "target-size-platform";
616
+ "duplicate-name": "duplicate-name";
617
+ "role-in-name": "role-in-name";
618
+ "label-in-name": "label-in-name";
619
+ "hidden-focusable": "hidden-focusable";
620
+ "text-clipped": "text-clipped";
621
+ native: "native";
622
+ }>;
623
+ identifier: z.ZodOptional<z.ZodString>;
624
+ }, z.core.$strict>>>;
625
+ minSeverity: z.ZodOptional<z.ZodEnum<{
626
+ error: "error";
627
+ warning: "warning";
628
+ }>>;
629
+ rules: z.ZodOptional<z.ZodArray<z.ZodEnum<{
630
+ "missing-name": "missing-name";
631
+ "image-no-name": "image-no-name";
632
+ "target-size": "target-size";
633
+ "target-size-platform": "target-size-platform";
634
+ "duplicate-name": "duplicate-name";
635
+ "role-in-name": "role-in-name";
636
+ "label-in-name": "label-in-name";
637
+ "hidden-focusable": "hidden-focusable";
638
+ "text-clipped": "text-clipped";
639
+ native: "native";
640
+ }>>>;
641
+ }, z.core.$strict>>;
376
642
  android: z.ZodOptional<z.ZodObject<{
377
643
  snapshot: z.ZodOptional<z.ZodBoolean>;
378
644
  }, z.core.$strict>>;
645
+ physical: z.ZodOptional<z.ZodObject<{
646
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
647
+ }, z.core.$strict>>;
648
+ ios: z.ZodOptional<z.ZodObject<{
649
+ teamId: z.ZodOptional<z.ZodString>;
650
+ runnerBundleId: z.ZodOptional<z.ZodString>;
651
+ }, z.core.$strict>>;
379
652
  }, z.core.$strict>;
380
653
  /** The slice of an Expo `app.json` warden reads (name, bundle ids). */
381
654
  export declare const appJsonSchema: z.ZodObject<{
@@ -209,6 +209,8 @@ export interface WardenProject {
209
209
  * `--kind`. Kinds sit on top of {@link WardenProject.variants}: both keep working, but a build is one or the other.
210
210
  */
211
211
  kinds?: WardenKinds | undefined;
212
+ /** iOS-only project settings. */
213
+ ios?: WardenProjectIos | undefined;
212
214
  /** Extra (legacy) cache roots laid out as `<dir>/<hash>/*.app|*.apk`, imported on demand. `~` expands to `$HOME`. */
213
215
  cacheDirs?: string[] | undefined;
214
216
  }
@@ -318,6 +320,19 @@ export interface WardenBatchPreset {
318
320
  except?: string[] | undefined;
319
321
  keep?: string[] | undefined;
320
322
  } | undefined;
323
+ /**
324
+ * Devices of this run have a fingerprint (Android) / Face ID (iOS) enrolled before any app install. Enrolled
325
+ * devices are a separate pool and golden from plain ones (profile `<profile>+bio`). Overrides the top-level
326
+ * `biometrics`. Default false.
327
+ */
328
+ biometrics?: boolean | undefined;
329
+ /**
330
+ * What happens to the state of the devices of this run when they are released: `"erase"` (iOS: shutdown +
331
+ * `simctl erase`; Android: uninstalls the third-party apps), `"uninstall"` (removes the user-installed apps) or
332
+ * `"none"`. Only warden-created simulators and emulators are reclaimed, never foreign, golden or physical
333
+ * devices. Overrides the top-level `reclaim`; `WARDEN_RECLAIM` is the fallback below it. Default `"none"`.
334
+ */
335
+ reclaim?: "erase" | "uninstall" | "none" | undefined;
321
336
  /** Per-job log dir. */
322
337
  logs?: string | undefined;
323
338
  /**
@@ -412,6 +427,63 @@ export interface WardenPerfConfig {
412
427
  /** Budgets; a metric the report has no number for (its capture did not run) cannot breach. */
413
428
  budgets?: WardenPerfBudgets | undefined;
414
429
  }
430
+ /** `a11y` (top level, or `e2e.<suite>.a11y`): how accessibility audits judge a screen. */
431
+ export interface WardenA11yConfig {
432
+ /** Findings to drop: a rule everywhere, or only on the element with that `identifier` (testID). */
433
+ ignore?: Array<{
434
+ rule: WardenA11yRule;
435
+ identifier?: string | undefined;
436
+ }> | undefined;
437
+ /** Lowest severity that fails an audit. @default "error" */
438
+ minSeverity?: "error" | "warning" | undefined;
439
+ /** Run only these rules (default: all). */
440
+ rules?: WardenA11yRule[] | undefined;
441
+ }
442
+ /** A rule id an audit reports; `native` = XCUITest / ATF findings. */
443
+ export type WardenA11yRule = "missing-name" | "image-no-name" | "target-size" | "target-size-platform" | "duplicate-name" | "role-in-name" | "label-in-name" | "hidden-focusable" | "text-clipped" | "native";
444
+ /** `conditions.network` as a custom shape: the fields of a `custom` network condition. */
445
+ export interface WardenCustomNetwork {
446
+ /** Added round-trip time, ms. */
447
+ latencyMs?: number | undefined;
448
+ /** Plus or minus spread on the latency, ms. */
449
+ jitterMs?: number | undefined;
450
+ /** Download rate, kilobits per second (0 = unlimited). */
451
+ downKbps?: number | undefined;
452
+ /** Upload rate, kilobits per second (0 = unlimited). */
453
+ upKbps?: number | undefined;
454
+ /** Share of packets lost, 0-100. */
455
+ lossPct?: number | undefined;
456
+ }
457
+ /**
458
+ * `conditions` (top level, or `e2e.<suite>.conditions`): the device state every spec of the suite starts from.
459
+ * `network`, `location` and `clock` are applied before the app launches and put back after each spec;
460
+ * `permissions`, `locale`, `timezone` and `a11y` are accepted but not applied yet (`warden e2e` says so once).
461
+ */
462
+ export interface WardenConditionsConfig {
463
+ /** `online`, `offline`, a preset (`edge`, `3g`, `4g`, `lte`, `wifi`, `slow`, `lossy`) or custom shaping. iOS launches the app with the network dylib so specs can change it later. */
464
+ network?: "online" | "offline" | "edge" | "3g" | "4g" | "lte" | "wifi" | "slow" | "lossy" | WardenCustomNetwork | undefined;
465
+ /** A point, or one of the bundled scenarios (`city-run`, `city-bike`, `freeway`). */
466
+ location?: "city-run" | "city-bike" | "freeway" | {
467
+ lat: number;
468
+ lon: number;
469
+ altM?: number | undefined;
470
+ } | undefined;
471
+ /** An ISO instant the clock starts at (and keeps running from), `{ at, frozen }`, or `{ offset }` ("2d") from now. */
472
+ clock?: string | {
473
+ at: string;
474
+ frozen?: boolean | undefined;
475
+ } | {
476
+ offset: string;
477
+ } | undefined;
478
+ /** Not applied yet. */
479
+ permissions?: Record<string, "granted" | "denied" | "unset"> | undefined;
480
+ /** Not applied yet. */
481
+ locale?: string | undefined;
482
+ /** Not applied yet. */
483
+ timezone?: string | undefined;
484
+ /** Not applied yet. */
485
+ a11y?: Record<string, unknown> | undefined;
486
+ }
415
487
  /** `e2e.<suite>.spec`: how `warden e2e` runs the `*.e2e.ts` specs (`bun test` with `@delacour/warden-e2e`). */
416
488
  export interface WardenE2eSpec {
417
489
  /** The app under test. Default: the suite project's `bundleId` for the platform. */
@@ -456,6 +528,16 @@ export interface WardenE2eDeviceLeg {
456
528
  */
457
529
  default?: boolean | undefined;
458
530
  }
531
+ /** One camera asset: a path (relative to the config file), or `{ path, loop }`. */
532
+ export type WardenCameraFeed = string | {
533
+ path: string;
534
+ loop?: boolean | undefined;
535
+ };
536
+ /** `e2e.<suite>.camera`: the asset each facing plays. At least one of `back` / `front`. */
537
+ export type WardenCameraConfig = {
538
+ back?: WardenCameraFeed | undefined;
539
+ front?: WardenCameraFeed | undefined;
540
+ };
459
541
  /**
460
542
  * `e2e.<suite>`: the specs `warden affected` selects and `warden e2e` runs. Every path and glob is
461
543
  * relative to the config file.
@@ -468,6 +550,16 @@ export interface WardenE2eSuite {
468
550
  project?: string | undefined;
469
551
  /** Perf budgets for this suite; each key replaces the top-level `perf.budgets` one. */
470
552
  perf?: WardenPerfConfig | undefined;
553
+ /** Device conditions every spec of this suite starts from; each area replaces the top-level one. */
554
+ conditions?: WardenConditionsConfig | undefined;
555
+ /** Accessibility audit settings for this suite; each key replaces the top-level `a11y` one. */
556
+ a11y?: WardenA11yConfig | undefined;
557
+ /**
558
+ * The simulated camera every spec of this suite starts from, applied before the first `app.open()`: a path, or
559
+ * `{ path, loop }` (video loop, default true), per facing. Paths are relative to the config file. Android devices of
560
+ * the suite are claimed with `--camera` (profile `<profile>+cam`, cold boot). png, jpg, heic, mp4 and mov are accepted.
561
+ */
562
+ camera?: WardenCameraConfig | undefined;
471
563
  /** Directory of specs: `*.e2e.ts(x)` specs whose other `.ts` files are helpers (searched recursively; dot dirs, `node_modules` and `__baselines__` skipped). */
472
564
  specsDir: string;
473
565
  /** How the specs run: the app under test, its launch arguments and the timeouts. */
@@ -626,6 +718,19 @@ export interface WardenE2eSuite {
626
718
  except?: string[] | undefined;
627
719
  keep?: string[] | undefined;
628
720
  } | undefined;
721
+ /**
722
+ * Devices of this run have a fingerprint (Android) / Face ID (iOS) enrolled before any app install. Enrolled
723
+ * devices are a separate pool and golden from plain ones (profile `<profile>+bio`). Overrides the top-level
724
+ * `biometrics`. Default false.
725
+ */
726
+ biometrics?: boolean | undefined;
727
+ /**
728
+ * What happens to the state of the devices of this run when they are released: `"erase"` (iOS: shutdown +
729
+ * `simctl erase`; Android: uninstalls the third-party apps), `"uninstall"` (removes the user-installed apps) or
730
+ * `"none"`. Only warden-created simulators and emulators are reclaimed, never foreign, golden or physical
731
+ * devices. Overrides the top-level `reclaim`; `WARDEN_RECLAIM` is the fallback below it. Default `"none"`.
732
+ */
733
+ reclaim?: "erase" | "uninstall" | "none" | undefined;
629
734
  /** Removed: renamed `warmDrivers`. */
630
735
  warmRunners?: undefined;
631
736
  /**
@@ -683,10 +788,64 @@ export interface WardenConfig {
683
788
  except?: string[] | undefined;
684
789
  keep?: string[] | undefined;
685
790
  } | undefined;
791
+ /**
792
+ * Devices of this run have a fingerprint (Android) / Face ID (iOS) enrolled before any app install. Enrolled
793
+ * devices are a separate pool and golden from plain ones (profile `<profile>+bio`). `e2e` suites and `batches` presets
794
+ * override it. Default false.
795
+ */
796
+ biometrics?: boolean | undefined;
797
+ /**
798
+ * What happens to the state of the devices of this run when they are released: `"erase"` (iOS: shutdown +
799
+ * `simctl erase`; Android: uninstalls the third-party apps), `"uninstall"` (removes the user-installed apps) or
800
+ * `"none"`. Only warden-created simulators and emulators are reclaimed, never foreign, golden or physical
801
+ * devices. Overrides the top-level `reclaim`; `WARDEN_RECLAIM` is the fallback below it. Default `"none"`.
802
+ */
803
+ reclaim?: "erase" | "uninstall" | "none" | undefined;
686
804
  /** Perf budgets every `e2e` suite starts from (a suite's own `perf.budgets` replace them per key). */
687
805
  perf?: WardenPerfConfig | undefined;
806
+ /** Device conditions every `e2e` suite starts from (a suite's own `conditions` replace them per area). */
807
+ conditions?: WardenConditionsConfig | undefined;
808
+ /** Accessibility audit settings every `e2e` suite starts from (a suite's own `a11y` keys replace them). */
809
+ a11y?: WardenA11yConfig | undefined;
688
810
  /** Android emulator settings. */
689
811
  android?: WardenAndroidSettings | undefined;
812
+ /** Physical iPhone settings. */
813
+ ios?: WardenIosSettings | undefined;
814
+ /** Physical phone and tablet settings. */
815
+ physical?: WardenPhysicalSettings | undefined;
816
+ }
817
+ /** Physical phone and tablet settings (`physical`). */
818
+ export interface WardenPhysicalSettings {
819
+ /**
820
+ * Allowlist for `--physical` claims that name no device: only these adb serials / CoreDevice UDIDs are picked.
821
+ * `WARDEN_PHYSICAL_IDS` (comma-separated) wins over it. Naming a device with `--serial` / `--udid` works for
822
+ * any device, listed or not.
823
+ *
824
+ * @example ["00008140-000A0B0C0D0E0F10", "R5CT123ABC"]
825
+ */
826
+ allow?: string[] | undefined;
827
+ }
828
+ /** iOS settings of one project (`projects[].ios`). */
829
+ export interface WardenProjectIos {
830
+ /** Builds for a physical iPhone (`--physical`, `--udid <iPhone>`). */
831
+ device?: {
832
+ bundleIdentifier?: string | undefined;
833
+ } | undefined;
834
+ }
835
+ /** Physical iPhone settings (`ios`). */
836
+ export interface WardenIosSettings {
837
+ /**
838
+ * Apple developer team id (10 characters, e.g. `LN69P7N673`) that signs warden's on-device runner. Without it
839
+ * (and without `WARDEN_IOS_TEAM_ID`, which wins) warden uses the team of the one `Apple Development` identity
840
+ * in your keychain and fails `ios_team_ambiguous` when there are several teams.
841
+ */
842
+ teamId?: string | undefined;
843
+ /**
844
+ * Bundle id of the runner app (its UI-test bundle is `<id>.uitests`).
845
+ *
846
+ * @default "nz.co.delacour.warden.runner.<team id, lower case>"
847
+ */
848
+ runnerBundleId?: string | undefined;
690
849
  }
691
850
  /** Android emulator settings (`android`). */
692
851
  export interface WardenAndroidSettings {
@@ -0,0 +1,37 @@
1
+ import { type AsyncResult } from "../../../types/src/result";
2
+ import type { Exec, ExecResult } from "../exec";
3
+ import type { InstalledApp } from "./resolve";
4
+ /** The temp-file effects of a devicectl call. */
5
+ export type DeviceIo = {
6
+ /** a fresh private directory */
7
+ tempDir: () => Promise<string>;
8
+ read: (path: string) => Promise<string>;
9
+ remove: (dir: string) => Promise<void>;
10
+ };
11
+ export declare const nodeDeviceIo: DeviceIo;
12
+ export type PhoneDeps = {
13
+ exec: Exec;
14
+ io?: DeviceIo;
15
+ };
16
+ export declare const phoneInstallArgv: (udid: string, appPath: string, json: string) => string[];
17
+ export declare const phoneUninstallArgv: (udid: string, bundleId: string, json: string) => string[];
18
+ export declare const phoneAppsArgv: (udid: string, bundleId: string, json: string) => string[];
19
+ /**
20
+ * A failed devicectl call in words: a locked phone, a phone the provisioning profile does not list, or one of the
21
+ * classified signing / device states (`classifyRunnerOutput`), each with what to do; else devicectl's first line.
22
+ */
23
+ export declare function describePhoneFailure(what: string, res: ExecResult): string;
24
+ /** Is `bundleId` on the phone, and which `CFBundleVersion` does it have? */
25
+ export declare function probePhone(deps: PhoneDeps, udid: string, bundleId: string): AsyncResult<InstalledApp>;
26
+ /** Install `appPath`, then confirm `bundleId` is there. */
27
+ export declare function installOnPhone(deps: PhoneDeps, udid: string, appPath: string, bundleId: string): AsyncResult<InstalledApp>;
28
+ /** Remove `bundleId` (the app under test) from the phone. */
29
+ export declare function uninstallFromPhone(deps: PhoneDeps, udid: string, bundleId: string): AsyncResult<void>;
30
+ /** `CFBundleVersion` of an `.app` (one `plutil` spawn); undefined when it cannot be read. */
31
+ export declare function appBundleVersion(exec: Exec, appDir: string): Promise<string | undefined>;
32
+ /**
33
+ * Is the app on the phone the cached build? The install record already named this build's key; this adds the
34
+ * `CFBundleVersion` the phone reports against the cached `.app`'s. Anything unreadable counts as a mismatch
35
+ * (a reinstall is the safe side).
36
+ */
37
+ export declare function phoneAppMatches(exec: Exec, cachedApp: string, installed: InstalledApp): Promise<boolean>;
@@ -1,10 +1,14 @@
1
1
  import { type AsyncResult } from "../../../types/src/result";
2
2
  import { type Exec } from "../exec";
3
3
  import type { Platform } from "../types";
4
+ import { type DeviceIo } from "./install-device";
4
5
  import type { InstalledApp } from "./resolve";
5
6
  /** Byte size of a file; undefined when it cannot be read. Injected so identity checks need no `stat` spawns. */
6
7
  export type FileSize = (path: string) => Promise<number | undefined>;
7
8
  export declare const nodeFileSize: FileSize;
9
+ /** Hex sha256 of a file; undefined when it cannot be read (or is a directory). Injected so tests need no real apk. */
10
+ export type FileDigest = (path: string) => Promise<string | undefined>;
11
+ export declare const nodeFileDigest: FileDigest;
8
12
  /** `ino:mtime` of a file; undefined when it cannot be read. Injected so tests need no real container. */
9
13
  export type FileStamp = (path: string) => Promise<string | undefined>;
10
14
  export declare const nodeFileStamp: FileStamp;
@@ -18,12 +22,19 @@ export type InstallerDeps = {
18
22
  env: Record<string, string | undefined>;
19
23
  /** default: `node:fs` */
20
24
  fileSize?: FileSize;
25
+ /** the temp files of `devicectl` calls on a physical iPhone (default: node:fs) */
26
+ deviceIo?: DeviceIo;
27
+ /** sha256 of the cached apk for the Android identity check (default: `node:fs`) */
28
+ fileDigest?: FileDigest;
21
29
  };
22
- /** A device to install onto: iOS simulator udid / Android emulator serial. */
30
+ /** A device to install onto: iOS simulator udid / Android emulator or phone serial. `physical`: a real phone (ABI check before installing). */
23
31
  export type InstallTarget = {
24
32
  platform: Platform;
25
33
  deviceId: string;
34
+ physical?: boolean;
26
35
  };
36
+ /** A real iPhone / iPad: installed, probed and removed with `devicectl`, not `simctl`. */
37
+ export declare const isPhoneIos: (target: InstallTarget) => boolean;
27
38
  /** `xcrun simctl install <udid> <app>` / `adb -s <serial> install -r <apk>`. */
28
39
  export declare function installArgv(target: InstallTarget, appPath: string, env: InstallerDeps["env"]): string[];
29
40
  /** `xcrun simctl get_app_container <udid> <bundleId>` / `adb -s <serial> shell pm path <bundleId>`. */
@@ -47,8 +58,9 @@ export declare function appIdentity(deps: InstallerDeps, appDir: string): Promis
47
58
  * Is the app on the device the cached `artifactPath` build? iOS: compare `appIdentity` of the
48
59
  * installed container with the cached `.app`; pass `installedDir` (the container `probeApp` already
49
60
  * found) to skip a second `simctl get_app_container`. Anything unreadable counts as a mismatch
50
- * (reinstall is the safe side). Android: not checked (always true) — warden's install record is
51
- * trusted there.
61
+ * (reinstall is the safe side). Android: the sha256 of the installed `base.apk` (`pm path` + the device's
62
+ * `sha256sum`) against the cached apk's. The install record is only a hint, never the proof: an emulator
63
+ * restored from a snapshot, or installed onto by another tool, keeps the record while the app differs.
52
64
  */
53
65
  export declare function appMatchesArtifact(deps: InstallerDeps, target: InstallTarget, bundleId: string, artifactPath: string, installedDir?: string): AsyncResult<boolean>;
54
66
  /** `xcrun simctl uninstall <udid> <bundleId>` / `adb -s <serial> uninstall <bundleId>`. */
@@ -60,6 +72,8 @@ export declare function uninstallArgv(target: InstallTarget, bundleId: string, e
60
72
  export declare function uninstallApp(deps: InstallerDeps, target: InstallTarget, bundleId: string): AsyncResult<void>;
61
73
  /** Install `appPath`, then confirm `bundleId` is present. */
62
74
  export declare function installApp(deps: InstallerDeps, target: InstallTarget, appPath: string, bundleId: string): AsyncResult<void>;
75
+ /** ABI directories under `lib/` in `unzip -Z1` output; empty for a pure-Java APK. */
76
+ export declare function apkAbis(entries: string): string[];
63
77
  /** `installApp`, keeping what the confirming probe found (iOS: the new bundle container, 17-7). */
64
78
  export declare function installAndProbe(deps: InstallerDeps, target: InstallTarget, appPath: string, bundleId: string): AsyncResult<InstalledApp>;
65
79
  /** Filesystem ops the iOS data wipe needs (injected; tests pass fakes). */