appium-xcuitest-driver 11.12.0 → 11.12.2

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [11.12.2](https://github.com/appium/appium-xcuitest-driver/compare/v11.12.1...v11.12.2) (2026-06-19)
2
+
3
+ ### Bug Fixes
4
+
5
+ * Make sure the tunnel process exits after an unexpected error ([#2878](https://github.com/appium/appium-xcuitest-driver/issues/2878)) ([a31696c](https://github.com/appium/appium-xcuitest-driver/commit/a31696cee1da738c4aff49b6ef2d07c40a8761a1))
6
+
7
+ ## [11.12.1](https://github.com/appium/appium-xcuitest-driver/compare/v11.12.0...v11.12.1) (2026-06-19)
8
+
9
+ ### Miscellaneous Chores
10
+
11
+ * Improve tunnel creation logging ([#2879](https://github.com/appium/appium-xcuitest-driver/issues/2879)) ([85fd331](https://github.com/appium/appium-xcuitest-driver/commit/85fd3317c58d93c3c38d08e6bee6da73ad28c8b7))
12
+
1
13
  ## [11.12.0](https://github.com/appium/appium-xcuitest-driver/compare/v11.11.2...v11.12.0) (2026-06-19)
2
14
 
3
15
  ### Features
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "appium-xcuitest-driver",
3
- "version": "11.12.0",
3
+ "version": "11.12.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appium-xcuitest-driver",
9
- "version": "11.12.0",
9
+ "version": "11.12.2",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@appium/css-locator-to-native": "^1.0.1",
@@ -63,7 +63,7 @@
63
63
  "npm": ">=10"
64
64
  },
65
65
  "optionalDependencies": {
66
- "appium-ios-remotexpc": "^5.0.0"
66
+ "appium-ios-remotexpc": "^5.1.0"
67
67
  },
68
68
  "peerDependencies": {
69
69
  "appium": "^3.0.0-rc.2"
@@ -137,6 +137,19 @@
137
137
  "npm": ">=10"
138
138
  }
139
139
  },
140
+ "node_modules/@appium/docutils/node_modules/teen_process": {
141
+ "version": "4.1.3",
142
+ "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-4.1.3.tgz",
143
+ "integrity": "sha512-8W7Xp7WtJ5ZXjv0iHMsCgPPKzUt6ACfG/rDWX0tMIlMJaYcTYsPw3ZQQ9+hG7YsY+gm+DUATiyah3AraJ9JYpg==",
144
+ "license": "Apache-2.0",
145
+ "dependencies": {
146
+ "shell-quote": "^1.8.1"
147
+ },
148
+ "engines": {
149
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0",
150
+ "npm": ">=10"
151
+ }
152
+ },
140
153
  "node_modules/@appium/logger": {
141
154
  "version": "2.0.9",
142
155
  "resolved": "https://registry.npmjs.org/@appium/logger/-/logger-2.0.9.tgz",
@@ -215,64 +228,7 @@
215
228
  "sharp": "0.35.1"
216
229
  }
217
230
  },
218
- "node_modules/@appium/types": {
219
- "version": "1.5.1",
220
- "resolved": "https://registry.npmjs.org/@appium/types/-/types-1.5.1.tgz",
221
- "integrity": "sha512-cQkbSh6AwEGlowfKBxVngtBc5fkqAPmg4WdjGZ2txa81lpfuNTLX50VWM8Nxf3hiCgRMsRVfBWdU9x38OJqDrQ==",
222
- "license": "Apache-2.0",
223
- "dependencies": {
224
- "@appium/schema": "1.2.1",
225
- "type-fest": "5.7.0"
226
- },
227
- "engines": {
228
- "node": "^20.19.0 || ^22.12.0 || >=24.0.0",
229
- "npm": ">=10"
230
- },
231
- "peerDependencies": {
232
- "@appium/logger": "^2.0.0"
233
- }
234
- },
235
- "node_modules/@colors/colors": {
236
- "version": "1.6.0",
237
- "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
238
- "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
239
- "license": "MIT",
240
- "engines": {
241
- "node": ">=0.1.90"
242
- }
243
- },
244
- "node_modules/@dabh/diagnostics": {
245
- "version": "2.0.8",
246
- "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz",
247
- "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==",
248
- "license": "MIT",
249
- "dependencies": {
250
- "@so-ric/colorspace": "^1.1.6",
251
- "enabled": "2.0.x",
252
- "kuler": "^2.0.0"
253
- }
254
- },
255
- "node_modules/@emnapi/runtime": {
256
- "version": "1.11.1",
257
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
258
- "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
259
- "extraneous": true,
260
- "license": "MIT",
261
- "dependencies": {
262
- "tslib": "^2.4.0"
263
- }
264
- },
265
- "node_modules/@img/colour": {
266
- "version": "1.1.0",
267
- "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
268
- "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
269
- "devOptional": true,
270
- "license": "MIT",
271
- "engines": {
272
- "node": ">=18"
273
- }
274
- },
275
- "node_modules/@img/sharp-libvips-linux-x64": {
231
+ "node_modules/@appium/support/node_modules/@img/sharp-libvips-linux-x64": {
276
232
  "version": "1.3.0",
277
233
  "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.0.tgz",
278
234
  "integrity": "sha512-y9RNUYDe2A1UAdhLyfeOodGRszQdaEoe4nfOpp/sNVPl2CWIcUyFaDoCh4vPLPxu19803j2naLqZup2WxDXCLA==",
@@ -291,7 +247,7 @@
291
247
  "url": "https://opencollective.com/libvips"
292
248
  }
293
249
  },
294
- "node_modules/@img/sharp-linux-x64": {
250
+ "node_modules/@appium/support/node_modules/@img/sharp-linux-x64": {
295
251
  "version": "0.35.1",
296
252
  "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.1.tgz",
297
253
  "integrity": "sha512-NbJD4mWdeyrNQKluO/tR/wBDOelcowSVGNBWxI0e3ZtlXc6F/UOVKDj1MLD4zl3oHTuvKW3s+MA9N54YTldAYw==",
@@ -316,7 +272,7 @@
316
272
  "@img/sharp-libvips-linux-x64": "1.3.0"
317
273
  }
318
274
  },
319
- "node_modules/@img/sharp-wasm32": {
275
+ "node_modules/@appium/support/node_modules/@img/sharp-wasm32": {
320
276
  "version": "0.35.1",
321
277
  "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.1.tgz",
322
278
  "integrity": "sha512-PCQUoQdZyE8tp3HpbevuihfUmgSP4qWI0FGEPWoeXqaS+cUrFfemabHQiebUmUmlUhCuNnQMxGrQ+CPqK4hnxg==",
@@ -332,6 +288,121 @@
332
288
  "url": "https://opencollective.com/libvips"
333
289
  }
334
290
  },
291
+ "node_modules/@appium/support/node_modules/sharp": {
292
+ "version": "0.35.1",
293
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.1.tgz",
294
+ "integrity": "sha512-lW979AMi+ESidzMv/Lnv+F9bknzLyxLqFI05Sm433vOeRcltgxQmXpnfOOFIAlKtwXU/ksupm2srQoFCkR214g==",
295
+ "license": "Apache-2.0",
296
+ "optional": true,
297
+ "dependencies": {
298
+ "@img/colour": "^1.1.0",
299
+ "detect-libc": "^2.1.2",
300
+ "semver": "^7.8.4"
301
+ },
302
+ "engines": {
303
+ "node": ">=20.9.0"
304
+ },
305
+ "funding": {
306
+ "url": "https://opencollective.com/libvips"
307
+ },
308
+ "optionalDependencies": {
309
+ "@img/sharp-darwin-arm64": "0.35.1",
310
+ "@img/sharp-darwin-x64": "0.35.1",
311
+ "@img/sharp-freebsd-wasm32": "0.35.1",
312
+ "@img/sharp-libvips-darwin-arm64": "1.3.0",
313
+ "@img/sharp-libvips-darwin-x64": "1.3.0",
314
+ "@img/sharp-libvips-linux-arm": "1.3.0",
315
+ "@img/sharp-libvips-linux-arm64": "1.3.0",
316
+ "@img/sharp-libvips-linux-ppc64": "1.3.0",
317
+ "@img/sharp-libvips-linux-riscv64": "1.3.0",
318
+ "@img/sharp-libvips-linux-s390x": "1.3.0",
319
+ "@img/sharp-libvips-linux-x64": "1.3.0",
320
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.0",
321
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.0",
322
+ "@img/sharp-linux-arm": "0.35.1",
323
+ "@img/sharp-linux-arm64": "0.35.1",
324
+ "@img/sharp-linux-ppc64": "0.35.1",
325
+ "@img/sharp-linux-riscv64": "0.35.1",
326
+ "@img/sharp-linux-s390x": "0.35.1",
327
+ "@img/sharp-linux-x64": "0.35.1",
328
+ "@img/sharp-linuxmusl-arm64": "0.35.1",
329
+ "@img/sharp-linuxmusl-x64": "0.35.1",
330
+ "@img/sharp-webcontainers-wasm32": "0.35.1",
331
+ "@img/sharp-win32-arm64": "0.35.1",
332
+ "@img/sharp-win32-ia32": "0.35.1",
333
+ "@img/sharp-win32-x64": "0.35.1"
334
+ }
335
+ },
336
+ "node_modules/@appium/support/node_modules/teen_process": {
337
+ "version": "4.1.3",
338
+ "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-4.1.3.tgz",
339
+ "integrity": "sha512-8W7Xp7WtJ5ZXjv0iHMsCgPPKzUt6ACfG/rDWX0tMIlMJaYcTYsPw3ZQQ9+hG7YsY+gm+DUATiyah3AraJ9JYpg==",
340
+ "license": "Apache-2.0",
341
+ "dependencies": {
342
+ "shell-quote": "^1.8.1"
343
+ },
344
+ "engines": {
345
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0",
346
+ "npm": ">=10"
347
+ }
348
+ },
349
+ "node_modules/@appium/types": {
350
+ "version": "1.5.1",
351
+ "resolved": "https://registry.npmjs.org/@appium/types/-/types-1.5.1.tgz",
352
+ "integrity": "sha512-cQkbSh6AwEGlowfKBxVngtBc5fkqAPmg4WdjGZ2txa81lpfuNTLX50VWM8Nxf3hiCgRMsRVfBWdU9x38OJqDrQ==",
353
+ "license": "Apache-2.0",
354
+ "dependencies": {
355
+ "@appium/schema": "1.2.1",
356
+ "type-fest": "5.7.0"
357
+ },
358
+ "engines": {
359
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0",
360
+ "npm": ">=10"
361
+ },
362
+ "peerDependencies": {
363
+ "@appium/logger": "^2.0.0"
364
+ }
365
+ },
366
+ "node_modules/@colors/colors": {
367
+ "version": "1.6.0",
368
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
369
+ "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
370
+ "license": "MIT",
371
+ "engines": {
372
+ "node": ">=0.1.90"
373
+ }
374
+ },
375
+ "node_modules/@dabh/diagnostics": {
376
+ "version": "2.0.8",
377
+ "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz",
378
+ "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==",
379
+ "license": "MIT",
380
+ "dependencies": {
381
+ "@so-ric/colorspace": "^1.1.6",
382
+ "enabled": "2.0.x",
383
+ "kuler": "^2.0.0"
384
+ }
385
+ },
386
+ "node_modules/@emnapi/runtime": {
387
+ "version": "1.11.1",
388
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
389
+ "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
390
+ "extraneous": true,
391
+ "license": "MIT",
392
+ "dependencies": {
393
+ "tslib": "^2.4.0"
394
+ }
395
+ },
396
+ "node_modules/@img/colour": {
397
+ "version": "1.1.0",
398
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
399
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
400
+ "devOptional": true,
401
+ "license": "MIT",
402
+ "engines": {
403
+ "node": ">=18"
404
+ }
405
+ },
335
406
  "node_modules/@so-ric/colorspace": {
336
407
  "version": "1.1.6",
337
408
  "resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz",
@@ -423,9 +494,9 @@
423
494
  }
424
495
  },
425
496
  "node_modules/appium-ios-device": {
426
- "version": "3.1.14",
427
- "resolved": "https://registry.npmjs.org/appium-ios-device/-/appium-ios-device-3.1.14.tgz",
428
- "integrity": "sha512-fjqh1oPYQ2C4v96OLhom3HCK6j2NRO0TYOgZXtT9vEEjug/Z25NAjxlLnQLBe7aAHxR2c0V/SyFmLTEBs/Ih5A==",
497
+ "version": "3.1.15",
498
+ "resolved": "https://registry.npmjs.org/appium-ios-device/-/appium-ios-device-3.1.15.tgz",
499
+ "integrity": "sha512-NyUc71Fd5KDz03+4iZlhu/79HTa0sAF2Um1S1MkKOfkzCLLSlDxEwQe1wBPD/aCx1Ix+MeRD/mzUCQS1o3h/2Q==",
429
500
  "license": "Apache-2.0",
430
501
  "dependencies": {
431
502
  "@appium/support": "^7.2.2",
@@ -442,9 +513,9 @@
442
513
  }
443
514
  },
444
515
  "node_modules/appium-ios-remotexpc": {
445
- "version": "5.0.1",
446
- "resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-5.0.1.tgz",
447
- "integrity": "sha512-7PpZWDZoA3JMQblrYsvoSSdrhTpWBXS4/AhwQeN+hGmA3dl7jAXZc7V9bJv6c1+nNINgfgGfUYeHGA2uFyx7Qw==",
516
+ "version": "5.1.0",
517
+ "resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-5.1.0.tgz",
518
+ "integrity": "sha512-/q6C2Rwreg69p6R/d29nkdjQewJzjenIAhGPHQiO5PM51JHcPXB6DPwVL5O49iin0eAGgFahp33aGsX+92WANA==",
448
519
  "license": "Apache-2.0",
449
520
  "optional": true,
450
521
  "dependencies": {
@@ -466,9 +537,9 @@
466
537
  }
467
538
  },
468
539
  "node_modules/appium-ios-simulator": {
469
- "version": "8.2.1",
470
- "resolved": "https://registry.npmjs.org/appium-ios-simulator/-/appium-ios-simulator-8.2.1.tgz",
471
- "integrity": "sha512-n2CRpfc56xsZbYrAmgACas+Liij4B1yYNH7PyNkMpS1vSFxu4pyD6hD9sF8vsxWSlyZ4dh78r14xnkzaTWuYsg==",
540
+ "version": "8.2.2",
541
+ "resolved": "https://registry.npmjs.org/appium-ios-simulator/-/appium-ios-simulator-8.2.2.tgz",
542
+ "integrity": "sha512-NmpbM+CpnSHNoEvCYWXkzvh+fhNd8pcYhpIirw/hvlVbZnG/Gs0Bw6+sU20uOw8O/uzziEgC6odogzpJ4AO70Q==",
472
543
  "license": "Apache-2.0",
473
544
  "dependencies": {
474
545
  "@appium/support": "^7.2.2",
@@ -504,9 +575,9 @@
504
575
  }
505
576
  },
506
577
  "node_modules/appium-remote-debugger": {
507
- "version": "15.10.4",
508
- "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-15.10.4.tgz",
509
- "integrity": "sha512-M/hafP6/AFfCrHGYBbaJ957IP9GRk63QOj4OIQdR+LO8GEYX7bdloAeR+AnPZ/I/IZIYoCpih/JhpVNHDR2hsA==",
578
+ "version": "15.10.5",
579
+ "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-15.10.5.tgz",
580
+ "integrity": "sha512-FV08kyPaCr3vyojGEXzH+ZJK2BtOABoLWj2PCdSDLyxrAVO5mU3OEl0Q6Wt36QTtlVV1BG6/WMg7przBxf1Z1Q==",
510
581
  "license": "Apache-2.0",
511
582
  "dependencies": {
512
583
  "@appium/base-driver": "^10.0.0-rc.1",
@@ -546,9 +617,9 @@
546
617
  }
547
618
  },
548
619
  "node_modules/appium-xcode": {
549
- "version": "6.2.2",
550
- "resolved": "https://registry.npmjs.org/appium-xcode/-/appium-xcode-6.2.2.tgz",
551
- "integrity": "sha512-THnFNNPW2M680OzSdyHHcvF46CusrvW+/t+zCvVA+MK/sO1AE22GIHoUScbl8HeRxVI9gf1SsXravNSh8OoNaA==",
620
+ "version": "6.2.3",
621
+ "resolved": "https://registry.npmjs.org/appium-xcode/-/appium-xcode-6.2.3.tgz",
622
+ "integrity": "sha512-3gWejSeYilKJ4LJ52EFzoTbuxnK1gfhfGK57c12SaRGKdEqSpas2BLl5p61BmvUAfQnITiVEtz8M0Aw7IP9Kfg==",
552
623
  "license": "Apache-2.0",
553
624
  "dependencies": {
554
625
  "@appium/support": "^7.2.2",
@@ -2433,9 +2504,9 @@
2433
2504
  }
2434
2505
  },
2435
2506
  "node_modules/node-simctl": {
2436
- "version": "8.2.3",
2437
- "resolved": "https://registry.npmjs.org/node-simctl/-/node-simctl-8.2.3.tgz",
2438
- "integrity": "sha512-udjYoXRsApFQP0fggKwGWFWUqinJKY11zIUmMxMv8Q4sfMLV0Uu9iavRUfiB3QOmJvL4WAXTaHv+tZvkiT+nyQ==",
2507
+ "version": "8.2.4",
2508
+ "resolved": "https://registry.npmjs.org/node-simctl/-/node-simctl-8.2.4.tgz",
2509
+ "integrity": "sha512-c2sgKgN7TUHE1o0/WJMLt1tqJKUCVzFL4m+I2WCQ06CgALDz1YaqHw1SR8SXHuHNJyRkuoWfHfCMXHFUcQEwpg==",
2439
2510
  "license": "Apache-2.0",
2440
2511
  "dependencies": {
2441
2512
  "@appium/logger": "^2.0.0-rc.1",
@@ -3099,51 +3170,6 @@
3099
3170
  "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
3100
3171
  "license": "ISC"
3101
3172
  },
3102
- "node_modules/sharp": {
3103
- "version": "0.35.1",
3104
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.1.tgz",
3105
- "integrity": "sha512-lW979AMi+ESidzMv/Lnv+F9bknzLyxLqFI05Sm433vOeRcltgxQmXpnfOOFIAlKtwXU/ksupm2srQoFCkR214g==",
3106
- "devOptional": true,
3107
- "license": "Apache-2.0",
3108
- "dependencies": {
3109
- "@img/colour": "^1.1.0",
3110
- "detect-libc": "^2.1.2",
3111
- "semver": "^7.8.4"
3112
- },
3113
- "engines": {
3114
- "node": ">=20.9.0"
3115
- },
3116
- "funding": {
3117
- "url": "https://opencollective.com/libvips"
3118
- },
3119
- "optionalDependencies": {
3120
- "@img/sharp-darwin-arm64": "0.35.1",
3121
- "@img/sharp-darwin-x64": "0.35.1",
3122
- "@img/sharp-freebsd-wasm32": "0.35.1",
3123
- "@img/sharp-libvips-darwin-arm64": "1.3.0",
3124
- "@img/sharp-libvips-darwin-x64": "1.3.0",
3125
- "@img/sharp-libvips-linux-arm": "1.3.0",
3126
- "@img/sharp-libvips-linux-arm64": "1.3.0",
3127
- "@img/sharp-libvips-linux-ppc64": "1.3.0",
3128
- "@img/sharp-libvips-linux-riscv64": "1.3.0",
3129
- "@img/sharp-libvips-linux-s390x": "1.3.0",
3130
- "@img/sharp-libvips-linux-x64": "1.3.0",
3131
- "@img/sharp-libvips-linuxmusl-arm64": "1.3.0",
3132
- "@img/sharp-libvips-linuxmusl-x64": "1.3.0",
3133
- "@img/sharp-linux-arm": "0.35.1",
3134
- "@img/sharp-linux-arm64": "0.35.1",
3135
- "@img/sharp-linux-ppc64": "0.35.1",
3136
- "@img/sharp-linux-riscv64": "0.35.1",
3137
- "@img/sharp-linux-s390x": "0.35.1",
3138
- "@img/sharp-linux-x64": "0.35.1",
3139
- "@img/sharp-linuxmusl-arm64": "0.35.1",
3140
- "@img/sharp-linuxmusl-x64": "0.35.1",
3141
- "@img/sharp-webcontainers-wasm32": "0.35.1",
3142
- "@img/sharp-win32-arm64": "0.35.1",
3143
- "@img/sharp-win32-ia32": "0.35.1",
3144
- "@img/sharp-win32-x64": "0.35.1"
3145
- }
3146
- },
3147
3173
  "node_modules/shebang-command": {
3148
3174
  "version": "2.0.0",
3149
3175
  "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -3461,9 +3487,9 @@
3461
3487
  }
3462
3488
  },
3463
3489
  "node_modules/teen_process": {
3464
- "version": "4.1.3",
3465
- "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-4.1.3.tgz",
3466
- "integrity": "sha512-8W7Xp7WtJ5ZXjv0iHMsCgPPKzUt6ACfG/rDWX0tMIlMJaYcTYsPw3ZQQ9+hG7YsY+gm+DUATiyah3AraJ9JYpg==",
3490
+ "version": "4.1.5",
3491
+ "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-4.1.5.tgz",
3492
+ "integrity": "sha512-XQ4MDij09YygEZyXD6QFKfWhAi7efiEQ4fM2ACNDgkj/LO5mZWi2bR5ghNEU232mMx4+MLrNwV95BV4S+4PGsg==",
3467
3493
  "license": "Apache-2.0",
3468
3494
  "dependencies": {
3469
3495
  "shell-quote": "^1.8.1"
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "xcuitest",
9
9
  "xctest"
10
10
  ],
11
- "version": "11.12.0",
11
+ "version": "11.12.2",
12
12
  "author": "Appium Contributors",
13
13
  "license": "Apache-2.0",
14
14
  "repository": {
@@ -107,7 +107,7 @@
107
107
  "ws": "^8.13.0"
108
108
  },
109
109
  "optionalDependencies": {
110
- "appium-ios-remotexpc": "^5.0.0"
110
+ "appium-ios-remotexpc": "^5.1.0"
111
111
  },
112
112
  "scripts": {
113
113
  "build": "tsc -b",
@@ -27,6 +27,9 @@ import {Command} from 'commander';
27
27
  const log = logger.getLogger('TunnelCreation');
28
28
  const TUNNEL_REGISTRY_PORT = 'tunnelRegistryPort';
29
29
  const DEFAULT_TUNNEL_REGISTRY_PORT = 42314;
30
+ const WIRELESS_APPLETV_DISCOVERY_PROGRESS_INTERVAL_MS = 1000;
31
+ const WIRELESS_APPLETV_DISCOVERY_TIMEOUT_MS = 10_000;
32
+ const WIRELESS_APPLETV_DISCOVERY_PROGRESS_BAR_WIDTH = 24;
30
33
 
31
34
  /**
32
35
  * TunnelCreator class for managing tunnel creation and related operations (USB and optional Apple TV over WiFi).
@@ -122,7 +125,7 @@ class TunnelCreator {
122
125
  */
123
126
  async cleanup() {
124
127
  this._isCleaningUp = true;
125
- log.warn('Cleaning up tunnel resources...');
128
+ log.info('Cleaning up tunnel resources...');
126
129
  /** @type {Error[]} */
127
130
  const cleanupErrors = [];
128
131
  const recordCleanupError = (message, err) => {
@@ -349,21 +352,24 @@ class TunnelCreator {
349
352
  /**
350
353
  * Sets up tunnel(s) for paired Apple TV device(s) over WiFi.
351
354
  * @param {string[]|undefined} [specificDeviceIds] - Optional Apple TV device identifiers to target.
352
- * @param {string[]|null} [prefetchedDeviceIds] - Optional prefetched Apple TV identifiers.
355
+ * @param {AppleTVDevice[] | null} [prefetchedDevices] - Optional prefetched Apple TV devices.
353
356
  * @returns {Promise<AppleTVTunnelResult[]>} Apple TV tunnel results.
354
357
  */
355
- async setupAppleTVTunnels(specificDeviceIds, prefetchedDeviceIds = null) {
358
+ async setupAppleTVTunnels(specificDeviceIds, prefetchedDevices = null) {
356
359
  /** @type {AppleTVTunnelResult[]} */
357
360
  const results = [];
358
361
 
359
362
  try {
360
- if ((!specificDeviceIds || specificDeviceIds.length === 0) && prefetchedDeviceIds === null) {
361
- log.warn('Skipping Apple TV tunnel setup because discovery prefetch did not return device IDs.');
363
+ if ((!specificDeviceIds || specificDeviceIds.length === 0) && prefetchedDevices === null) {
364
+ log.info('Skipping Apple TV tunnel setup because wireless discovery did not find any devices.');
362
365
  return results;
363
366
  }
367
+ const prefetchedDevicesById = new Map(
368
+ (prefetchedDevices ?? []).map((device) => [device.identifier, device]),
369
+ );
364
370
  const discoveredDeviceIds = specificDeviceIds && specificDeviceIds.length > 0
365
371
  ? [...new Set(specificDeviceIds)]
366
- : /** @type {string[]} */ (prefetchedDeviceIds);
372
+ : [...prefetchedDevicesById.keys()];
367
373
  log.info('Starting Apple TV tunnel (WiFi)...');
368
374
  const usbDiscoveredUdidSet = new Set(this._usbDevicesByUdid.keys());
369
375
  const targetDeviceIds = discoveredDeviceIds.filter((udid) => !usbDiscoveredUdidSet.has(udid));
@@ -380,7 +386,10 @@ class TunnelCreator {
380
386
 
381
387
  for (const deviceId of targetDeviceIds) {
382
388
  try {
383
- const result = await this._createAppleTVTunnelForUdid(deviceId);
389
+ const result = await this._createAppleTVTunnelForUdid(
390
+ deviceId,
391
+ prefetchedDevicesById.get(deviceId),
392
+ );
384
393
  results.push(result);
385
394
  log.info(`✅ Apple TV tunnel ready for ${deviceId}`);
386
395
  } catch (err) {
@@ -403,39 +412,50 @@ class TunnelCreator {
403
412
 
404
413
  /**
405
414
  * @param {string[] | undefined} specificDeviceIds
406
- * @returns {Promise<string[] | null>}
415
+ * @returns {{startedAt: number, promise: Promise<{devices: AppleTVDevice[] | null, error: unknown | null}>}}
407
416
  */
408
- async prefetchAppleTVDeviceIds(specificDeviceIds) {
417
+ prefetchAppleTVDevices(specificDeviceIds) {
418
+ const startedAt = performance.now();
409
419
  if (specificDeviceIds && specificDeviceIds.length > 0) {
410
- return [...new Set(specificDeviceIds)];
420
+ return {
421
+ startedAt,
422
+ promise: Promise.resolve({devices: null, error: null}),
423
+ };
411
424
  }
412
425
  const tunnelService = new AppleTVTunnelService();
413
- try {
414
- log.info('Prefetching paired Apple TV devices in parallel...');
415
- const devices = await tunnelService.discoverDevices();
416
- return devices.map((d) => d.identifier);
417
- } catch (err) {
418
- log.warn(`Apple TV discovery prefetch failed: ${err?.message ?? err}`);
419
- return null;
420
- } finally {
426
+ const promise = (async () => {
421
427
  try {
422
- tunnelService.disconnect();
423
- } catch {}
424
- }
428
+ const devices = await tunnelService.discoverDevices({
429
+ timeoutMs: WIRELESS_APPLETV_DISCOVERY_TIMEOUT_MS,
430
+ });
431
+ return {devices, error: null};
432
+ } catch (err) {
433
+ return {devices: null, error: err};
434
+ } finally {
435
+ try {
436
+ tunnelService.disconnect();
437
+ } catch {}
438
+ }
439
+ })();
440
+ return {startedAt, promise};
425
441
  }
426
442
 
427
443
  /**
428
444
  * @param {string} udid
445
+ * @param {AppleTVDevice | undefined} [prefetchedDevice]
429
446
  * @returns {Promise<AppleTVTunnelResult>}
430
447
  */
431
- async _createAppleTVTunnelForUdid(udid) {
448
+ async _createAppleTVTunnelForUdid(udid, prefetchedDevice) {
432
449
  let tunnelService = this._appletvTunnelServicesByUdid.get(udid);
433
450
  if (!tunnelService) {
434
451
  tunnelService = new AppleTVTunnelService();
435
452
  this._appletvTunnelServicesByUdid.set(udid, tunnelService);
436
453
  }
437
454
 
438
- const startResult = await tunnelService.startTunnel(undefined, udid);
455
+ const startResult = await tunnelService.startTunnel(undefined, udid, {
456
+ devices: prefetchedDevice ? [prefetchedDevice] : undefined,
457
+ discoveryTimeoutMs: WIRELESS_APPLETV_DISCOVERY_TIMEOUT_MS,
458
+ });
439
459
  if (!startResult.tcpSocket) {
440
460
  throw new Error('Apple TV TCP socket to listener port not established');
441
461
  }
@@ -711,6 +731,42 @@ function getTunnelUdid(result) {
711
731
  return /** @type {{ identifier: string }} */ (result.device).identifier;
712
732
  }
713
733
 
734
+ /**
735
+ * @param {unknown} err
736
+ * @returns {boolean}
737
+ */
738
+ function isNoAppleTVDevicesFoundError(err) {
739
+ return (err instanceof Error ? err.message : String(err)) === 'No devices found via discovery backend';
740
+ }
741
+
742
+ /**
743
+ * @param {{startedAt: number, promise: Promise<{devices: AppleTVDevice[] | null, error: unknown | null}>}} discovery
744
+ * @returns {Promise<AppleTVDevice[] | null>}
745
+ */
746
+ async function waitForAppleTVDiscovery(discovery) {
747
+ const wirelessDiscoveryProgress = startTimeoutProgressLogger({
748
+ label: 'Waiting for wireless Apple TV discovery',
749
+ startedAt: discovery.startedAt,
750
+ timeoutMs: WIRELESS_APPLETV_DISCOVERY_TIMEOUT_MS,
751
+ barWidth: WIRELESS_APPLETV_DISCOVERY_PROGRESS_BAR_WIDTH,
752
+ intervalMs: WIRELESS_APPLETV_DISCOVERY_PROGRESS_INTERVAL_MS,
753
+ });
754
+ const {devices, error} = await discovery.promise;
755
+ if (error) {
756
+ if (isNoAppleTVDevicesFoundError(error)) {
757
+ wirelessDiscoveryProgress.succeed('No wireless Apple TV devices found');
758
+ } else {
759
+ wirelessDiscoveryProgress.fail('Wireless Apple TV discovery failed');
760
+ log.warn(error);
761
+ }
762
+ return null;
763
+ }
764
+ wirelessDiscoveryProgress.succeed(
765
+ `Wireless Apple TV discovery completed: ${devices?.length ?? 0} device(s) found`,
766
+ );
767
+ return devices;
768
+ }
769
+
714
770
  /**
715
771
  * @param {number} ms
716
772
  * @returns {Promise<void>}
@@ -719,6 +775,51 @@ async function sleep(ms) {
719
775
  await new Promise((resolve) => setTimeout(resolve, ms));
720
776
  }
721
777
 
778
+ /**
779
+ * Logs a timeout-based progress bar while an operation without native progress callbacks is running.
780
+ *
781
+ * @param {{label: string, startedAt: number, timeoutMs: number, barWidth: number, intervalMs: number}} opts
782
+ * @returns {{succeed: (message?: string) => void, fail: (message?: string) => void}}
783
+ */
784
+ function startTimeoutProgressLogger({label, startedAt, timeoutMs, barWidth, intervalMs}) {
785
+ /** @type {NodeJS.Timeout | null} */
786
+ let timer = null;
787
+ let isStopped = false;
788
+
789
+ const logProgress = (status, isComplete = false) => {
790
+ const elapsedMs = performance.now() - startedAt;
791
+ const boundedElapsedMs = Math.min(elapsedMs, timeoutMs);
792
+ const progress = isComplete ? 1 : boundedElapsedMs / timeoutMs;
793
+ const filledWidth = Math.round(progress * barWidth);
794
+ const emptyWidth = barWidth - filledWidth;
795
+ const bar = `${'#'.repeat(filledWidth)}${'-'.repeat(emptyWidth)}`;
796
+ log.info(`${label}: [${bar}]${status && status !== 'waiting' ? ` - ${status}` : ''}`);
797
+ };
798
+
799
+ const stop = (status, isComplete = false) => {
800
+ if (isStopped) {
801
+ return;
802
+ }
803
+ isStopped = true;
804
+ if (timer) {
805
+ clearInterval(timer);
806
+ timer = null;
807
+ }
808
+ logProgress(status, isComplete);
809
+ };
810
+
811
+ logProgress('waiting');
812
+ timer = setInterval(() => {
813
+ logProgress('waiting');
814
+ }, intervalMs);
815
+ timer.unref?.();
816
+
817
+ return {
818
+ succeed: (message = 'done') => stop(message, true),
819
+ fail: (message = 'failed') => stop(message),
820
+ };
821
+ }
822
+
722
823
  /**
723
824
  * @param {string} value
724
825
  * @param {string} label
@@ -791,6 +892,10 @@ function setupCleanupHandlers(tunnelCreator) {
791
892
  }
792
893
  }
793
894
  };
895
+ const cleanupAndExit = async () => {
896
+ await cleanupOnce();
897
+ process.exit(process.exitCode ?? 1);
898
+ };
794
899
 
795
900
  const shutdownSignals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
796
901
  for (const signal of shutdownSignals) {
@@ -813,7 +918,7 @@ function setupCleanupHandlers(tunnelCreator) {
813
918
  if (process.exitCode == null) {
814
919
  process.exitCode = 1;
815
920
  }
816
- void cleanupOnce();
921
+ void cleanupAndExit();
817
922
  });
818
923
 
819
924
  process.on('uncaughtException', (err) => {
@@ -821,7 +926,7 @@ function setupCleanupHandlers(tunnelCreator) {
821
926
  if (process.exitCode == null) {
822
927
  process.exitCode = 1;
823
928
  }
824
- void cleanupOnce();
929
+ void cleanupAndExit();
825
930
  });
826
931
 
827
932
  return cleanupOnce;
@@ -916,9 +1021,12 @@ async function main() {
916
1021
 
917
1022
  await tunnelCreator.startRegistryServer();
918
1023
 
919
- const prefetchedAppleTVDeviceIdsPromise = shouldRunAppleTVFlow
920
- ? tunnelCreator.prefetchAppleTVDeviceIds(requestedAppleTVIds)
921
- : Promise.resolve(null);
1024
+ const appleTVDiscoveryPrefetch = shouldRunAppleTVFlow && !hasRequestedAppleTVIds
1025
+ ? tunnelCreator.prefetchAppleTVDevices(requestedAppleTVIds)
1026
+ : null;
1027
+ if (appleTVDiscoveryPrefetch) {
1028
+ log.info('Prefetching paired Apple TV devices...');
1029
+ }
922
1030
 
923
1031
  const usbmux = await createUsbmux();
924
1032
  /** @type {UsbTunnelResult[]} */
@@ -937,10 +1045,12 @@ async function main() {
937
1045
  /** @type {AppleTVTunnelResult[]} */
938
1046
  let appletvResults = [];
939
1047
  if (shouldRunAppleTVFlow) {
940
- const prefetchedAppleTVDeviceIds = await prefetchedAppleTVDeviceIdsPromise;
1048
+ const prefetchedAppleTVDevices = appleTVDiscoveryPrefetch
1049
+ ? await waitForAppleTVDiscovery(appleTVDiscoveryPrefetch)
1050
+ : null;
941
1051
  appletvResults = await tunnelCreator.setupAppleTVTunnels(
942
1052
  requestedAppleTVIds,
943
- prefetchedAppleTVDeviceIds,
1053
+ prefetchedAppleTVDevices,
944
1054
  );
945
1055
  } else {
946
1056
  log.info('Skipping Apple TV tunnel setup because only --udid was provided.');
@@ -952,7 +1062,8 @@ async function main() {
952
1062
  ];
953
1063
 
954
1064
  if (successfulResults.length === 0) {
955
- log.warn('No tunnels created (no USB devices and no Apple TV tunnel).');
1065
+ log.warn('No tunnels created (no USB and no wireless Apple TV devices).');
1066
+ await cleanupOnce();
956
1067
  return;
957
1068
  }
958
1069
 
@@ -990,7 +1101,9 @@ async function main() {
990
1101
  }
991
1102
  } catch (err) {
992
1103
  log.error('Error during tunnel setup:', err);
1104
+ process.exitCode = 1;
993
1105
  await cleanupOnce();
1106
+ process.exit(process.exitCode);
994
1107
  }
995
1108
  }
996
1109
 
@@ -1012,6 +1125,10 @@ await main();
1012
1125
  * @typedef {UsbTunnelSuccess | UsbTunnelFailure} UsbTunnelResult
1013
1126
  */
1014
1127
 
1128
+ /**
1129
+ * @typedef {Awaited<ReturnType<import('appium-ios-remotexpc').AppleTVTunnelService['discoverDevices']>>[number]} AppleTVDevice
1130
+ */
1131
+
1015
1132
  /**
1016
1133
  * @typedef {EstablishedTunnel & { kind: 'appletv', device: { identifier: string, name?: string }, success: true, tunnelService: import('appium-ios-remotexpc').AppleTVTunnelService }} AppleTVTunnelSuccess
1017
1134
  * @typedef {Object & { kind: 'appletv', device: { identifier: string }, success: false, error: string }} AppleTVTunnelFailure