@midscene/ios 0.30.10 → 1.0.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 (65) hide show
  1. package/README.md +11 -11
  2. package/dist/es/bin.mjs +423 -327
  3. package/dist/es/index.mjs +150 -64
  4. package/dist/lib/bin.js +393 -283
  5. package/dist/lib/index.js +155 -69
  6. package/dist/types/index.d.ts +88 -14
  7. package/package.json +8 -7
  8. package/static/index.html +1 -1
  9. package/static/static/css/index.d32b7df9.css +2 -0
  10. package/static/static/css/index.d32b7df9.css.map +1 -0
  11. package/static/static/js/79.25af61dc.js +611 -0
  12. package/static/static/js/{931.dc961e99.js.LICENSE.txt → 79.25af61dc.js.LICENSE.txt} +0 -4
  13. package/static/static/js/79.25af61dc.js.map +1 -0
  14. package/static/static/js/async/195.0366f6e8.js +3 -0
  15. package/static/static/js/async/195.0366f6e8.js.map +1 -0
  16. package/static/static/js/async/{702.60261735.js → 199.f31e52e7.js} +20 -20
  17. package/static/static/js/async/199.f31e52e7.js.map +1 -0
  18. package/static/static/js/async/221.591b048e.js +21 -0
  19. package/static/static/js/async/221.591b048e.js.map +1 -0
  20. package/static/static/js/async/271.15d46ff8.js +30 -0
  21. package/static/static/js/async/271.15d46ff8.js.map +1 -0
  22. package/static/static/js/async/35.2b64fb0f.js +1 -0
  23. package/static/static/js/async/{644.6bdc4065.js → 467.710fa05a.js} +1 -1
  24. package/static/static/js/async/652.b5a7c7b4.js +3 -0
  25. package/static/static/js/async/652.b5a7c7b4.js.map +1 -0
  26. package/static/static/js/async/856.be9fd814.js +158 -0
  27. package/static/static/js/async/{212.e243c338.js.map → 856.be9fd814.js.map} +1 -1
  28. package/static/static/js/async/860.b56301d9.js +2 -0
  29. package/static/static/js/async/860.b56301d9.js.map +1 -0
  30. package/static/static/js/async/990.82a78a53.js +26 -0
  31. package/static/static/js/async/990.82a78a53.js.map +1 -0
  32. package/static/static/js/index.0930f837.js +10 -0
  33. package/static/static/js/index.0930f837.js.map +1 -0
  34. package/static/static/js/lib-react.7b1abe58.js +3 -0
  35. package/static/static/js/lib-react.7b1abe58.js.map +1 -0
  36. package/static/static/css/index.44466eb4.css +0 -2
  37. package/static/static/css/index.44466eb4.css.map +0 -1
  38. package/static/static/js/931.dc961e99.js +0 -620
  39. package/static/static/js/931.dc961e99.js.map +0 -1
  40. package/static/static/js/async/173.9cf6b074.js +0 -3
  41. package/static/static/js/async/173.9cf6b074.js.map +0 -1
  42. package/static/static/js/async/212.e243c338.js +0 -158
  43. package/static/static/js/async/329.f888b505.js +0 -26
  44. package/static/static/js/async/329.f888b505.js.map +0 -1
  45. package/static/static/js/async/364.1821e74b.js +0 -30
  46. package/static/static/js/async/364.1821e74b.js.map +0 -1
  47. package/static/static/js/async/544.b73fa603.js +0 -2
  48. package/static/static/js/async/544.b73fa603.js.map +0 -1
  49. package/static/static/js/async/582.5dccae2d.js +0 -21
  50. package/static/static/js/async/582.5dccae2d.js.map +0 -1
  51. package/static/static/js/async/624.45ee2b2c.js +0 -3
  52. package/static/static/js/async/624.45ee2b2c.js.map +0 -1
  53. package/static/static/js/async/659.9afd03db.js +0 -21
  54. package/static/static/js/async/659.9afd03db.js.map +0 -1
  55. package/static/static/js/async/702.60261735.js.map +0 -1
  56. package/static/static/js/async/920.7d9a9aa8.js +0 -2
  57. package/static/static/js/async/920.7d9a9aa8.js.map +0 -1
  58. package/static/static/js/async/983.8b91303f.js +0 -1
  59. package/static/static/js/index.2caaacaf.js +0 -10
  60. package/static/static/js/index.2caaacaf.js.map +0 -1
  61. package/static/static/js/lib-react.f566a9ed.js +0 -3
  62. package/static/static/js/lib-react.f566a9ed.js.map +0 -1
  63. /package/static/static/js/{index.2caaacaf.js.LICENSE.txt → index.0930f837.js.LICENSE.txt} +0 -0
  64. /package/static/static/js/{lib-react.f566a9ed.js.LICENSE.txt → lib-react.7b1abe58.js.LICENSE.txt} +0 -0
  65. /package/static/static/wasm/{9e906fbf55e08f98.module.wasm → 9e906fbf.module.wasm} +0 -0
