doc-detective 4.21.0 → 4.22.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 (46) hide show
  1. package/dist/common/src/schemas/schemas.json +264 -264
  2. package/dist/common/src/types/generated/config_v3.d.ts +4 -4
  3. package/dist/common/src/types/generated/context_v3.d.ts +4 -4
  4. package/dist/common/src/types/generated/report_v3.d.ts +4 -4
  5. package/dist/common/src/types/generated/resolvedTests_v3.d.ts +8 -8
  6. package/dist/common/src/types/generated/spec_v3.d.ts +4 -4
  7. package/dist/common/src/types/generated/startSurface_v3.d.ts +7 -7
  8. package/dist/common/src/types/generated/step_v3.d.ts +7 -7
  9. package/dist/common/src/types/generated/test_v3.d.ts +18 -18
  10. package/dist/core/tests/androidEmulator.d.ts +2 -12
  11. package/dist/core/tests/androidEmulator.d.ts.map +1 -1
  12. package/dist/core/tests/androidEmulator.js +5 -17
  13. package/dist/core/tests/androidEmulator.js.map +1 -1
  14. package/dist/core/tests/appSurface.d.ts +35 -1
  15. package/dist/core/tests/appSurface.d.ts.map +1 -1
  16. package/dist/core/tests/appSurface.js +162 -20
  17. package/dist/core/tests/appSurface.js.map +1 -1
  18. package/dist/core/tests/iosSimulator.d.ts +89 -0
  19. package/dist/core/tests/iosSimulator.d.ts.map +1 -0
  20. package/dist/core/tests/iosSimulator.js +453 -0
  21. package/dist/core/tests/iosSimulator.js.map +1 -0
  22. package/dist/core/tests/mobileDevice.d.ts +15 -0
  23. package/dist/core/tests/mobileDevice.d.ts.map +1 -0
  24. package/dist/core/tests/mobileDevice.js +24 -0
  25. package/dist/core/tests/mobileDevice.js.map +1 -0
  26. package/dist/core/tests/mobilePlatform.d.ts +1 -2
  27. package/dist/core/tests/mobilePlatform.d.ts.map +1 -1
  28. package/dist/core/tests/mobilePlatform.js +15 -14
  29. package/dist/core/tests/mobilePlatform.js.map +1 -1
  30. package/dist/core/tests.d.ts.map +1 -1
  31. package/dist/core/tests.js +152 -45
  32. package/dist/core/tests.js.map +1 -1
  33. package/dist/index.cjs +845 -331
  34. package/dist/runtime/heavyDeps.d.ts +1 -1
  35. package/dist/runtime/heavyDeps.d.ts.map +1 -1
  36. package/dist/runtime/heavyDeps.js +1 -0
  37. package/dist/runtime/heavyDeps.js.map +1 -1
  38. package/dist/runtime/installCommand.d.ts +1 -1
  39. package/dist/runtime/installCommand.d.ts.map +1 -1
  40. package/dist/runtime/installCommand.js +21 -4
  41. package/dist/runtime/installCommand.js.map +1 -1
  42. package/dist/runtime/iosInstaller.d.ts +23 -0
  43. package/dist/runtime/iosInstaller.d.ts.map +1 -0
  44. package/dist/runtime/iosInstaller.js +104 -0
  45. package/dist/runtime/iosInstaller.js.map +1 -0
  46. package/package.json +2 -1
@@ -1,11 +1,11 @@
1
1
  // Native app surfaces phase A3: the `android`/`ios` target platforms. Unlike
2
2
  // desktop platforms (where host == target), a mobile platform names the
3
3
  // TARGET a context runs against and is gated by host *capability*, not host
