@limrun/appium-xcuitest-driver 10.4.3-lim.1 → 10.10.1-lim.1
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 +84 -0
- package/build/lib/app-utils.d.ts +2 -2
- package/build/lib/app-utils.d.ts.map +1 -1
- package/build/lib/app-utils.js +4 -1
- package/build/lib/app-utils.js.map +1 -1
- package/build/lib/commands/app-management.js +2 -2
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/appearance.js +2 -2
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/bidi/models.d.ts.map +1 -1
- package/build/lib/commands/bidi/models.js +1 -0
- package/build/lib/commands/bidi/models.js.map +1 -1
- package/build/lib/commands/bidi/types.d.ts +1 -0
- package/build/lib/commands/bidi/types.d.ts.map +1 -1
- package/build/lib/commands/biometric.js +3 -3
- package/build/lib/commands/biometric.js.map +1 -1
- package/build/lib/commands/certificate.d.ts.map +1 -1
- package/build/lib/commands/certificate.js +9 -3
- package/build/lib/commands/certificate.js.map +1 -1
- package/build/lib/commands/condition.d.ts +2 -0
- package/build/lib/commands/condition.d.ts.map +1 -1
- package/build/lib/commands/condition.js +75 -2
- package/build/lib/commands/condition.js.map +1 -1
- package/build/lib/commands/context.d.ts +5 -5
- package/build/lib/commands/context.d.ts.map +1 -1
- package/build/lib/commands/context.js +6 -6
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/file-movement.d.ts.map +1 -1
- package/build/lib/commands/file-movement.js +7 -7
- package/build/lib/commands/file-movement.js.map +1 -1
- package/build/lib/commands/general.js +1 -1
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/gesture.js +1 -1
- package/build/lib/commands/gesture.js.map +1 -1
- package/build/lib/commands/keychains.js +1 -1
- package/build/lib/commands/keychains.js.map +1 -1
- package/build/lib/commands/localization.js +1 -1
- package/build/lib/commands/localization.js.map +1 -1
- package/build/lib/commands/location.d.ts +3 -2
- package/build/lib/commands/location.d.ts.map +1 -1
- package/build/lib/commands/location.js +10 -4
- package/build/lib/commands/location.js.map +1 -1
- package/build/lib/commands/log.js +9 -9
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/memory.js +1 -1
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/notifications.js +1 -1
- package/build/lib/commands/notifications.js.map +1 -1
- package/build/lib/commands/pasteboard.js +2 -2
- package/build/lib/commands/pasteboard.js.map +1 -1
- package/build/lib/commands/pcap.js +1 -1
- package/build/lib/commands/pcap.js.map +1 -1
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +13 -4
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.js +2 -2
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/proxy-helper.d.ts.map +1 -1
- package/build/lib/commands/proxy-helper.js +0 -3
- package/build/lib/commands/proxy-helper.js.map +1 -1
- package/build/lib/commands/screenshots.js +1 -1
- package/build/lib/commands/screenshots.js.map +1 -1
- package/build/lib/commands/simctl.d.ts +1 -1
- package/build/lib/commands/simctl.d.ts.map +1 -1
- package/build/lib/commands/simctl.js +1 -1
- package/build/lib/commands/simctl.js.map +1 -1
- package/build/lib/commands/web.js +1 -1
- package/build/lib/commands/web.js.map +1 -1
- package/build/lib/commands/xctest-record-screen.js +2 -2
- package/build/lib/commands/xctest-record-screen.js.map +1 -1
- package/build/lib/desired-caps.d.ts +392 -505
- package/build/lib/desired-caps.d.ts.map +1 -1
- package/build/lib/desired-caps.js +19 -10
- package/build/lib/desired-caps.js.map +1 -1
- package/build/lib/device/clients/base-device-client.d.ts +22 -0
- package/build/lib/device/clients/base-device-client.d.ts.map +1 -0
- package/build/lib/device/clients/base-device-client.js +14 -0
- package/build/lib/device/clients/base-device-client.js.map +1 -0
- package/build/lib/device/clients/py-ios-device-client.d.ts +21 -0
- package/build/lib/device/clients/py-ios-device-client.d.ts.map +1 -0
- package/build/lib/device/clients/py-ios-device-client.js +125 -0
- package/build/lib/device/clients/py-ios-device-client.js.map +1 -0
- package/build/lib/device/device-connections-factory.d.ts +18 -0
- package/build/lib/device/device-connections-factory.d.ts.map +1 -0
- package/build/lib/device/device-connections-factory.js +260 -0
- package/build/lib/device/device-connections-factory.js.map +1 -0
- package/build/lib/device/log/helpers.d.ts +10 -0
- package/build/lib/device/log/helpers.d.ts.map +1 -0
- package/build/lib/device/log/helpers.js +37 -0
- package/build/lib/device/log/helpers.js.map +1 -0
- package/build/lib/device/log/ios-crash-log.d.ts +34 -0
- package/build/lib/device/log/ios-crash-log.d.ts.map +1 -0
- package/build/lib/device/log/ios-crash-log.js +141 -0
- package/build/lib/device/log/ios-crash-log.js.map +1 -0
- package/build/lib/device/log/ios-device-log.d.ts +19 -0
- package/build/lib/device/log/ios-device-log.d.ts.map +1 -0
- package/build/lib/device/log/ios-device-log.js +42 -0
- package/build/lib/device/log/ios-device-log.js.map +1 -0
- package/build/lib/device/log/ios-log.d.ts +24 -0
- package/build/lib/device/log/ios-log.d.ts.map +1 -0
- package/build/lib/device/log/ios-log.js +50 -0
- package/build/lib/device/log/ios-log.js.map +1 -0
- package/build/lib/device/log/ios-performance-log.d.ts +18 -0
- package/build/lib/device/log/ios-performance-log.d.ts.map +1 -0
- package/build/lib/device/log/ios-performance-log.js +43 -0
- package/build/lib/device/log/ios-performance-log.js.map +1 -0
- package/build/lib/device/log/ios-simulator-log.d.ts +38 -0
- package/build/lib/device/log/ios-simulator-log.d.ts.map +1 -0
- package/build/lib/device/log/ios-simulator-log.js +184 -0
- package/build/lib/device/log/ios-simulator-log.js.map +1 -0
- package/build/lib/device/log/line-consuming-log.d.ts +9 -0
- package/build/lib/device/log/line-consuming-log.d.ts.map +1 -0
- package/build/lib/device/log/line-consuming-log.js +16 -0
- package/build/lib/device/log/line-consuming-log.js.map +1 -0
- package/build/lib/device/log/safari-console-log.d.ts +67 -0
- package/build/lib/device/log/safari-console-log.d.ts.map +1 -0
- package/build/lib/device/log/safari-console-log.js +81 -0
- package/build/lib/device/log/safari-console-log.js.map +1 -0
- package/build/lib/device/log/safari-network-log.d.ts +75 -0
- package/build/lib/device/log/safari-network-log.d.ts.map +1 -0
- package/build/lib/device/log/safari-network-log.js +47 -0
- package/build/lib/device/log/safari-network-log.js.map +1 -0
- package/build/lib/device/real-device-management.d.ts +146 -0
- package/build/lib/device/real-device-management.d.ts.map +1 -0
- package/build/lib/device/real-device-management.js +740 -0
- package/build/lib/device/real-device-management.js.map +1 -0
- package/build/lib/device/simulator-management.d.ts +65 -0
- package/build/lib/device/simulator-management.d.ts.map +1 -0
- package/build/lib/device/simulator-management.js +261 -0
- package/build/lib/device/simulator-management.js.map +1 -0
- package/build/lib/device-log/ios-crash-log.d.ts +1 -1
- package/build/lib/device-log/ios-crash-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-simulator-log.d.ts +1 -1
- package/build/lib/device-log/ios-simulator-log.d.ts.map +1 -1
- package/build/lib/doctor/required-checks.js +1 -1
- package/build/lib/doctor/required-checks.js.map +1 -1
- package/build/lib/driver.d.ts +129 -1377
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +461 -573
- package/build/lib/driver.js.map +1 -1
- package/build/lib/method-map.d.ts +1 -1
- package/build/lib/method-map.d.ts.map +1 -1
- package/build/lib/method-map.js +2 -2
- package/build/lib/method-map.js.map +1 -1
- package/build/lib/simulator-management.d.ts +10 -0
- package/build/lib/simulator-management.d.ts.map +1 -1
- package/build/lib/simulator-management.js +9 -5
- package/build/lib/simulator-management.js.map +1 -1
- package/build/lib/utils.d.ts +2 -9
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +3 -47
- package/build/lib/utils.js.map +1 -1
- package/lib/app-utils.js +5 -1
- package/lib/commands/app-management.js +2 -2
- package/lib/commands/appearance.js +2 -2
- package/lib/commands/bidi/models.ts +1 -0
- package/lib/commands/bidi/types.ts +1 -0
- package/lib/commands/biometric.js +3 -3
- package/lib/commands/certificate.js +9 -3
- package/lib/commands/condition.js +85 -2
- package/lib/commands/context.js +6 -6
- package/lib/commands/file-movement.js +11 -7
- package/lib/commands/general.js +1 -1
- package/lib/commands/gesture.js +1 -1
- package/lib/commands/keychains.js +1 -1
- package/lib/commands/localization.js +1 -1
- package/lib/commands/location.js +11 -4
- package/lib/commands/log.js +9 -9
- package/lib/commands/memory.js +1 -1
- package/lib/commands/notifications.js +1 -1
- package/lib/commands/pasteboard.js +2 -2
- package/lib/commands/pcap.js +1 -1
- package/lib/commands/performance.js +12 -1
- package/lib/commands/permissions.js +2 -2
- package/lib/commands/proxy-helper.js +0 -3
- package/lib/commands/screenshots.js +1 -1
- package/lib/commands/simctl.js +1 -1
- package/lib/commands/web.js +1 -1
- package/lib/commands/xctest-record-screen.js +2 -2
- package/lib/{desired-caps.js → desired-caps.ts} +20 -6
- package/lib/{real-device-clients → device/clients}/py-ios-device-client.ts +1 -1
- package/lib/{device-connections-factory.js → device/device-connections-factory.ts} +96 -60
- package/lib/{device-log → device/log}/helpers.ts +1 -1
- package/lib/{device-log → device/log}/ios-crash-log.ts +4 -4
- package/lib/{device-log → device/log}/ios-log.ts +1 -1
- package/lib/{device-log → device/log}/ios-simulator-log.ts +1 -1
- package/lib/{device-log → device/log}/line-consuming-log.ts +1 -1
- package/lib/{device-log → device/log}/safari-console-log.ts +1 -1
- package/lib/device/real-device-management.ts +831 -0
- package/lib/{simulator-management.js → device/simulator-management.ts} +75 -64
- package/lib/doctor/required-checks.ts +1 -1
- package/lib/{driver.js → driver.ts} +623 -707
- package/lib/{method-map.js → method-map.ts} +5 -2
- package/lib/utils.js +3 -54
- package/package.json +17 -19
- package/scripts/build-wda.js +3 -3
- package/lib/ios-fs-helpers.js +0 -355
- package/lib/ios-generic-simulators.js +0 -11
- package/lib/real-device-management.js +0 -133
- package/lib/real-device.js +0 -347
- package/lib/xcrun.js +0 -16
- /package/lib/{real-device-clients → device/clients}/base-device-client.ts +0 -0
- /package/lib/{device-log → device/log}/ios-device-log.ts +0 -0
- /package/lib/{device-log → device/log}/ios-performance-log.ts +0 -0
- /package/lib/{device-log → device/log}/safari-network-log.ts +0 -0
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import type { MethodMap } from '@appium/types';
|
|
2
|
+
import type { XCUITestDriver } from './driver';
|
|
3
|
+
|
|
4
|
+
export const newMethodMap = {
|
|
2
5
|
'/session/:sessionId/timeouts/async_script': {
|
|
3
6
|
POST: {
|
|
4
7
|
command: 'asyncScriptTimeout',
|
|
@@ -193,4 +196,4 @@ export const newMethodMap = /** @type {const} */ ({
|
|
|
193
196
|
deprecated: true,
|
|
194
197
|
},
|
|
195
198
|
},
|
|
196
|
-
}
|
|
199
|
+
} as const satisfies MethodMap<XCUITestDriver>;
|
package/lib/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as xcode from '
|
|
1
|
+
import * as xcode from 'appium-xcode';
|
|
2
2
|
import {errors} from 'appium/driver';
|
|
3
3
|
import {fs, net, util} from 'appium/support';
|
|
4
4
|
import B from 'bluebird';
|
|
@@ -8,7 +8,6 @@ import path from 'node:path';
|
|
|
8
8
|
import url from 'node:url';
|
|
9
9
|
import * as semver from 'semver';
|
|
10
10
|
import {exec} from 'teen_process';
|
|
11
|
-
import iosGenericSimulators from './ios-generic-simulators';
|
|
12
11
|
import log from './logger';
|
|
13
12
|
import {PLATFORM_NAME_TVOS, PLATFORM_NAME_IOS} from './desired-caps';
|
|
14
13
|
|
|
@@ -50,61 +49,12 @@ async function getAndCheckXcodeVersion() {
|
|
|
50
49
|
*/
|
|
51
50
|
async function getAndCheckIosSdkVersion() {
|
|
52
51
|
try {
|
|
53
|
-
return '26';
|
|
54
52
|
return await xcode.getMaxIOSSDK();
|
|
55
53
|
} catch (err) {
|
|
56
54
|
throw log.errorWithException(`Could not determine iOS SDK version: ${err.message}`);
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
/**
|
|
61
|
-
* Get the generic simulator for a given IOS version and device type (iPhone, iPad)
|
|
62
|
-
*
|
|
63
|
-
* @param {string|number} platformVersion IOS version. e.g.) 13.0
|
|
64
|
-
* @param {string} deviceName Type of IOS device. Can be iPhone, iPad (possibly more in the future)
|
|
65
|
-
*
|
|
66
|
-
* @returns {string?} Generic iPhone or iPad simulator (if applicable)
|
|
67
|
-
*/
|
|
68
|
-
function getGenericSimulatorForIosVersion(platformVersion, deviceName) {
|
|
69
|
-
const genericSimulators = iosGenericSimulators[deviceName];
|
|
70
|
-
if (!genericSimulators) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Find the highest iOS version in the list that is below the provided version
|
|
75
|
-
let result = null;
|
|
76
|
-
const compareVersions = ([simOne], [simTwo]) =>
|
|
77
|
-
util.compareVersions(simOne, '<', simTwo) ? -1 : 1;
|
|
78
|
-
for (const [platformVersionFromList, iosSimulator] of genericSimulators.sort(compareVersions)) {
|
|
79
|
-
if (util.compareVersions(platformVersionFromList, '>', String(platformVersion))) {
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
result = iosSimulator;
|
|
83
|
-
}
|
|
84
|
-
return result;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
*
|
|
89
|
-
* @param {string} platformVersion
|
|
90
|
-
* @param {string} deviceName
|
|
91
|
-
* @returns {string}
|
|
92
|
-
*/
|
|
93
|
-
function translateDeviceName(platformVersion, deviceName) {
|
|
94
|
-
if (!deviceName) {
|
|
95
|
-
return deviceName;
|
|
96
|
-
}
|
|
97
|
-
const deviceNameTranslated = getGenericSimulatorForIosVersion(
|
|
98
|
-
platformVersion,
|
|
99
|
-
`${deviceName}`.toLowerCase().trim(),
|
|
100
|
-
);
|
|
101
|
-
if (!deviceNameTranslated) {
|
|
102
|
-
return deviceName;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
log.debug(`Changing deviceName from '${deviceName}' to '${deviceNameTranslated}'`);
|
|
106
|
-
return deviceNameTranslated;
|
|
107
|
-
}
|
|
108
58
|
|
|
109
59
|
/**
|
|
110
60
|
* @param {string[]} locations
|
|
@@ -531,7 +481,6 @@ export {
|
|
|
531
481
|
checkAppPresent,
|
|
532
482
|
getDriverInfo,
|
|
533
483
|
clearSystemFiles,
|
|
534
|
-
translateDeviceName,
|
|
535
484
|
normalizeCommandTimeouts,
|
|
536
485
|
DEFAULT_TIMEOUT_KEY,
|
|
537
486
|
markSystemFilesForCleanup,
|
|
@@ -545,7 +494,7 @@ export {
|
|
|
545
494
|
};
|
|
546
495
|
|
|
547
496
|
/**
|
|
548
|
-
* @typedef {import('
|
|
549
|
-
* @typedef {import('
|
|
497
|
+
* @typedef {import('appium-xcode').XcodeVersion} XcodeVersion
|
|
498
|
+
* @typedef {import('appium-ios-simulator').Simulator} Simulator
|
|
550
499
|
* @typedef {import('./driver').XCUITestDriver} XCUITestDriver
|
|
551
500
|
*/
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"xcuitest",
|
|
9
9
|
"xctest"
|
|
10
10
|
],
|
|
11
|
-
"version": "10.
|
|
11
|
+
"version": "10.10.1-lim.1",
|
|
12
12
|
"author": "Appium Contributors",
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"repository": {
|
|
@@ -84,10 +84,10 @@
|
|
|
84
84
|
"@colors/colors": "^1.6.0",
|
|
85
85
|
"appium-idb": "^2.0.0",
|
|
86
86
|
"appium-ios-device": "^3.0.0",
|
|
87
|
-
"
|
|
88
|
-
"appium-remote-debugger": "^15.0
|
|
89
|
-
"appium-webdriveragent": "
|
|
90
|
-
"
|
|
87
|
+
"appium-ios-simulator": "npm:@limrun/appium-ios-simulator@8.0.5-lim.4",
|
|
88
|
+
"appium-remote-debugger": "^15.2.0",
|
|
89
|
+
"appium-webdriveragent": "npm:@limrun/appium-webdriveragent@10.4.0-lim.1",
|
|
90
|
+
"appium-xcode": "npm:@limrun/appium-xcode@6.1.3-lim.1",
|
|
91
91
|
"async-lock": "^1.4.0",
|
|
92
92
|
"asyncbox": "^3.0.0",
|
|
93
93
|
"bluebird": "^3.7.2",
|
|
@@ -99,10 +99,9 @@
|
|
|
99
99
|
"moment": "^2.29.4",
|
|
100
100
|
"moment-timezone": "^0.x",
|
|
101
101
|
"node-devicectl": "^1.1.0",
|
|
102
|
-
"
|
|
102
|
+
"node-simctl": "npm:@limrun/node-simctl@8.0.5-lim.3",
|
|
103
103
|
"portscanner": "^2.2.0",
|
|
104
104
|
"semver": "^7.5.4",
|
|
105
|
-
"source-map-support": "^0.x",
|
|
106
105
|
"teen_process": "^3.0.0",
|
|
107
106
|
"winston": "^3.17.0",
|
|
108
107
|
"ws": "^8.13.0"
|
|
@@ -124,15 +123,15 @@
|
|
|
124
123
|
"install-docs-deps": "appium-docs init --no-mkdocs",
|
|
125
124
|
"prepare": "npm run rebuild",
|
|
126
125
|
"rebuild": "npm run clean; npm run build",
|
|
127
|
-
"test": "mocha --exit --timeout 1m \"./test/unit/**/*-specs.
|
|
128
|
-
"e2e-test": "mocha --exit --timeout 10m \"./test/functional/**/*-specs.
|
|
129
|
-
"e2e-test:basic": "mocha \"./test/functional/basic\" --exit --timeout 10m",
|
|
130
|
-
"e2e-test:device": "mocha \"./test/functional/device\" --exit --timeout 10m",
|
|
131
|
-
"e2e-test:driver": "mocha \"./test/functional/driver\" --exit --timeout 10m",
|
|
132
|
-
"e2e-test:long": "mocha \"./test/functional/long\" --exit --timeout 10m",
|
|
133
|
-
"e2e-test:parallel": "mocha \"./test/functional/parallel\" --exit --timeout 10m",
|
|
134
|
-
"e2e-test:web": "mocha \"./test/functional/web\" --exit --timeout 10m",
|
|
135
|
-
"e2e-test:native-web-tap": "mocha \"./test/functional/web/safari-nativewebtap-e2e-specs.
|
|
126
|
+
"test": "mocha --exit --timeout 1m \"./test/unit/**/*-specs.ts\"",
|
|
127
|
+
"e2e-test": "mocha --exit --timeout 10m \"./test/functional/**/*-specs.ts\"",
|
|
128
|
+
"e2e-test:basic": "mocha \"./test/functional/basic/**/*-specs.ts\" --exit --timeout 10m",
|
|
129
|
+
"e2e-test:device": "mocha \"./test/functional/device/**/*-specs.ts\" --exit --timeout 10m",
|
|
130
|
+
"e2e-test:driver": "mocha \"./test/functional/driver/**/*-specs.ts\" --exit --timeout 10m",
|
|
131
|
+
"e2e-test:long": "mocha \"./test/functional/long/**/*-specs.ts\" --exit --timeout 10m",
|
|
132
|
+
"e2e-test:parallel": "mocha \"./test/functional/parallel/**/*-specs.ts\" --exit --timeout 10m",
|
|
133
|
+
"e2e-test:web": "mocha \"./test/functional/web/**/*-specs.ts\" --exit --timeout 10m",
|
|
134
|
+
"e2e-test:native-web-tap": "mocha \"./test/functional/web/safari-nativewebtap-e2e-specs.ts\" --exit --timeout 10m",
|
|
136
135
|
"start": "appium --relaxed-security --port 4567 --keep-alive-timeout 1200"
|
|
137
136
|
},
|
|
138
137
|
"prettier": {
|
|
@@ -146,7 +145,6 @@
|
|
|
146
145
|
"devDependencies": {
|
|
147
146
|
"@appium/docutils": "^2.0.0-rc.1",
|
|
148
147
|
"@appium/eslint-config-appium-ts": "^2.0.0-rc.1",
|
|
149
|
-
"@appium/test-support": "^4.0.0-rc.1",
|
|
150
148
|
"@appium/tsconfig": "^1.0.0-rc.1",
|
|
151
149
|
"@appium/types": "^1.0.0-rc.1",
|
|
152
150
|
"@semantic-release/changelog": "^6.0.3",
|
|
@@ -154,7 +152,7 @@
|
|
|
154
152
|
"@types/bluebird": "^3.5.38",
|
|
155
153
|
"@types/lodash": "^4.14.196",
|
|
156
154
|
"@types/mocha": "^10.0.1",
|
|
157
|
-
"@types/node": "^
|
|
155
|
+
"@types/node": "^25.0.0",
|
|
158
156
|
"@types/portscanner": "^2.1.1",
|
|
159
157
|
"axios": "^1.4.0",
|
|
160
158
|
"chai": "^6.0.0",
|
|
@@ -165,7 +163,7 @@
|
|
|
165
163
|
"mocha-multi-reporters": "^1.5.1",
|
|
166
164
|
"pem": "^1.14.8",
|
|
167
165
|
"prettier": "^3.0.0",
|
|
168
|
-
"semantic-release": "^25.0.
|
|
166
|
+
"semantic-release": "^25.0.2",
|
|
169
167
|
"sharp": "^0.x",
|
|
170
168
|
"sinon": "^21.0.0",
|
|
171
169
|
"ts-node": "^10.9.1",
|
package/scripts/build-wda.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const {WebDriverAgent} = require('appium-webdriveragent');
|
|
2
|
-
const xcode = require('
|
|
3
|
-
const {Simctl} = require('
|
|
4
|
-
const {getSimulator} = require('
|
|
2
|
+
const xcode = require('appium-xcode');
|
|
3
|
+
const {Simctl} = require('node-simctl');
|
|
4
|
+
const {getSimulator} = require('appium-ios-simulator');
|
|
5
5
|
const {logger} = require('appium/support');
|
|
6
6
|
const {parseArgValue} = require('./utils');
|
|
7
7
|
|
package/lib/ios-fs-helpers.js
DELETED
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import B, {TimeoutError} from 'bluebird';
|
|
3
|
-
import {fs, tempDir, mkdirp, zip, util, timing} from 'appium/support';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import log from './logger';
|
|
6
|
-
|
|
7
|
-
export const IO_TIMEOUT_MS = 4 * 60 * 1000;
|
|
8
|
-
// Mobile devices use NAND memory modules for the storage,
|
|
9
|
-
// and the parallelism there is not as performant as on regular SSDs
|
|
10
|
-
const MAX_IO_CHUNK_SIZE = 8;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Retrieve a file from a real device
|
|
14
|
-
*
|
|
15
|
-
* @param {any} afcService Apple File Client service instance from
|
|
16
|
-
* 'appium-ios-device' module
|
|
17
|
-
* @param {string} remotePath Relative path to the file on the device
|
|
18
|
-
* @returns {Promise<Buffer>} The file content as a buffer
|
|
19
|
-
*/
|
|
20
|
-
export async function pullFile(afcService, remotePath) {
|
|
21
|
-
const stream = await afcService.createReadStream(remotePath, {autoDestroy: true});
|
|
22
|
-
const pullPromise = new B((resolve, reject) => {
|
|
23
|
-
stream.on('close', resolve);
|
|
24
|
-
stream.on('error', reject);
|
|
25
|
-
}).timeout(IO_TIMEOUT_MS);
|
|
26
|
-
const buffers = [];
|
|
27
|
-
stream.on('data', (data) => buffers.push(data));
|
|
28
|
-
await pullPromise;
|
|
29
|
-
return Buffer.concat(buffers);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Checks a presence of a local folder.
|
|
34
|
-
*
|
|
35
|
-
* @param {string} folderPath Full path to the local folder
|
|
36
|
-
* @returns {Promise<boolean>} True if the folder exists and is actually a folder
|
|
37
|
-
*/
|
|
38
|
-
async function folderExists(folderPath) {
|
|
39
|
-
try {
|
|
40
|
-
return (await fs.stat(folderPath)).isDirectory();
|
|
41
|
-
} catch {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Retrieve a folder from a real device
|
|
48
|
-
*
|
|
49
|
-
* @param {any} afcService Apple File Client service instance from
|
|
50
|
-
* 'appium-ios-device' module
|
|
51
|
-
* @param {string} remoteRootPath Relative path to the folder on the device
|
|
52
|
-
* @returns {Promise<Buffer>} The folder content as a zipped base64-encoded buffer
|
|
53
|
-
*/
|
|
54
|
-
export async function pullFolder(afcService, remoteRootPath) {
|
|
55
|
-
const tmpFolder = await tempDir.openDir();
|
|
56
|
-
try {
|
|
57
|
-
let localTopItem = null;
|
|
58
|
-
let countFilesSuccess = 0;
|
|
59
|
-
let countFilesFail = 0;
|
|
60
|
-
let countFolders = 0;
|
|
61
|
-
const pullPromises = [];
|
|
62
|
-
await afcService.walkDir(remoteRootPath, true, async (remotePath, isDir) => {
|
|
63
|
-
const localPath = path.join(tmpFolder, remotePath);
|
|
64
|
-
const dirname = isDir ? localPath : path.dirname(localPath);
|
|
65
|
-
if (!(await folderExists(dirname))) {
|
|
66
|
-
await mkdirp(dirname);
|
|
67
|
-
}
|
|
68
|
-
if (!localTopItem || localPath.split(path.sep).length < localTopItem.split(path.sep).length) {
|
|
69
|
-
localTopItem = localPath;
|
|
70
|
-
}
|
|
71
|
-
if (isDir) {
|
|
72
|
-
++countFolders;
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const readStream = await afcService.createReadStream(remotePath, {autoDestroy: true});
|
|
77
|
-
const writeStream = fs.createWriteStream(localPath, {autoClose: true});
|
|
78
|
-
pullPromises.push(
|
|
79
|
-
new B((resolve) => {
|
|
80
|
-
writeStream.on('close', () => {
|
|
81
|
-
++countFilesSuccess;
|
|
82
|
-
resolve();
|
|
83
|
-
});
|
|
84
|
-
const onStreamingError = (e) => {
|
|
85
|
-
readStream.unpipe(writeStream);
|
|
86
|
-
log.warn(
|
|
87
|
-
`Cannot pull '${remotePath}' to '${localPath}'. ` +
|
|
88
|
-
`The file will be skipped. Original error: ${e.message}`,
|
|
89
|
-
);
|
|
90
|
-
++countFilesFail;
|
|
91
|
-
resolve();
|
|
92
|
-
};
|
|
93
|
-
writeStream.on('error', onStreamingError);
|
|
94
|
-
readStream.on('error', onStreamingError);
|
|
95
|
-
}).timeout(IO_TIMEOUT_MS),
|
|
96
|
-
);
|
|
97
|
-
readStream.pipe(writeStream);
|
|
98
|
-
if (pullPromises.length >= MAX_IO_CHUNK_SIZE) {
|
|
99
|
-
await B.any(pullPromises);
|
|
100
|
-
for (let i = pullPromises.length - 1; i >= 0; i--) {
|
|
101
|
-
if (pullPromises[i].isFulfilled()) {
|
|
102
|
-
pullPromises.splice(i, 1);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
// Wait for the rest of files to be pulled
|
|
108
|
-
if (!_.isEmpty(pullPromises)) {
|
|
109
|
-
await B.all(pullPromises);
|
|
110
|
-
}
|
|
111
|
-
log.info(
|
|
112
|
-
`Pulled ${util.pluralize('file', countFilesSuccess, true)} out of ` +
|
|
113
|
-
`${countFilesSuccess + countFilesFail} and ${util.pluralize(
|
|
114
|
-
'folder',
|
|
115
|
-
countFolders,
|
|
116
|
-
true,
|
|
117
|
-
)} ` +
|
|
118
|
-
`from '${remoteRootPath}'`,
|
|
119
|
-
);
|
|
120
|
-
return await zip.toInMemoryZip(localTopItem ? path.dirname(localTopItem) : tmpFolder, {
|
|
121
|
-
encodeToBase64: true,
|
|
122
|
-
});
|
|
123
|
-
} finally {
|
|
124
|
-
await fs.rimraf(tmpFolder);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Creates remote folder path recursively. Noop if the given path
|
|
130
|
-
* already exists
|
|
131
|
-
*
|
|
132
|
-
* @param {any} afcService Apple File Client service instance from
|
|
133
|
-
* 'appium-ios-device' module
|
|
134
|
-
* @param {string} remoteRoot The relative path to the remote folder structure
|
|
135
|
-
* to be created
|
|
136
|
-
*/
|
|
137
|
-
async function remoteMkdirp(afcService, remoteRoot) {
|
|
138
|
-
if (remoteRoot === '.' || remoteRoot === '/') {
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
try {
|
|
142
|
-
await afcService.listDirectory(remoteRoot);
|
|
143
|
-
return;
|
|
144
|
-
} catch {
|
|
145
|
-
// This means that the directory is missing and we got an object not found error.
|
|
146
|
-
// Therefore, we are going to the parent
|
|
147
|
-
await remoteMkdirp(afcService, path.dirname(remoteRoot));
|
|
148
|
-
}
|
|
149
|
-
await afcService.createDirectory(remoteRoot);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* @typedef {Object} PushFileOptions
|
|
154
|
-
* @property {number} [timeoutMs=240000] The maximum count of milliceconds to wait until
|
|
155
|
-
* file push is completed. Cannot be lower than 60000ms
|
|
156
|
-
*/
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Pushes a file to a real device
|
|
160
|
-
*
|
|
161
|
-
* @param {any} afcService afcService Apple File Client service instance from
|
|
162
|
-
* 'appium-ios-device' module
|
|
163
|
-
* @param {string|Buffer} localPathOrPayload Either full path to the source file
|
|
164
|
-
* or a buffer payload to be written into the remote destination
|
|
165
|
-
* @param {string} remotePath Relative path to the file on the device. The remote
|
|
166
|
-
* folder structure is created automatically if necessary.
|
|
167
|
-
* @param {PushFileOptions} [opts={}]
|
|
168
|
-
*/
|
|
169
|
-
export async function pushFile(afcService, localPathOrPayload, remotePath, opts = {}) {
|
|
170
|
-
const {timeoutMs = IO_TIMEOUT_MS} = opts;
|
|
171
|
-
const timer = new timing.Timer().start();
|
|
172
|
-
await remoteMkdirp(afcService, path.dirname(remotePath));
|
|
173
|
-
const source = Buffer.isBuffer(localPathOrPayload)
|
|
174
|
-
? localPathOrPayload
|
|
175
|
-
: fs.createReadStream(localPathOrPayload, {autoClose: true});
|
|
176
|
-
const writeStream = await afcService.createWriteStream(remotePath, {
|
|
177
|
-
autoDestroy: true,
|
|
178
|
-
});
|
|
179
|
-
writeStream.on('finish', writeStream.destroy);
|
|
180
|
-
let pushError = null;
|
|
181
|
-
const filePushPromise = new B((resolve, reject) => {
|
|
182
|
-
writeStream.on('close', () => {
|
|
183
|
-
if (pushError) {
|
|
184
|
-
reject(pushError);
|
|
185
|
-
} else {
|
|
186
|
-
resolve();
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
const onStreamError = (e) => {
|
|
190
|
-
if (!Buffer.isBuffer(source)) {
|
|
191
|
-
source.unpipe(writeStream);
|
|
192
|
-
}
|
|
193
|
-
log.debug(e);
|
|
194
|
-
pushError = e;
|
|
195
|
-
};
|
|
196
|
-
writeStream.on('error', onStreamError);
|
|
197
|
-
if (!Buffer.isBuffer(source)) {
|
|
198
|
-
source.on('error', onStreamError);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
if (Buffer.isBuffer(source)) {
|
|
202
|
-
writeStream.write(source);
|
|
203
|
-
writeStream.end();
|
|
204
|
-
} else {
|
|
205
|
-
source.pipe(writeStream);
|
|
206
|
-
}
|
|
207
|
-
await filePushPromise.timeout(Math.max(timeoutMs, 60000));
|
|
208
|
-
const fileSize = Buffer.isBuffer(localPathOrPayload)
|
|
209
|
-
? localPathOrPayload.length
|
|
210
|
-
: (await fs.stat(localPathOrPayload)).size;
|
|
211
|
-
log.debug(
|
|
212
|
-
`Successfully pushed the file payload (${util.toReadableSizeString(fileSize)}) ` +
|
|
213
|
-
`to the remote location '${remotePath}' in ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`,
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* @typedef {Object} PushFolderOptions
|
|
219
|
-
*
|
|
220
|
-
* @property {number} [timeoutMs=240000] The maximum timeout to wait until a
|
|
221
|
-
* single file is copied
|
|
222
|
-
* @property {boolean} [enableParallelPush=false] Whether to push files in parallel.
|
|
223
|
-
* This usually gives better performance, but might sometimes be less stable.
|
|
224
|
-
*/
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Pushes a folder to a real device
|
|
228
|
-
*
|
|
229
|
-
* @param {any} afcService Apple File Client service instance from
|
|
230
|
-
* 'appium-ios-device' module
|
|
231
|
-
* @param {string} srcRootPath The full path to the source folder
|
|
232
|
-
* @param {string} dstRootPath The relative path to the destination folder. The folder
|
|
233
|
-
* will be deleted if already exists.
|
|
234
|
-
* @param {PushFolderOptions} opts
|
|
235
|
-
*/
|
|
236
|
-
export async function pushFolder(afcService, srcRootPath, dstRootPath, opts = {}) {
|
|
237
|
-
const {timeoutMs = IO_TIMEOUT_MS, enableParallelPush = false} = opts;
|
|
238
|
-
|
|
239
|
-
const timer = new timing.Timer().start();
|
|
240
|
-
const allItems = /** @type {import('path-scurry').Path[]} */ (
|
|
241
|
-
/** @type {unknown} */ (
|
|
242
|
-
await fs.glob('**', {
|
|
243
|
-
cwd: srcRootPath,
|
|
244
|
-
withFileTypes: true,
|
|
245
|
-
})
|
|
246
|
-
)
|
|
247
|
-
);
|
|
248
|
-
log.debug(`Successfully scanned the tree structure of '${srcRootPath}'`);
|
|
249
|
-
// top-level folders go first
|
|
250
|
-
/** @type {string[]} */
|
|
251
|
-
const foldersToPush = allItems
|
|
252
|
-
.filter((x) => x.isDirectory())
|
|
253
|
-
.map((x) => x.relative())
|
|
254
|
-
.sort((a, b) => a.split(path.sep).length - b.split(path.sep).length);
|
|
255
|
-
// larger files go first
|
|
256
|
-
/** @type {string[]} */
|
|
257
|
-
const filesToPush = allItems
|
|
258
|
-
.filter((x) => !x.isDirectory())
|
|
259
|
-
.sort((a, b) => (b.size ?? 0) - (a.size ?? 0))
|
|
260
|
-
.map((x) => x.relative());
|
|
261
|
-
log.debug(
|
|
262
|
-
`Got ${util.pluralize('folder', foldersToPush.length, true)} and ` +
|
|
263
|
-
`${util.pluralize('file', filesToPush.length, true)} to push`,
|
|
264
|
-
);
|
|
265
|
-
// create the folder structure first
|
|
266
|
-
try {
|
|
267
|
-
await afcService.deleteDirectory(dstRootPath);
|
|
268
|
-
} catch {}
|
|
269
|
-
await afcService.createDirectory(dstRootPath);
|
|
270
|
-
for (const relativeFolderPath of foldersToPush) {
|
|
271
|
-
// createDirectory does not accept folder names ending with a path separator
|
|
272
|
-
const absoluteFolderPath = _.trimEnd(path.join(dstRootPath, relativeFolderPath), path.sep);
|
|
273
|
-
if (absoluteFolderPath) {
|
|
274
|
-
await afcService.createDirectory(absoluteFolderPath);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
// do not forget about the root folder
|
|
278
|
-
log.debug(
|
|
279
|
-
`Successfully created the remote folder structure ` +
|
|
280
|
-
`(${util.pluralize('item', foldersToPush.length + 1, true)})`,
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
const _pushFile = async (/** @type {string} */ relativePath) => {
|
|
284
|
-
const absoluteSourcePath = path.join(srcRootPath, relativePath);
|
|
285
|
-
const readStream = fs.createReadStream(absoluteSourcePath, {autoClose: true});
|
|
286
|
-
const absoluteDestinationPath = path.join(dstRootPath, relativePath);
|
|
287
|
-
const writeStream = await afcService.createWriteStream(absoluteDestinationPath, {
|
|
288
|
-
autoDestroy: true,
|
|
289
|
-
});
|
|
290
|
-
writeStream.on('finish', writeStream.destroy);
|
|
291
|
-
let pushError = null;
|
|
292
|
-
const filePushPromise = new B((resolve, reject) => {
|
|
293
|
-
writeStream.on('close', () => {
|
|
294
|
-
if (pushError) {
|
|
295
|
-
reject(pushError);
|
|
296
|
-
} else {
|
|
297
|
-
resolve();
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
const onStreamError = (e) => {
|
|
301
|
-
readStream.unpipe(writeStream);
|
|
302
|
-
log.debug(e);
|
|
303
|
-
pushError = e;
|
|
304
|
-
};
|
|
305
|
-
writeStream.on('error', onStreamError);
|
|
306
|
-
readStream.on('error', onStreamError);
|
|
307
|
-
});
|
|
308
|
-
readStream.pipe(writeStream);
|
|
309
|
-
await filePushPromise.timeout(Math.max(timeoutMs - timer.getDuration().asMilliSeconds, 60000));
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
if (enableParallelPush) {
|
|
313
|
-
log.debug(`Proceeding to parallel files push (max ${MAX_IO_CHUNK_SIZE} writers)`);
|
|
314
|
-
const pushPromises = [];
|
|
315
|
-
for (const relativeFilePath of filesToPush) {
|
|
316
|
-
pushPromises.push(B.resolve(_pushFile(relativeFilePath)));
|
|
317
|
-
// keep the push queue filled
|
|
318
|
-
if (pushPromises.length >= MAX_IO_CHUNK_SIZE) {
|
|
319
|
-
await B.any(pushPromises);
|
|
320
|
-
const elapsedMs = timer.getDuration().asMilliSeconds;
|
|
321
|
-
if (elapsedMs > timeoutMs) {
|
|
322
|
-
throw new TimeoutError(`Timed out after ${elapsedMs} ms`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
for (let i = pushPromises.length - 1; i >= 0; i--) {
|
|
326
|
-
if (pushPromises[i].isFulfilled()) {
|
|
327
|
-
pushPromises.splice(i, 1);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
if (!_.isEmpty(pushPromises)) {
|
|
332
|
-
const remainingPromises = pushPromises.filter((p) => !p.isFulfilled());
|
|
333
|
-
if (remainingPromises.length > 0) {
|
|
334
|
-
await B.all(remainingPromises).timeout(
|
|
335
|
-
Math.max(timeoutMs - timer.getDuration().asMilliSeconds, 60000),
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
} else {
|
|
340
|
-
log.debug(`Proceeding to serial files push`);
|
|
341
|
-
for (const relativeFilePath of filesToPush) {
|
|
342
|
-
await _pushFile(relativeFilePath);
|
|
343
|
-
const elapsedMs = timer.getDuration().asMilliSeconds;
|
|
344
|
-
if (elapsedMs > timeoutMs) {
|
|
345
|
-
throw new TimeoutError(`Timed out after ${elapsedMs} ms`);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
log.debug(
|
|
351
|
-
`Successfully pushed ${util.pluralize('folder', foldersToPush.length, true)} ` +
|
|
352
|
-
`and ${util.pluralize('file', filesToPush.length, true)} ` +
|
|
353
|
-
`within ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`,
|
|
354
|
-
);
|
|
355
|
-
}
|