package/dist/es/index.mjs CHANGED
@@ -154,9 +154,8 @@ class IOSWebDriverClient extends WebDriverClient {
154
154
  this.ensureSession();
155
155
  debugIOS('Getting active element');
156
156
  try {
157
- var _response_value, _response_value1;
158
157
  const response = await this.makeRequest('GET', `/session/${this.sessionId}/element/active`);
159
- const elementId = (null == (_response_value = response.value) ? void 0 : _response_value.ELEMENT) || (null == (_response_value1 = response.value) ? void 0 : _response_value1['element-6066-11e4-a52e-4f735466cecf']) || response.ELEMENT || response['element-6066-11e4-a52e-4f735466cecf'];
158
+ const elementId = response.value?.ELEMENT || response.value?.['element-6066-11e4-a52e-4f735466cecf'] || response.ELEMENT || response['element-6066-11e4-a52e-4f735466cecf'];
160
159
  if (elementId) {
161
160
  debugIOS(`Got active element ID: ${elementId}`);
162
161
  return elementId;
@@ -233,8 +232,17 @@ class IOSWebDriverClient extends WebDriverClient {
233
232
  });
234
233
  debugIOS(`Tapped at coordinates (${x}, ${y})`);
235
234
  } catch (error) {
236
- debugIOS(`Failed to tap at (${x}, ${y}): ${error}`);
237
- throw new Error(`Failed to tap at coordinates: ${error}`);
235
+ debugIOS(`New tap endpoint failed, trying legacy endpoint: ${error}`);
236
+ try {
237
+ await this.makeRequest('POST', `/session/${this.sessionId}/wda/tap/0`, {
238
+ x,
239
+ y
240
+ });
241
+ debugIOS(`Tapped at coordinates (${x}, ${y}) using legacy endpoint`);
242
+ } catch (fallbackError) {
243
+ debugIOS(`Failed to tap at (${x}, ${y}): ${fallbackError}`);
244
+ throw new Error(`Failed to tap at coordinates: ${fallbackError}`);
245
+ }
238
246
  }
239
247
  }