4
- // identity. As of A3b, android native app contexts can PASS (via
5
- // androidContextPreflight, which capability-gates and lazily installs the
6
- // toolchain); the cases this module composes SKIP reasons for are the ones
7
- // still gated by a later phase iOS (A4) and android+browser (A5). The reason
8
- // composer is pure so it's unit-testable without probing an SDK.
4
+ // identity. As of A4, native app contexts can pass on both mobile targets
5
+ // when the host is capable. The remaining mobile-target skip reason this
6
+ // module composes is mobile browser testing (A5), which is still gated on both
7
+ // android and ios. The reason composer is pure so it's unit-testable without
8
+ // probing an SDK.
9
9
  export { isMobileTargetPlatform, mobileContextSkipReason };
10
10
  // Classify a context platform as a mobile target, or null for desktop / junk.
11
11
  function isMobileTargetPlatform(platform) {
@@ -13,18 +13,19 @@ function isMobileTargetPlatform(platform) {
13
13
  return platform;
14
14
  return null;
15
15
  }
16
- // Compose the SKIP reason (and log level) for the mobile-context cases still
17
- // gated by a not-yet-implemented phase:
18
- // - ios -> app surfaces land in A4
19
- // - android with a browser step -> mobile browsers land in A5
20
- // (Android native app runs are handled by androidContextPreflight, which
21
- // capability-gates and lazily installs the toolchain rather than skipping.)
22
- function mobileContextSkipReason({ platform, hasBrowserStep, }) {
16
+ // Compose the SKIP reason (and log level) for the one mobile-context case still
17
+ // gated by a later phase: a mobile-web (browser) step on either target — mobile
18
+ // browsers land in A5. Native app contexts (no browser step) are NOT routed
19
+ // here; they pass through their platform's context preflight (androidContext-
20
+ // Preflight / iosContextPreflight), which capability-gates and runs them. This
21
+ // composer is only ever called for a mobile-browser context, so it branches on
22
+ // the target platform alone.
23
+ function mobileContextSkipReason({ platform, }) {
23
24
  const roadmap = "docs/design/native-app-surfaces.md";
24
25
  if (platform === "ios") {
25
26
  return {
26
- level: "info",
27
- reason: `Skipping context on 'ios': iOS app surfaces land in phase A4 of the native app roadmap (${roadmap}). Gate iOS tests with runOn platforms so this skip is intentional.`,
27
+ level: "warning",
28
+ reason: `Skipping context on 'ios': mobile browser testing on iOS lands in phase A5 of the native app roadmap (${roadmap}). Native iOS app tests run on capable macOS hosts.`,
28
29
  };
29
30
  }
30
31
  // android + a browser step: mobile-web testing on Android is phase A5.
@@ -1 +1 @@
1
- {"version":3,"file":"mobilePlatform.js","sourceRoot":"","sources":["../../../src/core/tests/mobilePlatform.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wEAAwE;AACxE,4EAA4E;AAC5E,iEAAiE;AACjE,0EAA0E;AAC1E,2EAA2E;AAC3E,+EAA+E;AAC/E,iEAAiE;AAEjE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,CAAC;AAI3D,8EAA8E;AAC9E,SAAS,sBAAsB,CAAC,QAAiB;IAC/C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK;QAAE,OAAO,QAAQ,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6EAA6E;AAC7E,wCAAwC;AACxC,6DAA6D;AAC7D,gEAAgE;AAChE,yEAAyE;AACzE,4EAA4E;AAC5E,SAAS,uBAAuB,CAAC,EAC/B,QAAQ,EACR,cAAc,GAIf;IACC,MAAM,OAAO,GAAG,oCAAoC,CAAC;IACrD,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO;YACL,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,2FAA2F,OAAO,qEAAqE;SAChL,CAAC;IACJ,CAAC;IACD,uEAAuE;IACvE,OAAO;QACL,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,iHAAiH,OAAO,2DAA2D;KAC5L,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"mobilePlatform.js","sourceRoot":"","sources":["../../../src/core/tests/mobilePlatform.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wEAAwE;AACxE,4EAA4E;AAC5E,0EAA0E;AAC1E,yEAAyE;AACzE,+EAA+E;AAC/E,6EAA6E;AAC7E,kBAAkB;AAElB,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,CAAC;AAI3D,8EAA8E;AAC9E,SAAS,sBAAsB,CAAC,QAAiB;IAC/C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK;QAAE,OAAO,QAAQ,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,4EAA4E;AAC5E,8EAA8E;AAC9E,+EAA+E;AAC/E,+EAA+E;AAC/E,6BAA6B;AAC7B,SAAS,uBAAuB,CAAC,EAC/B,QAAQ,GAGT;IACC,MAAM,OAAO,GAAG,oCAAoC,CAAC;IACrD,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,yGAAyG,OAAO,qDAAqD;SAC9K,CAAC;IACJ,CAAC;IACD,uEAAuE;IACvE,OAAO;QACL,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,iHAAiH,OAAO,2DAA2D;KAC5L,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../src/core/tests.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../src/core/tests.ts"],"names":[],"mappings":"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"}
@@ -38,6 +38,7 @@ import { isMobileTargetPlatform, mobileContextSkipReason, } from "./tests/mobile
38
38
  import { detectAndroidSdk } from "../runtime/androidSdk.js";
39
39
  import { hostAbi, listInstalledSystemImages, installAndroid, } from "../runtime/androidInstaller.js";
40
40
  import { buildAcquireDeviceDeps, checkEmulatorAcceleration, hostHasKvm, planDeviceAcquisition, planAndroidToolchain, normalizeDeviceDescriptor, acquireDevice, createDeviceRegistry, teardownDeviceRegistry, } from "./tests/androidEmulator.js";
41
+ import { buildAcquireSimulatorDeps, planSimulatorAcquisition, acquireSimulator, createSimulatorRegistry, teardownSimulatorRegistry, } from "./tests/iosSimulator.js";
41
42
  import { runBrowserScript } from "./tests/runBrowserScript.js";
42
43
  import { dragAndDropElement } from "./tests/dragAndDrop.js";
43
44
  import { createSessionRegistry, registerSession, activeDriver, sweepSessions, } from "./tests/browserSessions.js";
@@ -409,7 +410,6 @@ async function androidContextPreflight({ config, context, clog, }) {
409
410
  if (hasBrowserStep) {
410
411
  const { level, reason } = mobileContextSkipReason({
411
412
  platform: "android",
412
- hasBrowserStep,
413
413
  });
414
414
  return { ok: false, level, reason };
415
415
  }
@@ -569,6 +569,62 @@ async function androidContextPreflight({ config, context, clog, }) {
569
569
  }
570
570
  /* c8 ignore stop */
571
571
  }
572
+ // iOS context preflight (native app phase A4): mobile-browser contexts are
573
+ // still gated to A5; native app contexts probe host capability/toolchain via
574
+ // appSurfacePreflight, then validate that the context's default simulator can
575
+ // be resolved (booted/created) via simctl. On success return the appium
576
+ // entry/home plus the injected simctl effect bundle for the run's
577
+ // acquireSimulator closure.
578
+ async function iosContextPreflight({ config, context, }) {
579
+ const hasBrowserStep = isBrowserRequired({ test: context });
580
+ if (hasBrowserStep) {
581
+ const { level, reason } = mobileContextSkipReason({
582
+ platform: "ios",
583
+ });
584
+ return { ok: false, level, reason };
585
+ }
586
+ const pre = await appSurfacePreflight({ config, platform: "ios" });
587
+ if (!pre.ok)
588
+ return { ok: false, level: "info", reason: pre.reason };
589
+ /* c8 ignore start */
590
+ // The ok path only runs on a capable macOS host (appSurfacePreflight's
591
+ // probeIosToolchain passed), so the simctl probes below are macOS-only and
592
+ // never execute in the cross-platform unit suite.
593
+ const simulatorDeps = buildAcquireSimulatorDeps((m) => log(config, "debug", m));
594
+ try {
595
+ const desc = normalizeDeviceDescriptor({
596
+ contextDevice: context.device,
597
+ platform: "ios",
598
+ });
599
+ const [devices, runtimes, deviceTypes] = await Promise.all([
600
+ simulatorDeps.listDevices(),
601
+ simulatorDeps.listRuntimes(),
602
+ simulatorDeps.listDeviceTypes(),
603
+ ]);
604
+ const plan = planSimulatorAcquisition(desc, {
605
+ devices,
606
+ runtimes,
607
+ deviceTypes,
608
+ });
609
+ if (plan.action === "skip") {
610
+ return { ok: false, level: "info", reason: plan.reason };
611
+ }
612
+ }
613
+ catch (error) {
614
+ return {
615
+ ok: false,
616
+ level: "info",
617
+ reason: `Skipping context on 'ios': couldn't probe the iOS simulator environment (${error?.message ?? error}). Check Xcode / simctl, or run \`doc-detective install ios --yes\`.`,
618
+ };
619
+ }
620
+ return {
621
+ ok: true,
622
+ appiumEntry: pre.appiumEntry,
623
+ appiumHome: pre.appiumHome,
624
+ simulatorDeps,
625
+ };
626
+ /* c8 ignore stop */
627
+ }
572
628
  function getDefaultBrowser({ runnerDetails }) {
573
629
  let browser = {};
574
630
  const browserNames = ["firefox", "chrome", "safari"];
@@ -1245,6 +1301,11 @@ async function runSpecs({ resolvedTests }) {
1245
1301
  // wanting the same device converge on one boot. Swept in the `finally` below —
1246
1302
  // only devices Doc Detective booted are killed (launch-ownership).
1247
1303
  const deviceRegistry = createDeviceRegistry();
1304
+ // Run-level simulator registry (native app phase A4): booted/created iOS
1305
+ // simulators keyed by resolved name, the simctl analogue of deviceRegistry.
1306
+ // Swept in the `finally` below — only simulators Doc Detective booted are
1307
+ // shut down (launch-ownership).
1308
+ const simulatorRegistry = createSimulatorRegistry();
1248
1309
  // Kill every still-registered background process (and its child tree) and
1249
1310
  // remove any deferred temp scripts. Awaits the kills so the process tree is
1250
1311
  // actually gone before the run returns. Idempotent: closeSurface already
@@ -1344,6 +1405,7 @@ async function runSpecs({ resolvedTests }) {
1344
1405
  warmUpResults,
1345
1406
  processRegistry,
1346
1407
  deviceRegistry,
1408
+ simulatorRegistry,
1347
1409
  logPrefix: limit > 1 ? `[${job.test.testId}/${job.context.contextId}]` : "",
1348
1410
  });
1349
1411
  }
@@ -1430,6 +1492,7 @@ async function runSpecs({ resolvedTests }) {
1430
1492
  warmUpResults,
1431
1493
  processRegistry,
1432
1494
  deviceRegistry,
1495
+ simulatorRegistry,
1433
1496
  platform,
1434
1497
  markAutoRecord,
1435
1498
  limit,
@@ -1495,6 +1558,16 @@ async function runSpecs({ resolvedTests }) {
1495
1558
  await killTree(entry.process?.pid);
1496
1559
  });
1497
1560
  }
1561
+ // Sweep the iOS simulator registry (native app phase A4): shut down only the
1562
+ // simulators Doc Detective booted (bootedByUs), leaving pre-existing booted
1563
+ // ones running. `simctl shutdown` via the injected effect bundle.
1564
+ if (simulatorRegistry.size > 0) {
1565
+ const simDeps = buildAcquireSimulatorDeps();
1566
+ await teardownSimulatorRegistry(simulatorRegistry, async (entry) => {
1567
+ log(config, "debug", `Shutting down simulator "${entry.name}" (${entry.udid}).`);
1568
+ await simDeps.shutdown(entry);
1569
+ });
1570
+ }
1498
1571
  /* c8 ignore stop */
1499
1572
  process.off("SIGINT", onSignal);
1500
1573
  process.off("SIGTERM", onSignal);
@@ -1560,7 +1633,7 @@ async function runSpecs({ resolvedTests }) {
1560
1633
  * NEVER touches the summary — Phase-3 in runSpecs remains the sole tally site;
1561
1634
  * here we only push reports.
1562
1635
  */
1563
- async function runRoutedSpec({ spec, specReport, specGuardSkip, config, runnerDetails, appiumPool, portToDisplay, metaValues, installAttempts, warmUpResults, processRegistry, deviceRegistry, platform, markAutoRecord, limit, resourceRegistry, exclusivityCtx, }) {
1636
+ async function runRoutedSpec({ spec, specReport, specGuardSkip, config, runnerDetails, appiumPool, portToDisplay, metaValues, installAttempts, warmUpResults, processRegistry, deviceRegistry, simulatorRegistry, platform, markAutoRecord, limit, resourceRegistry, exclusivityCtx, }) {
1564
1637
  // Set once a `stop:spec` (or deferred `stop:run`) decision halts the spec; the
1565
1638
  // remaining tests are recorded SKIPPED with the stop reason and not executed.
1566
1639
  let stopRest = false;
@@ -1723,6 +1796,7 @@ async function runRoutedSpec({ spec, specReport, specGuardSkip, config, runnerDe
1723
1796
  warmUpResults,
1724
1797
  processRegistry,
1725
1798
  deviceRegistry,
1799
+ simulatorRegistry,
1726
1800
  logPrefix: limit > 1 ? `[${job.test.testId}/${job.context.contextId}]` : "",
1727
1801
  });
1728
1802
  }
@@ -2288,7 +2362,7 @@ async function captureAutoScreenshot({ config, driver, spec, test, context, step
2288
2362
  * report or summary counters — the caller owns aggregation, which keeps this
2289
2363
  * function safe to run concurrently with sibling contexts.
2290
2364
  */
2291
- async function runContext({ config, spec, test, context, runnerDetails, appiumPool, portToDisplay, metaValues, installAttempts, warmUpResults, processRegistry, deviceRegistry, logPrefix = "", }) {
2365
+ async function runContext({ config, spec, test, context, runnerDetails, appiumPool, portToDisplay, metaValues, installAttempts, warmUpResults, processRegistry, deviceRegistry, simulatorRegistry, logPrefix = "", }) {
2292
2366
  const platform = runnerDetails.environment.platform;
2293
2367
  // `let`, not `const`: an on-demand browser install below re-detects available
2294
2368
  // apps and reassigns this snapshot.
@@ -2354,45 +2428,59 @@ async function runContext({ config, spec, test, context, runnerDetails, appiumPo
2354
2428
  contextReport.resultDescription = requirementsSkip;
2355
2429
  return contextReport;
2356
2430
  }
2357
- if (mobileTarget === "ios") {
2358
- // iOS has no PASS path yet point at phase A4.
2359
- const { level, reason } = mobileContextSkipReason({ platform: "ios" });
2360
- clog(level, reason);
2361
- contextReport.result = "SKIPPED";
2362
- contextReport.resultDescription = reason;
2363
- return contextReport;
2431
+ if (mobileTarget === "android") {
2432
+ // Android (phase A3b): full preflight. SDK detection is lazy (probed
2433
+ // only here, only for android contexts), so a run that never targets
2434
+ // android pays nothing. On skip, land SKIPPED with the actionable reason;
2435
+ // on ok, prime the app session with the device layer and FALL THROUGH to
2436
+ // run the steps.
2437
+ const pre = await androidContextPreflight({ config, context, clog });
2438
+ if (!pre.ok) {
2439
+ clog(pre.level, pre.reason);
2440
+ contextReport.result = "SKIPPED";
2441
+ contextReport.resultDescription = pre.reason;
2442
+ return contextReport;
2443
+ }
2444
+ /* c8 ignore start */
2445
+ // The ok path only runs on a host with a real SDK + emulator (CI legs).
2446
+ appSession = createAppSessionState();
2447
+ appSession.appiumEntry = pre.appiumEntry;
2448
+ appSession.appiumHome = pre.appiumHome;
2449
+ appSession.defaultDevice = context.device;
2450
+ appSession.androidSdkRoot = pre.sdkRoot;
2451
+ appSession.androidDeviceRegistry = deviceRegistry;
2452
+ appSession.androidDeviceDeps = pre.deviceDeps;
2453
+ // resolved device (name) joins the context report the way resolved
2454
+ // browser versions do; the concrete udid is known once a surface boots
2455
+ // it.
2456
+ contextReport.device = context.device ?? { platform: "android" };
2457
+ // Surface any preflight warnings (e.g. a lazy toolchain install) in the
2458
+ // output report — not just the terminal — so a run that quietly
2459
+ // downloaded the multi-GB SDK is auditable after the fact.
2460
+ if (pre.warnings.length)
2461
+ contextReport.warnings = pre.warnings;
2462
+ /* c8 ignore stop */
2364
2463
  }
2365
- // Android (phase A3b): full preflight. SDK detection is lazy (probed only
2366
- // here, only for android contexts), so a run that never targets android
2367
- // pays nothing. On skip, land SKIPPED with the actionable reason; on ok,
2368
- // prime the app session with the device layer and FALL THROUGH to run the
2369
- // steps — none of the desktop engine/platform skips below apply to it (the
2370
- // `!platformMatches` skip is guarded on `!appSession`).
2371
- const pre = await androidContextPreflight({ config, context, clog });
2372
- if (!pre.ok) {
2373
- clog(pre.level, pre.reason);
2374
- contextReport.result = "SKIPPED";
2375
- contextReport.resultDescription = pre.reason;
2376
- return contextReport;
2464
+ else {
2465
+ const pre = await iosContextPreflight({ config, context });
2466
+ if (!pre.ok) {
2467
+ clog(pre.level, pre.reason);
2468
+ contextReport.result = "SKIPPED";
2469
+ contextReport.resultDescription = pre.reason;
2470
+ return contextReport;
2471
+ }
2472
+ /* c8 ignore start */
2473
+ // The ok path only runs on a capable macOS host (CI fixture legs): prime
2474
+ // the app session with the simulator layer and FALL THROUGH to run steps.
2475
+ appSession = createAppSessionState();
2476
+ appSession.appiumEntry = pre.appiumEntry;
2477
+ appSession.appiumHome = pre.appiumHome;
2478
+ appSession.defaultDevice = context.device;
2479
+ appSession.iosSimulatorRegistry = simulatorRegistry;
2480
+ appSession.iosSimulatorDeps = pre.simulatorDeps;
2481
+ contextReport.device = context.device ?? { platform: "ios" };
2482
+ /* c8 ignore stop */
2377
2483
  }
2378
- /* c8 ignore start */
2379
- // The ok path only runs on a host with a real SDK + emulator (CI legs).
2380
- appSession = createAppSessionState();
2381
- appSession.appiumEntry = pre.appiumEntry;
2382
- appSession.appiumHome = pre.appiumHome;
2383
- appSession.defaultDevice = context.device;
2384
- appSession.androidSdkRoot = pre.sdkRoot;
2385
- appSession.androidDeviceRegistry = deviceRegistry;
2386
- appSession.androidDeviceDeps = pre.deviceDeps;
2387
- // resolved device (name) joins the context report the way resolved browser
2388
- // versions do; the concrete udid is known once a surface boots it.
2389
- contextReport.device = context.device ?? { platform: "android" };
2390
- // Surface any preflight warnings (e.g. a lazy toolchain install) in the
2391
- // output report — not just the terminal — so a run that quietly downloaded
2392
- // the multi-GB SDK is auditable after the fact.
2393
- if (pre.warnings.length)
2394
- contextReport.warnings = pre.warnings;
2395
- /* c8 ignore stop */
2396
2484
  }
2397
2485
  // `requires` capability gate: any unmet requirement skips the context with a
2398
2486
  // message naming what's missing. Evaluated only on the platform the context
@@ -3442,9 +3530,12 @@ async function runStep({ config = {}, context = {}, step, driver, metaValues = {
3442
3530
  return { port: server.port, process: server.process };
3443
3531
  },
3444
3532
  startDriver: (capabilities, port) => driverStart(capabilities, port, 2, { cacheDir: config?.cacheDir }),
3445
- // Android device acquisition (boot/create-and-boot, or reuse),
3446
- // bound to the run-level registry stashed on the app session. Only
3447
- // set for android app sessions (which only exist on a capable host).
3533
+ // Mobile device acquisition (boot/create-and-boot, or reuse), bound
3534
+ // to the run-level registry stashed on the app session. Android uses
3535
+ // the emulator layer; iOS uses the simctl simulator layer. Both
3536
+ // return the same { entry:{name,udid} } | { skip } shape, so
3537
+ // startAppSurface's mobile branch stays uniform. Only set for a
3538
+ // mobile app session (which only exists on a capable host).
3448
3539
  /* c8 ignore start */
3449
3540
  acquireDevice: appSession?.androidDeviceDeps
3450
3541
  ? (desc) => acquireDevice({
@@ -3453,7 +3544,13 @@ async function runStep({ config = {}, context = {}, step, driver, metaValues = {
3453
3544
  sdkRoot: appSession.androidSdkRoot,
3454
3545
  deps: appSession.androidDeviceDeps,
3455
3546
  })
3456
- : undefined,
3547
+ : appSession?.iosSimulatorDeps
3548
+ ? (desc) => acquireSimulator({
3549
+ desc,
3550
+ registry: appSession.iosSimulatorRegistry,
3551
+ deps: appSession.iosSimulatorDeps,
3552
+ })
3553
+ : undefined,
3457
3554
  /* c8 ignore stop */
3458
3555
  },
3459
3556
  });
@@ -3611,6 +3708,16 @@ async function driverStart(capabilities, port, maxAttempts = 4, ctx = {}) {
3611
3708
  // creation failure and propagates immediately.
3612
3709
  const TRANSIENT = /ECONNREFUSED|ECONNRESET|socket hang up|could not proxy command|crashed during startup|cannot connect to|DevToolsActivePort|session not created/i;
3613
3710
  const wdio = await loadHeavyDep("webdriverio", { ctx });
3711
+ // The wdio client aborts the POST /session request after connectionRetryTimeout.
3712
+ // A cold native session can take far longer to create than the 2-minute
3713
+ // default: the first XCUITest session builds WebDriverAgent via xcodebuild
3714
+ // (several minutes on a fresh macOS runner), and Mac2 builds WebDriverAgentMac
3715
+ // similarly. Derive the client timeout from whatever slow-startup ceiling the
3716
+ // capabilities declared (wdaLaunchTimeout / wdaConnectionTimeout /
3717
+ // serverStartupTimeout) so the client waits as long as the driver was told to,
3718
+ // never below the 2-minute floor. Browser/Windows/Android sessions carry none
3719
+ // of these caps and keep the 2-minute default unchanged.
3720
+ const startupCeiling = Math.max(120000, Number(capabilities?.["appium:wdaLaunchTimeout"]) || 0, Number(capabilities?.["appium:wdaConnectionTimeout"]) || 0, Number(capabilities?.["appium:serverStartupTimeout"]) || 0);
3614
3721
  let lastError;
3615
3722
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
3616
3723
  try {
@@ -3621,7 +3728,7 @@ async function driverStart(capabilities, port, maxAttempts = 4, ctx = {}) {
3621
3728
  path: "/",
3622
3729
  logLevel: "error",
3623
3730
  capabilities,
3624
- connectionRetryTimeout: 120000, // 2 minutes
3731
+ connectionRetryTimeout: startupCeiling,
3625
3732
  waitforTimeout: 120000, // 2 minutes
3626
3733
  });
3627
3734
  // Per-context mutable state. `recordings` lives here (not on config)