@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.
- package/README.md +11 -11
- package/dist/es/bin.mjs +423 -327
- package/dist/es/index.mjs +150 -64
- package/dist/lib/bin.js +393 -283
- package/dist/lib/index.js +155 -69
- package/dist/types/index.d.ts +88 -14
- package/package.json +8 -7
- package/static/index.html +1 -1
- package/static/static/css/index.d32b7df9.css +2 -0
- package/static/static/css/index.d32b7df9.css.map +1 -0
- package/static/static/js/79.25af61dc.js +611 -0
- package/static/static/js/{931.dc961e99.js.LICENSE.txt → 79.25af61dc.js.LICENSE.txt} +0 -4
- package/static/static/js/79.25af61dc.js.map +1 -0
- package/static/static/js/async/195.0366f6e8.js +3 -0
- package/static/static/js/async/195.0366f6e8.js.map +1 -0
- package/static/static/js/async/{702.60261735.js → 199.f31e52e7.js} +20 -20
- package/static/static/js/async/199.f31e52e7.js.map +1 -0
- package/static/static/js/async/221.591b048e.js +21 -0
- package/static/static/js/async/221.591b048e.js.map +1 -0
- package/static/static/js/async/271.15d46ff8.js +30 -0
- package/static/static/js/async/271.15d46ff8.js.map +1 -0
- package/static/static/js/async/35.2b64fb0f.js +1 -0
- package/static/static/js/async/{644.6bdc4065.js → 467.710fa05a.js} +1 -1
- package/static/static/js/async/652.b5a7c7b4.js +3 -0
- package/static/static/js/async/652.b5a7c7b4.js.map +1 -0
- package/static/static/js/async/856.be9fd814.js +158 -0
- package/static/static/js/async/{212.e243c338.js.map → 856.be9fd814.js.map} +1 -1
- package/static/static/js/async/860.b56301d9.js +2 -0
- package/static/static/js/async/860.b56301d9.js.map +1 -0
- package/static/static/js/async/990.82a78a53.js +26 -0
- package/static/static/js/async/990.82a78a53.js.map +1 -0
- package/static/static/js/index.0930f837.js +10 -0
- package/static/static/js/index.0930f837.js.map +1 -0
- package/static/static/js/lib-react.7b1abe58.js +3 -0
- package/static/static/js/lib-react.7b1abe58.js.map +1 -0
- package/static/static/css/index.44466eb4.css +0 -2
- package/static/static/css/index.44466eb4.css.map +0 -1
- package/static/static/js/931.dc961e99.js +0 -620
- package/static/static/js/931.dc961e99.js.map +0 -1
- package/static/static/js/async/173.9cf6b074.js +0 -3
- package/static/static/js/async/173.9cf6b074.js.map +0 -1
- package/static/static/js/async/212.e243c338.js +0 -158
- package/static/static/js/async/329.f888b505.js +0 -26
- package/static/static/js/async/329.f888b505.js.map +0 -1
- package/static/static/js/async/364.1821e74b.js +0 -30
- package/static/static/js/async/364.1821e74b.js.map +0 -1
- package/static/static/js/async/544.b73fa603.js +0 -2
- package/static/static/js/async/544.b73fa603.js.map +0 -1
- package/static/static/js/async/582.5dccae2d.js +0 -21
- package/static/static/js/async/582.5dccae2d.js.map +0 -1
- package/static/static/js/async/624.45ee2b2c.js +0 -3
- package/static/static/js/async/624.45ee2b2c.js.map +0 -1
- package/static/static/js/async/659.9afd03db.js +0 -21
- package/static/static/js/async/659.9afd03db.js.map +0 -1
- package/static/static/js/async/702.60261735.js.map +0 -1
- package/static/static/js/async/920.7d9a9aa8.js +0 -2
- package/static/static/js/async/920.7d9a9aa8.js.map +0 -1
- package/static/static/js/async/983.8b91303f.js +0 -1
- package/static/static/js/index.2caaacaf.js +0 -10
- package/static/static/js/index.2caaacaf.js.map +0 -1
- package/static/static/js/lib-react.f566a9ed.js +0 -3
- package/static/static/js/lib-react.f566a9ed.js.map +0 -1
- /package/static/static/js/{index.2caaacaf.js.LICENSE.txt → index.0930f837.js.LICENSE.txt} +0 -0
- /package/static/static/js/{lib-react.f566a9ed.js.LICENSE.txt → lib-react.7b1abe58.js.LICENSE.txt} +0 -0
- /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 =
|
|
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(`
|
|
237
|
-
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
|
|
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('
|
|
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 ??
|
|
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 =
|
|
403
|
-
if ('
|
|
404
|
-
else if ('
|
|
405
|
-
else if ('
|
|
406
|
-
else if ('
|
|
407
|
-
else if ('
|
|
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 (
|
|
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(
|
|
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,
|
|
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 (
|
|
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 =
|
|
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
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
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.
|
|
804
|
-
const endY = Math.round(0.
|
|
805
|
-
await this.swipe(centerX, startY, centerX, endY,
|
|
806
|
-
debugDevice('Dismissed keyboard with swipe
|
|
807
|
-
await sleep(
|
|
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 =
|
|
879
|
-
const wdaPort =
|
|
880
|
-
const wdaHost =
|
|
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
|
-
|
|
937
|
-
const
|
|
938
|
-
|
|
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
|
}
|