240
248
  async swipe(fromX, fromY, toX, toY, duration = 500) {
@@ -307,13 +315,34 @@ class IOSWebDriverClient extends WebDriverClient {
307
315
  debugIOS(`Triple tapped at coordinates (${x}, ${y})`);
308
316
  }
309
317
  async getScreenScale() {
310
- var _screenResponse_value;
311
- const screenResponse = await this.makeRequest('GET', '/wda/screen');
312
- if (null == screenResponse ? void 0 : null == (_screenResponse_value = screenResponse.value) ? void 0 : _screenResponse_value.scale) {
313
- debugIOS(`Got screen scale from WDA screen endpoint: ${screenResponse.value.scale}`);
314
- return screenResponse.value.scale;
318
+ this.ensureSession();
319
+ try {
320
+ const screenResponse = await this.makeRequest('GET', `/session/${this.sessionId}/wda/screen`);
321
+ if (screenResponse?.value?.scale) {
322
+ debugIOS(`Got screen scale from WDA screen endpoint: ${screenResponse.value.scale}`);
323
+ return screenResponse.value.scale;
324
+ }
325
+ } catch (error) {
326
+ debugIOS(`Failed to get screen scale from /wda/screen: ${error}`);
315
327
  }
316
- debugIOS('No screen scale found in WDA screen response');
328
+ try {
329
+ debugIOS('Calculating screen scale from screenshot and window size');
330
+ const [screenshotBase64, windowSize] = await Promise.all([
331
+ this.takeScreenshot(),
332
+ this.getWindowSize()
333
+ ]);
334
+ const { jimpFromBase64 } = await import("@midscene/shared/img");
335
+ const screenshotImg = await jimpFromBase64(screenshotBase64);
336
+ const screenshotWidth = screenshotImg.bitmap.width;
337
+ const screenshotHeight = screenshotImg.bitmap.height;
338
+ const scale = Math.max(screenshotWidth, screenshotHeight) / Math.max(windowSize.width, windowSize.height);
339
+ const roundedScale = Math.round(scale);
340
+ debugIOS(`Calculated screen scale: ${roundedScale} (screenshot: ${screenshotWidth}x${screenshotHeight}, window: ${windowSize.width}x${windowSize.height})`);
341
+ return roundedScale;
342
+ } catch (error) {
343
+ debugIOS(`Failed to calculate screen scale: ${error}`);
344
+ }
345
+ debugIOS('No screen scale found');
317
346
  return null;
318
347
  }
319
348
  async createSession(capabilities) {
@@ -340,6 +369,10 @@ class IOSWebDriverClient extends WebDriverClient {
340
369
  debugIOS(`Failed to apply iOS session configuration: ${error}`);
341
370
  }
342
371
  }
372
+ async executeRequest(method, endpoint, data) {
373
+ this.ensureSession();
374
+ return this.makeRequest(method, endpoint, data);
375
+ }
343
376
  }
344
377
  function _define_property(obj, key, value) {
345
378
  if (key in obj) Object.defineProperty(obj, key, {
@@ -352,6 +385,12 @@ function _define_property(obj, key, value) {
352
385
  return obj;
353
386
  }
354
387
  const debugDevice = getDebug('ios:device');
388
+ const WDA_HTTP_METHODS = [
389
+ 'GET',
390
+ 'POST',
391
+ 'DELETE',
392
+ 'PUT'
393
+ ];
355
394
  class IOSDevice {
356
395
  actionSpace() {
357
396
  const defaultActions = [
@@ -371,7 +410,7 @@ class IOSDevice {
371
410
  interfaceAlias: 'aiInput',
372
411
  paramSchema: z.object({
373
412
  value: z.string().describe('The text to input. Provide the final content for replace/append modes, or an empty string when using clear mode to remove existing text.'),
374
- autoDismissKeyboard: z.boolean().optional().describe('If true, the keyboard will be dismissed after the input is completed. Do not set it unless the user asks you to do so.'),
413
+ autoDismissKeyboard: z.boolean().optional().describe('Whether to dismiss the keyboard after input. Defaults to true if not specified. Set to false to keep the keyboard visible after input.'),
375
414
  mode: z["enum"]([
376
415
  'replace',
377
416
  'clear',
@@ -380,14 +419,13 @@ class IOSDevice {
380
419
  locate: getMidsceneLocationSchema().describe('The input field to be filled').optional()
381
420
  }),
382
421
  call: async (param)=>{
383
- var _this_options;
384
422
  const element = param.locate;
385
423
  if (element) {
386
424
  if ('append' !== param.mode) await this.clearInput(element);
387
425
  }
388
426
  if ('clear' === param.mode) return;
389
427
  if (!param || !param.value) return;
390
- const autoDismissKeyboard = param.autoDismissKeyboard ?? (null == (_this_options = this.options) ? void 0 : _this_options.autoDismissKeyboard);
428
+ const autoDismissKeyboard = param.autoDismissKeyboard ?? this.options?.autoDismissKeyboard;
391
429
  await this.typeText(param.value, {
392
430
  autoDismissKeyboard
393
431
  });
@@ -399,18 +437,18 @@ class IOSDevice {
399
437
  left: element.center[0],
400
438
  top: element.center[1]
401
439
  } : void 0;
402
- const scrollToEventName = null == param ? void 0 : param.scrollType;
403
- if ('untilTop' === scrollToEventName) await this.scrollUntilTop(startingPoint);
404
- else if ('untilBottom' === scrollToEventName) await this.scrollUntilBottom(startingPoint);
405
- else if ('untilRight' === scrollToEventName) await this.scrollUntilRight(startingPoint);
406
- else if ('untilLeft' === scrollToEventName) await this.scrollUntilLeft(startingPoint);
407
- else if ('once' !== scrollToEventName && scrollToEventName) throw new Error(`Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(param)}`);
440
+ const scrollToEventName = param?.scrollType;
441
+ if ('scrollToTop' === scrollToEventName) await this.scrollUntilTop(startingPoint);
442
+ else if ('scrollToBottom' === scrollToEventName) await this.scrollUntilBottom(startingPoint);
443
+ else if ('scrollToRight' === scrollToEventName) await this.scrollUntilRight(startingPoint);
444
+ else if ('scrollToLeft' === scrollToEventName) await this.scrollUntilLeft(startingPoint);
445
+ else if ('singleAction' !== scrollToEventName && scrollToEventName) throw new Error(`Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(param)}`);
408
446
  else {
409
- if ((null == param ? void 0 : param.direction) !== 'down' && param && param.direction) if ('up' === param.direction) await this.scrollUp(param.distance || void 0, startingPoint);
447
+ if (param?.direction !== 'down' && param && param.direction) if ('up' === param.direction) await this.scrollUp(param.distance || void 0, startingPoint);
410
448
  else if ('left' === param.direction) await this.scrollLeft(param.distance || void 0, startingPoint);
411
449
  else if ('right' === param.direction) await this.scrollRight(param.distance || void 0, startingPoint);
412
450
  else throw new Error(`Unknown scroll direction: ${param.direction}`);
413
- else await this.scrollDown((null == param ? void 0 : param.distance) || void 0, startingPoint);
451
+ else await this.scrollDown(param?.distance || void 0, startingPoint);
414
452
  await sleep(500);
415
453
  }
416
454
  }),
@@ -424,22 +462,6 @@ class IOSDevice {
424
462
  defineActionKeyboardPress(async (param)=>{
425
463
  await this.pressKey(param.keyName);
426
464
  }),
427
- defineAction({
428
- name: 'IOSHomeButton',
429
- description: 'Trigger the system "home" operation on iOS devices',
430
- paramSchema: z.object({}),
431
- call: async ()=>{
432
- await this.home();
433
- }
434
- }),
435
- defineAction({
436
- name: 'IOSAppSwitcher',
437
- description: 'Trigger the system "app switcher" operation on iOS devices',
438
- paramSchema: z.object({}),
439
- call: async ()=>{
440
- await this.appSwitcher();
441
- }
442
- }),
443
465
  defineAction({
444
466
  name: 'IOSLongPress',
445
467
  description: 'Trigger a long press on the screen at specified coordinates on iOS devices',
@@ -451,7 +473,7 @@ class IOSDevice {
451
473
  const element = param.locate;
452
474
  node_assert(element, 'IOSLongPress requires an element to be located');
453
475
  const [x, y] = element.center;
454
- await this.longPress(x, y, null == param ? void 0 : param.duration);
476
+ await this.longPress(x, y, param?.duration);
455
477
  }
456
478
  }),
457
479
  defineActionClearInput(async (param)=>{
@@ -460,9 +482,11 @@ class IOSDevice {
460
482
  await this.clearInput(element);
461
483
  })
462
484
  ];
485
+ const platformSpecificActions = Object.values(createPlatformActions(this));
463
486
  const customActions = this.customActions || [];
464
487
  return [
465
488
  ...defaultActions,
489
+ ...platformSpecificActions,
466
490
  ...customActions
467
491
  ];
468
492
  }
@@ -479,7 +503,7 @@ class IOSDevice {
479
503
  await this.wdaManager.start();
480
504
  await this.wdaBackend.createSession();
481
505
  const deviceInfo = await this.wdaBackend.getDeviceInfo();
482
- if (null == deviceInfo ? void 0 : deviceInfo.udid) {
506
+ if (deviceInfo?.udid) {
483
507
  this.deviceId = deviceInfo.udid;
484
508
  debugDevice(`Updated device ID to real UDID: ${this.deviceId}`);
485
509
  }
@@ -587,9 +611,8 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
587
611
  await this.wdaBackend.swipe(Math.round(fromX), Math.round(fromY), Math.round(toX), Math.round(toY), duration);
588
612
  }
589
613
  async typeText(text, options) {
590
- var _this_options;
591
614
  if (!text) return;
592
- const shouldAutoDismissKeyboard = (null == options ? void 0 : options.autoDismissKeyboard) ?? (null == (_this_options = this.options) ? void 0 : _this_options.autoDismissKeyboard) ?? true;
615
+ const shouldAutoDismissKeyboard = options?.autoDismissKeyboard ?? this.options?.autoDismissKeyboard ?? true;
593
616
  debugDevice(`Typing text: "${text}"`);
594
617
  try {
595
618
  await sleep(200);
@@ -791,20 +814,30 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
791
814
  }
792
815
  async hideKeyboard(keyNames) {
793
816
  try {
794
- if (keyNames && keyNames.length > 0) {
795
- debugDevice(`Using keyNames to dismiss keyboard: ${keyNames.join(', ')}`);
796
- await this.wdaBackend.dismissKeyboard(keyNames);
797
- debugDevice('Dismissed keyboard using provided keyNames');
798
- await sleep(300);
817
+ const dismissKeys = keyNames && keyNames.length > 0 ? keyNames : [
818
+ 'return',
819
+ 'done',
820
+ 'go',
821
+ 'search',
822
+ 'next',
823
+ 'send'
824
+ ];
825
+ debugDevice(`Attempting to dismiss keyboard using WDA API with keys: ${dismissKeys.join(', ')}`);
826
+ try {
827
+ await this.wdaBackend.dismissKeyboard(dismissKeys);
828
+ debugDevice('Successfully dismissed keyboard using WDA API');
829
+ await sleep(500);
799
830
  return true;
831
+ } catch (wdaError) {
832
+ debugDevice(`WDA dismissKeyboard failed, falling back to swipe gesture: ${wdaError}`);
800
833
  }
801
834
  const windowSize = await this.wdaBackend.getWindowSize();
802
835
  const centerX = Math.round(windowSize.width / 2);
803
- const startY = Math.round(0.33 * windowSize.height);
804
- const endY = Math.round(0.33 * windowSize.height + 10);
805
- await this.swipe(centerX, startY, centerX, endY, 50);
806
- debugDevice('Dismissed keyboard with swipe down gesture at screen one-third position');
807
- await sleep(300);
836
+ const startY = Math.round(0.9 * windowSize.height);
837
+ const endY = Math.round(0.5 * windowSize.height);
838
+ await this.swipe(centerX, startY, centerX, endY, 300);
839
+ debugDevice('Dismissed keyboard with swipe up gesture from bottom of screen');
840
+ await sleep(500);
808
841
  return true;
809
842
  } catch (error) {
810
843
  debugDevice(`Failed to hide keyboard: ${error}`);
@@ -833,6 +866,7 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
833
866
  async openUrlViaSafari(url) {
834
867
  try {
835
868
  debugDevice(`Opening URL via Safari: ${url}`);
869
+ await this.wdaBackend.terminateApp('com.apple.mobilesafari');
836
870
  await this.wdaBackend.launchApp('com.apple.mobilesafari');
837
871
  await sleep(2000);
838
872
  await this.typeText(url);
@@ -850,6 +884,9 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
850
884
  throw new Error(`Failed to open URL via Safari: ${error}`);
851
885
  }
852
886
  }
887
+ async runWdaRequest(method, endpoint, data) {
888
+ return await this.wdaBackend.executeRequest(method, endpoint, data);
889
+ }
853
890
  async destroy() {
854
891
  if (this.destroyed) return;
855
892
  try {
@@ -875,9 +912,9 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
875
912
  _define_property(this, "options", void 0);
876
913
  this.deviceId = 'pending-connection';
877
914
  this.options = options;
878
- this.customActions = null == options ? void 0 : options.customActions;
879
- const wdaPort = (null == options ? void 0 : options.wdaPort) || DEFAULT_WDA_PORT;
880
- const wdaHost = (null == options ? void 0 : options.wdaHost) || 'localhost';
915
+ this.customActions = options?.customActions;
916
+ const wdaPort = options?.wdaPort || DEFAULT_WDA_PORT;
917
+ const wdaHost = options?.wdaHost || 'localhost';
881
918
  this.wdaBackend = new IOSWebDriverClient({
882
919
  port: wdaPort,
883
920
  host: wdaHost
@@ -885,6 +922,44 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
885
922
  this.wdaManager = WDAManager.getInstance(wdaPort, wdaHost);
886
923
  }
887
924
  }
925
+ const runWdaRequestParamSchema = z.object({
926
+ method: z["enum"](WDA_HTTP_METHODS).describe('HTTP method (GET, POST, DELETE, PUT)'),
927
+ endpoint: z.string().describe('WebDriver API endpoint'),
928
+ data: z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
929
+ });
930
+ const launchParamSchema = z.string().describe('App bundle ID or URL to launch');
931
+ const createPlatformActions = (device)=>({
932
+ RunWdaRequest: defineAction({
933
+ name: 'RunWdaRequest',
934
+ description: 'Execute WebDriverAgent API request directly on iOS device',
935
+ interfaceAlias: 'runWdaRequest',
936
+ paramSchema: runWdaRequestParamSchema,
937
+ call: async (param)=>await device.runWdaRequest(param.method, param.endpoint, param.data)
938
+ }),
939
+ Launch: defineAction({
940
+ name: 'Launch',
941
+ description: 'Launch an iOS app or URL',
942
+ interfaceAlias: 'launch',
943
+ paramSchema: launchParamSchema,
944
+ call: async (param)=>{
945
+ await device.launch(param);
946
+ }
947
+ }),
948
+ IOSHomeButton: defineAction({
949
+ name: 'IOSHomeButton',
950
+ description: 'Trigger the system "home" operation on iOS devices',
951
+ call: async ()=>{
952
+ await device.home();
953
+ }
954
+ }),
955
+ IOSAppSwitcher: defineAction({
956
+ name: 'IOSAppSwitcher',
957
+ description: 'Trigger the system "app switcher" operation on iOS devices',
958
+ call: async ()=>{
959
+ await device.appSwitcher();
960
+ }
961
+ })
962
+ });
888
963
  const execAsync = promisify(exec);
889
964
  const debugUtils = getDebug('ios:utils');
890
965
  function checkMacOSPlatform() {
@@ -931,24 +1006,35 @@ async function checkIOSEnvironment() {
931
1006
  };
932
1007
  }
933
1008
  }
1009
+ function agent_define_property(obj, key, value) {
1010
+ if (key in obj) Object.defineProperty(obj, key, {
1011
+ value: value,
1012
+ enumerable: true,
1013
+ configurable: true,
1014
+ writable: true
1015
+ });
1016
+ else obj[key] = value;
1017
+ return obj;
1018
+ }
934
1019
  const debugAgent = getDebug('ios:agent');
935
1020
  class IOSAgent extends Agent {
936
- async launch(uri) {
937
- const device = this.page;
938
- await device.launch(uri);
1021
+ createActionWrapper(name) {
1022
+ const action = this.wrapActionInActionSpace(name);
1023
+ return (...args)=>action(args[0]);
1024
+ }
1025
+ constructor(device, opts){
1026
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0);
1027
+ this.launch = this.createActionWrapper('Launch');
1028
+ this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1029
+ this.home = this.createActionWrapper('IOSHomeButton');
1030
+ this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
939
1031
  }
940
1032
  }
941
1033
  async function agentFromWebDriverAgent(opts) {
942
1034
  debugAgent('Creating iOS agent with WebDriverAgent auto-detection');
943
1035
  const envCheck = await checkIOSEnvironment();
944
1036
  if (!envCheck.available) throw new Error(`iOS environment not available: ${envCheck.error}`);
945
- const device = new IOSDevice({
946
- autoDismissKeyboard: null == opts ? void 0 : opts.autoDismissKeyboard,
947
- customActions: null == opts ? void 0 : opts.customActions,
948
- wdaPort: null == opts ? void 0 : opts.wdaPort,
949
- wdaHost: null == opts ? void 0 : opts.wdaHost,
950
- useWDA: null == opts ? void 0 : opts.useWDA
951
- });
1037
+ const device = new IOSDevice(opts || {});
952
1038
  await device.connect();
953
1039
  return new IOSAgent(device, opts);
954
1040
  }