appium-xcuitest-driver 10.14.1 → 10.14.3
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 +12 -0
- package/build/lib/commands/alert.d.ts +26 -31
- package/build/lib/commands/alert.d.ts.map +1 -1
- package/build/lib/commands/alert.js +20 -29
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/appearance.d.ts +7 -9
- package/build/lib/commands/appearance.d.ts.map +1 -1
- package/build/lib/commands/appearance.js +13 -19
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/execute.d.ts +10 -22
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +12 -28
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/location.d.ts +8 -11
- package/build/lib/commands/location.d.ts.map +1 -1
- package/build/lib/commands/location.js +7 -15
- package/build/lib/commands/location.js.map +1 -1
- package/build/lib/commands/navigation.d.ts +14 -26
- package/build/lib/commands/navigation.d.ts.map +1 -1
- package/build/lib/commands/navigation.js +10 -18
- package/build/lib/commands/navigation.js.map +1 -1
- package/build/lib/commands/pcap.d.ts +18 -38
- package/build/lib/commands/pcap.d.ts.map +1 -1
- package/build/lib/commands/pcap.js +9 -14
- package/build/lib/commands/pcap.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +15 -17
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +12 -18
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/proxy-helper.d.ts +11 -11
- package/build/lib/commands/proxy-helper.d.ts.map +1 -1
- package/build/lib/commands/proxy-helper.js +15 -24
- package/build/lib/commands/proxy-helper.js.map +1 -1
- package/build/lib/commands/screenshots.d.ts +15 -9
- package/build/lib/commands/screenshots.d.ts.map +1 -1
- package/build/lib/commands/screenshots.js +13 -11
- package/build/lib/commands/screenshots.js.map +1 -1
- package/build/lib/commands/simctl.d.ts +16 -22
- package/build/lib/commands/simctl.d.ts.map +1 -1
- package/build/lib/commands/simctl.js +8 -17
- package/build/lib/commands/simctl.js.map +1 -1
- package/build/lib/commands/source.d.ts +10 -8
- package/build/lib/commands/source.d.ts.map +1 -1
- package/build/lib/commands/source.js +11 -14
- package/build/lib/commands/source.js.map +1 -1
- package/build/lib/commands/timeouts.d.ts +25 -32
- package/build/lib/commands/timeouts.d.ts.map +1 -1
- package/build/lib/commands/timeouts.js +18 -14
- package/build/lib/commands/timeouts.js.map +1 -1
- package/build/lib/driver.js +1 -1
- package/build/lib/driver.js.map +1 -1
- package/build/lib/execute-method-map.d.ts.map +1 -1
- package/build/lib/execute-method-map.js +0 -2
- package/build/lib/execute-method-map.js.map +1 -1
- package/lib/commands/alert.ts +98 -0
- package/lib/commands/appearance.ts +70 -0
- package/lib/commands/{execute.js → execute.ts} +41 -37
- package/lib/commands/{location.js → location.ts} +19 -22
- package/lib/commands/{navigation.js → navigation.ts} +23 -26
- package/lib/commands/{pcap.js → pcap.ts} +28 -28
- package/lib/commands/permissions.ts +90 -0
- package/lib/commands/{proxy-helper.js → proxy-helper.ts} +26 -26
- package/lib/commands/{screenshots.js → screenshots.ts} +24 -16
- package/lib/commands/{simctl.js → simctl.ts} +27 -21
- package/lib/commands/{source.js → source.ts} +23 -20
- package/lib/commands/timeouts.ts +95 -0
- package/lib/driver.ts +1 -1
- package/lib/execute-method-map.ts +0 -2
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
- package/lib/commands/alert.js +0 -88
- package/lib/commands/appearance.js +0 -71
- package/lib/commands/permissions.js +0 -85
- package/lib/commands/timeouts.js +0 -68
|
@@ -2,19 +2,23 @@ import {retryInterval} from 'asyncbox';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import {errors} from 'appium/driver';
|
|
4
4
|
import {util, imageUtil} from 'appium/support';
|
|
5
|
+
import type {XCUITestDriver} from '../driver';
|
|
6
|
+
import type {Simulator} from 'appium-ios-simulator';
|
|
7
|
+
import type {Element} from '@appium/types';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
10
|
+
* Takes a screenshot of the current screen.
|
|
11
|
+
*
|
|
12
|
+
* @returns Base64-encoded screenshot data
|
|
9
13
|
*/
|
|
10
|
-
export async function getScreenshot() {
|
|
14
|
+
export async function getScreenshot(this: XCUITestDriver): Promise<string> {
|
|
11
15
|
if (this.isWebContext()) {
|
|
12
16
|
const webScreenshotMode = (await this.settings.getSettings()).webScreenshotMode;
|
|
13
17
|
switch (_.toLower(webScreenshotMode)) {
|
|
14
18
|
case 'page':
|
|
15
19
|
case 'viewport':
|
|
16
20
|
return await this.remote.captureScreenshot({
|
|
17
|
-
coordinateSystem:
|
|
21
|
+
coordinateSystem: _.capitalize(webScreenshotMode) as 'Viewport' | 'Page',
|
|
18
22
|
});
|
|
19
23
|
case 'native':
|
|
20
24
|
case undefined:
|
|
@@ -29,7 +33,7 @@ export async function getScreenshot() {
|
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
const getScreenshotFromWDA = async () => {
|
|
36
|
+
const getScreenshotFromWDA = async (): Promise<string> => {
|
|
33
37
|
this.log.debug(`Taking screenshot with WDA`);
|
|
34
38
|
const data = await this.proxyCommand('/screenshot', 'GET');
|
|
35
39
|
if (!_.isString(data)) {
|
|
@@ -53,14 +57,14 @@ export async function getScreenshot() {
|
|
|
53
57
|
|
|
54
58
|
try {
|
|
55
59
|
return await getScreenshotFromWDA();
|
|
56
|
-
} catch (err) {
|
|
60
|
+
} catch (err: any) {
|
|
57
61
|
this.log.warn(`Error getting screenshot: ${err.message}`);
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
// simulator attempt
|
|
61
65
|
if (this.isSimulator()) {
|
|
62
66
|
this.log.info(`Falling back to 'simctl io screenshot' API`);
|
|
63
|
-
const payload = await
|
|
67
|
+
const payload = await (this.device as Simulator).simctl.getScreenshot();
|
|
64
68
|
if (!payload) {
|
|
65
69
|
throw new errors.UnableToCaptureScreen();
|
|
66
70
|
}
|
|
@@ -68,13 +72,19 @@ export async function getScreenshot() {
|
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
// Retry for real devices only. Fail fast on Simulator if simctl does not work as expected
|
|
71
|
-
return
|
|
75
|
+
return await retryInterval(2, 1000, getScreenshotFromWDA) as string;
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
/**
|
|
75
|
-
*
|
|
79
|
+
* Takes a screenshot of a specific element.
|
|
80
|
+
*
|
|
81
|
+
* @param el - Element to capture
|
|
82
|
+
* @returns Base64-encoded screenshot data
|
|
76
83
|
*/
|
|
77
|
-
export async function getElementScreenshot(
|
|
84
|
+
export async function getElementScreenshot(
|
|
85
|
+
this: XCUITestDriver,
|
|
86
|
+
el: Element<string> | string,
|
|
87
|
+
): Promise<string> {
|
|
78
88
|
el = util.unwrapElement(el);
|
|
79
89
|
if (this.isWebContext()) {
|
|
80
90
|
const atomsElement = this.getAtomsElement(el);
|
|
@@ -96,10 +106,11 @@ export async function getElementScreenshot(el) {
|
|
|
96
106
|
}
|
|
97
107
|
|
|
98
108
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
109
|
+
* Takes a screenshot of the current viewport.
|
|
110
|
+
*
|
|
111
|
+
* @returns Base64-encoded screenshot data
|
|
101
112
|
*/
|
|
102
|
-
export async function getViewportScreenshot() {
|
|
113
|
+
export async function getViewportScreenshot(this: XCUITestDriver): Promise<string> {
|
|
103
114
|
if (this.isWebContext()) {
|
|
104
115
|
return await this.remote.captureScreenshot();
|
|
105
116
|
}
|
|
@@ -130,6 +141,3 @@ export async function getViewportScreenshot() {
|
|
|
130
141
|
return await imageUtil.cropBase64Image(screenshot, region);
|
|
131
142
|
}
|
|
132
143
|
|
|
133
|
-
/**
|
|
134
|
-
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|
|
135
|
-
*/
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { errors } from 'appium/driver';
|
|
2
|
+
import type {XCUITestDriver} from '../driver';
|
|
3
|
+
import type {Simulator} from 'appium-ios-simulator';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* List of subcommands for `simctl` we provide as mobile simctl command.
|
|
@@ -27,19 +29,33 @@ const SUBCOMMANDS_HAS_DEVICE = [
|
|
|
27
29
|
'terminate',
|
|
28
30
|
'ui',
|
|
29
31
|
'uninstall'
|
|
30
|
-
];
|
|
32
|
+
] as const;
|
|
33
|
+
|
|
34
|
+
export interface SimctlExecResponse {
|
|
35
|
+
/** The output of standard out. */
|
|
36
|
+
stdout: string;
|
|
37
|
+
/** The output of standard error. */
|
|
38
|
+
stderr: string;
|
|
39
|
+
/** Return code. */
|
|
40
|
+
code: number;
|
|
41
|
+
}
|
|
31
42
|
|
|
32
43
|
/**
|
|
33
44
|
* Run the given command with arguments as `xcrun simctl` subcommand.
|
|
34
45
|
* This method works behind the 'simctl' security flag.
|
|
35
|
-
*
|
|
36
|
-
* @param
|
|
37
|
-
* @param
|
|
38
|
-
* @param
|
|
39
|
-
* @returns
|
|
40
|
-
* @throws
|
|
46
|
+
*
|
|
47
|
+
* @param command - Subcommand to run with `xcrun simctl`. Must be one of the supported commands.
|
|
48
|
+
* @param args - Arguments for the subcommand. The arguments should be after <device> in the help.
|
|
49
|
+
* @param timeout - The maximum number of milliseconds
|
|
50
|
+
* @returns The execution result with stdout, stderr, and return code
|
|
51
|
+
* @throws If the simctl subcommand command returns non-zero return code, or the given subcommand was invalid.
|
|
41
52
|
*/
|
|
42
|
-
export async function mobileSimctl(
|
|
53
|
+
export async function mobileSimctl(
|
|
54
|
+
this: XCUITestDriver,
|
|
55
|
+
command: string,
|
|
56
|
+
args: string[] = [],
|
|
57
|
+
timeout?: number,
|
|
58
|
+
): Promise<SimctlExecResponse> {
|
|
43
59
|
if (!this.isSimulator()) {
|
|
44
60
|
throw new errors.UnsupportedOperationError(`Only simulator is supported.`);
|
|
45
61
|
}
|
|
@@ -48,13 +64,13 @@ export async function mobileSimctl(command, args = [], timeout = undefined) {
|
|
|
48
64
|
throw new errors.InvalidArgumentError(`Unknown device or simulator UDID: '${this.opts.udid}'`);
|
|
49
65
|
}
|
|
50
66
|
|
|
51
|
-
if (!SUBCOMMANDS_HAS_DEVICE.includes(command)) {
|
|
67
|
+
if (!(SUBCOMMANDS_HAS_DEVICE as readonly string[]).includes(command)) {
|
|
52
68
|
throw new errors.InvalidArgumentError(`The given command '${command}' is not supported. ` +
|
|
53
69
|
`Available subcommands are ${SUBCOMMANDS_HAS_DEVICE.join(',')}`);
|
|
54
70
|
}
|
|
55
71
|
|
|
56
|
-
const result = await
|
|
57
|
-
command,
|
|
72
|
+
const result = await (this.device as Simulator).simctl.exec(
|
|
73
|
+
command as typeof SUBCOMMANDS_HAS_DEVICE[number],
|
|
58
74
|
{args: [this.opts.udid, ...args], timeout}
|
|
59
75
|
);
|
|
60
76
|
return {
|
|
@@ -64,13 +80,3 @@ export async function mobileSimctl(command, args = [], timeout = undefined) {
|
|
|
64
80
|
};
|
|
65
81
|
}
|
|
66
82
|
|
|
67
|
-
/**
|
|
68
|
-
* @typedef {Object} SimctlExecResponse
|
|
69
|
-
* @property {string} stdout The output of standard out.
|
|
70
|
-
* @property {string} stderr The output of standard error.
|
|
71
|
-
* @property {number} code Return code.
|
|
72
|
-
*/
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|
|
76
|
-
*/
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import js2xml from 'js2xmlparser2';
|
|
3
|
+
import type {XCUITestDriver} from '../driver';
|
|
4
|
+
import type {SourceFormat} from './types';
|
|
3
5
|
|
|
4
6
|
const APPIUM_AUT_TAG = 'AppiumAUT';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
|
-
*
|
|
9
|
+
* Retrieves the page source of the current application.
|
|
10
|
+
*
|
|
11
|
+
* @returns The page source as XML or HTML string
|
|
8
12
|
*/
|
|
9
|
-
export async function getPageSource() {
|
|
13
|
+
export async function getPageSource(this: XCUITestDriver): Promise<string> {
|
|
10
14
|
if (this.isWebContext()) {
|
|
11
15
|
const script = 'return document.documentElement.outerHTML';
|
|
12
16
|
return await this.executeAtom('execute_script', [script, []]);
|
|
@@ -28,14 +32,17 @@ export async function getPageSource() {
|
|
|
28
32
|
/**
|
|
29
33
|
* Retrieve the source tree of the current page in XML or JSON format.
|
|
30
34
|
*
|
|
31
|
-
* @param
|
|
32
|
-
* @param
|
|
35
|
+
* @param format - Page tree source representation format.
|
|
36
|
+
* @param excludedAttributes - A comma-separated string of attribute names to exclude from the output. Only works if `format` is `xml`.
|
|
33
37
|
* @privateRemarks Why isn't `excludedAttributes` an array?
|
|
34
|
-
* @returns
|
|
35
|
-
* @this {XCUITestDriver}
|
|
38
|
+
* @returns The source tree of the current page in the given format.
|
|
36
39
|
*/
|
|
37
|
-
export async function mobileGetSource(
|
|
38
|
-
|
|
40
|
+
export async function mobileGetSource(
|
|
41
|
+
this: XCUITestDriver,
|
|
42
|
+
format: SourceFormat = 'xml',
|
|
43
|
+
excludedAttributes?: string,
|
|
44
|
+
): Promise<string> {
|
|
45
|
+
const paramsMap: Record<string, string> = {
|
|
39
46
|
format,
|
|
40
47
|
scope: APPIUM_AUT_TAG,
|
|
41
48
|
};
|
|
@@ -45,7 +52,7 @@ export async function mobileGetSource(format = 'xml', excludedAttributes) {
|
|
|
45
52
|
const query = Object.entries(paramsMap)
|
|
46
53
|
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
47
54
|
.join('&');
|
|
48
|
-
return
|
|
55
|
+
return await this.proxyCommand(`/source?${query}`, 'GET') as string;
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
/**
|
|
@@ -76,15 +83,14 @@ export async function mobileGetSource(format = 'xml', excludedAttributes) {
|
|
|
76
83
|
* rawIdentifier: null }
|
|
77
84
|
* ```
|
|
78
85
|
*/
|
|
79
|
-
function getTreeForXML(srcTree) {
|
|
80
|
-
function getTree(element, elementIndex, parentPath) {
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
function getTreeForXML(srcTree: any): any {
|
|
87
|
+
function getTree(element: any, elementIndex: number, parentPath: string): any {
|
|
88
|
+
const curPath = `${parentPath}/${elementIndex}`;
|
|
89
|
+
const rect = element.rect || {};
|
|
83
90
|
/**
|
|
84
91
|
* @privateRemarks I don't even want to try to type this right now
|
|
85
|
-
* @type {any}
|
|
86
92
|
*/
|
|
87
|
-
|
|
93
|
+
const subtree: any = {
|
|
88
94
|
'@': {
|
|
89
95
|
type: `XCUIElementType${element.type}`,
|
|
90
96
|
enabled: parseInt(element.isEnabled, 10) === 1,
|
|
@@ -114,11 +120,11 @@ function getTreeForXML(srcTree) {
|
|
|
114
120
|
[`XCUIElementType${element.type}`]: subtree,
|
|
115
121
|
};
|
|
116
122
|
}
|
|
117
|
-
|
|
123
|
+
const tree = getTree(srcTree, 0, '');
|
|
118
124
|
return tree;
|
|
119
125
|
}
|
|
120
126
|
|
|
121
|
-
function getSourceXml(jsonSource) {
|
|
127
|
+
function getSourceXml(jsonSource: any): string {
|
|
122
128
|
return js2xml('AppiumAUT', jsonSource, {
|
|
123
129
|
wrapArray: {enabled: false, elementName: 'element'},
|
|
124
130
|
declaration: {include: true},
|
|
@@ -126,6 +132,3 @@ function getSourceXml(jsonSource) {
|
|
|
126
132
|
});
|
|
127
133
|
}
|
|
128
134
|
|
|
129
|
-
/**
|
|
130
|
-
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|
|
131
|
-
*/
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type {XCUITestDriver} from '../driver';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sets the page load timeout using W3C protocol.
|
|
5
|
+
*
|
|
6
|
+
* @param ms - Timeout in milliseconds
|
|
7
|
+
*/
|
|
8
|
+
export async function pageLoadTimeoutW3C(
|
|
9
|
+
this: XCUITestDriver,
|
|
10
|
+
ms: number,
|
|
11
|
+
): Promise<void> {
|
|
12
|
+
await this.setPageLoadTimeout(this.parseTimeoutArgument(ms));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Sets the page load timeout using MJSONWP protocol.
|
|
17
|
+
*
|
|
18
|
+
* @param ms - Timeout in milliseconds
|
|
19
|
+
*/
|
|
20
|
+
export async function pageLoadTimeoutMJSONWP(
|
|
21
|
+
this: XCUITestDriver,
|
|
22
|
+
ms: number,
|
|
23
|
+
): Promise<void> {
|
|
24
|
+
await this.setPageLoadTimeout(this.parseTimeoutArgument(ms));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Sets the async script timeout using W3C protocol.
|
|
29
|
+
*
|
|
30
|
+
* @param ms - Timeout in milliseconds
|
|
31
|
+
*/
|
|
32
|
+
export async function scriptTimeoutW3C(
|
|
33
|
+
this: XCUITestDriver,
|
|
34
|
+
ms: number,
|
|
35
|
+
): Promise<void> {
|
|
36
|
+
// XXX: this is synchronous
|
|
37
|
+
await this.setAsyncScriptTimeout(this.parseTimeoutArgument(ms));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Alias for {@linkcode XCUITestDriver.scriptTimeoutW3C}.
|
|
42
|
+
*
|
|
43
|
+
* @param ms - The timeout in milliseconds
|
|
44
|
+
* @deprecated Use {@linkcode XCUITestDriver.scriptTimeoutW3C} instead
|
|
45
|
+
*/
|
|
46
|
+
export async function scriptTimeoutMJSONWP(
|
|
47
|
+
this: XCUITestDriver,
|
|
48
|
+
ms: number,
|
|
49
|
+
): Promise<void> {
|
|
50
|
+
await this.asyncScriptTimeout(ms);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Alias for {@linkcode XCUITestDriver.scriptTimeoutW3C}.
|
|
55
|
+
*
|
|
56
|
+
* @param ms - The timeout in milliseconds
|
|
57
|
+
* @deprecated Use {@linkcode XCUITestDriver.scriptTimeoutW3C} instead
|
|
58
|
+
*/
|
|
59
|
+
export async function asyncScriptTimeout(
|
|
60
|
+
this: XCUITestDriver,
|
|
61
|
+
ms: number,
|
|
62
|
+
): Promise<void> {
|
|
63
|
+
await this.scriptTimeoutW3C(ms);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sets the page load timeout.
|
|
68
|
+
*
|
|
69
|
+
* @param ms - Timeout in milliseconds
|
|
70
|
+
*/
|
|
71
|
+
export function setPageLoadTimeout(
|
|
72
|
+
this: XCUITestDriver,
|
|
73
|
+
ms: number,
|
|
74
|
+
): void {
|
|
75
|
+
ms = parseInt(String(ms), 10);
|
|
76
|
+
this.pageLoadMs = ms;
|
|
77
|
+
if (this._remote) {
|
|
78
|
+
this.remote.pageLoadMs = ms;
|
|
79
|
+
}
|
|
80
|
+
this.log.debug(`Set page load timeout to ${ms}ms`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Sets the async script timeout.
|
|
85
|
+
*
|
|
86
|
+
* @param ms - Timeout in milliseconds
|
|
87
|
+
*/
|
|
88
|
+
export function setAsyncScriptTimeout(
|
|
89
|
+
this: XCUITestDriver,
|
|
90
|
+
ms: number,
|
|
91
|
+
): void {
|
|
92
|
+
this.asyncWaitMs = ms;
|
|
93
|
+
this.log.debug(`Set async script timeout to ${ms}ms`);
|
|
94
|
+
}
|
|
95
|
+
|
package/lib/driver.ts
CHANGED
|
@@ -500,7 +500,7 @@ export class XCUITestDriver
|
|
|
500
500
|
this.log.debug(`Executing command '${cmd}'`);
|
|
501
501
|
|
|
502
502
|
if (cmd === 'receiveAsyncResponse') {
|
|
503
|
-
return await this.receiveAsyncResponse(
|
|
503
|
+
return await this.receiveAsyncResponse(args[0], args[1]);
|
|
504
504
|
}
|
|
505
505
|
// TODO: once this fix gets into base driver remove from here
|
|
506
506
|
if (cmd === 'getStatus') {
|
|
@@ -466,14 +466,12 @@ export const executeMethodMap = {
|
|
|
466
466
|
command: 'mobileResetLocationService',
|
|
467
467
|
},
|
|
468
468
|
'mobile: startPcap': {
|
|
469
|
-
// @ts-expect-error Method exists on XCUITestDriver but is defined in pcap.js (JS file), so TypeScript can't verify it
|
|
470
469
|
command: 'mobileStartPcap',
|
|
471
470
|
params: {
|
|
472
471
|
optional: ['timeLimitSec', 'forceRestart'],
|
|
473
472
|
},
|
|
474
473
|
},
|
|
475
474
|
'mobile: stopPcap': {
|
|
476
|
-
// @ts-expect-error Method exists on XCUITestDriver but is defined in pcap.js (JS file), so TypeScript can't verify it
|
|
477
475
|
command: 'mobileStopPcap',
|
|
478
476
|
},
|
|
479
477
|
'mobile: listConditionInducers': {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-xcuitest-driver",
|
|
3
|
-
"version": "10.14.
|
|
3
|
+
"version": "10.14.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "appium-xcuitest-driver",
|
|
9
|
-
"version": "10.14.
|
|
9
|
+
"version": "10.14.3",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@appium/strongbox": "^1.0.0-rc.1",
|
|
@@ -692,9 +692,9 @@
|
|
|
692
692
|
}
|
|
693
693
|
},
|
|
694
694
|
"node_modules/appium-ios-remotexpc": {
|
|
695
|
-
"version": "0.
|
|
696
|
-
"resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-0.
|
|
697
|
-
"integrity": "sha512-
|
|
695
|
+
"version": "0.24.1",
|
|
696
|
+
"resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-0.24.1.tgz",
|
|
697
|
+
"integrity": "sha512-LJ83A/cHx+CFOX9yGLoG+bsfgYiJdN1PSBDDe7FkZ/C6DGTi+5zvDxOwaBSLmhgEh6uae40EGK8/FbFiKwR4Kg==",
|
|
698
698
|
"license": "Apache-2.0",
|
|
699
699
|
"optional": true,
|
|
700
700
|
"dependencies": {
|
package/package.json
CHANGED
package/lib/commands/alert.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @this {XCUITestDriver}
|
|
3
|
-
*/
|
|
4
|
-
export async function getAlertText() {
|
|
5
|
-
return /** @type {string|null} */ (await this.proxyCommand('/alert/text', 'GET'));
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @param {string} value
|
|
10
|
-
* @this {XCUITestDriver}
|
|
11
|
-
* @returns {Promise<void>}
|
|
12
|
-
*/
|
|
13
|
-
export async function setAlertText(value) {
|
|
14
|
-
await this.proxyCommand('/alert/text', 'POST', {value});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @param { {buttonLabel?: string} } opts
|
|
19
|
-
* @returns {Promise<void>}
|
|
20
|
-
* @this {XCUITestDriver}
|
|
21
|
-
*/
|
|
22
|
-
export async function postAcceptAlert(opts = {}) {
|
|
23
|
-
await this.proxyCommand('/alert/accept', 'POST', toAlertParams(opts));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @param { {buttonLabel?: string} } opts
|
|
28
|
-
* @returns {Promise<void>}
|
|
29
|
-
* @this {XCUITestDriver}
|
|
30
|
-
*/
|
|
31
|
-
export async function postDismissAlert(opts = {}) {
|
|
32
|
-
await this.proxyCommand('/alert/dismiss', 'POST', toAlertParams(opts));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @internal
|
|
37
|
-
* @this {XCUITestDriver}
|
|
38
|
-
* @returns {Promise<string[]>} The list of button labels
|
|
39
|
-
*/
|
|
40
|
-
export async function getAlertButtons() {
|
|
41
|
-
return /** @type {string[]} */ (await this.proxyCommand('/wda/alert/buttons', 'GET'));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Tries to apply the given action to the currently visible alert.
|
|
46
|
-
*
|
|
47
|
-
* @param {AlertAction} action - The actual action to apply.
|
|
48
|
-
* @param {string} [buttonLabel] - The name of the button used to perform the chosen alert action. Only makes sense if the action is `accept` or `dismiss`.
|
|
49
|
-
* @returns {Promise<string[]|void>} If `action` is `getButtons`, a list of alert button labelsp; otherwise nothing.
|
|
50
|
-
* @remarks This should really be separate commands.
|
|
51
|
-
* @this {XCUITestDriver}
|
|
52
|
-
*/
|
|
53
|
-
export async function mobileHandleAlert(action, buttonLabel) {
|
|
54
|
-
switch (action) {
|
|
55
|
-
case 'accept':
|
|
56
|
-
return await this.postAcceptAlert({buttonLabel});
|
|
57
|
-
case 'dismiss':
|
|
58
|
-
return await this.postDismissAlert({buttonLabel});
|
|
59
|
-
case 'getButtons':
|
|
60
|
-
return await this.getAlertButtons();
|
|
61
|
-
default:
|
|
62
|
-
throw new Error(
|
|
63
|
-
`The 'action' value should be either 'accept', 'dismiss' or 'getButtons'. ` +
|
|
64
|
-
`'${action}' is provided instead.`,
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
*
|
|
71
|
-
* @param { {buttonLabel?: string} } opts
|
|
72
|
-
* @returns { {name?: string} }
|
|
73
|
-
*/
|
|
74
|
-
function toAlertParams(opts = {}) {
|
|
75
|
-
const params = {};
|
|
76
|
-
if (opts.buttonLabel) {
|
|
77
|
-
params.name = opts.buttonLabel;
|
|
78
|
-
}
|
|
79
|
-
return params;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* @typedef {'accept'|'dismiss'|'getButtons'} AlertAction
|
|
84
|
-
*/
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|
|
88
|
-
*/
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import {util} from 'appium/support';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Set the device's UI appearance style
|
|
6
|
-
*
|
|
7
|
-
* @since iOS 12.0
|
|
8
|
-
* @param {'dark'|'light'} style - The appearance style to set
|
|
9
|
-
* @throws {Error} if the current platform does not support UI appearance changes
|
|
10
|
-
* @this {XCUITestDriver}
|
|
11
|
-
*/
|
|
12
|
-
export async function mobileSetAppearance(style) {
|
|
13
|
-
if (!['light', 'dark'].includes(_.toLower(style))) {
|
|
14
|
-
throw new Error(`The 'style' value is expected to equal either 'light' or 'dark'`);
|
|
15
|
-
}
|
|
16
|
-
if (util.compareVersions(/** @type {string} */ (this.opts.platformVersion), '<', '12.0')) {
|
|
17
|
-
throw new Error('Changing appearance is only supported since iOS 12');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (this.isSimulator()) {
|
|
21
|
-
try {
|
|
22
|
-
return void (await /** @type {import('appium-ios-simulator').Simulator} */ (this.device).setAppearance(style));
|
|
23
|
-
} catch (e) {
|
|
24
|
-
this.log.debug(e.stack);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
try {
|
|
28
|
-
return void (await this.proxyCommand('/wda/device/appearance', 'POST', {name: style}, false));
|
|
29
|
-
} catch (e) {
|
|
30
|
-
this.log.debug(e.stack);
|
|
31
|
-
}
|
|
32
|
-
// Fall back to the ugly Siri workaround if the current SDK is too old
|
|
33
|
-
await this.mobileSiriCommand(`Turn ${_.toLower(style) === 'dark' ? 'on' : 'off'} dark mode`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Get the device's UI appearance style.
|
|
38
|
-
*
|
|
39
|
-
* @since Xcode SDK 11
|
|
40
|
-
* @returns {Promise<{style: Style}>}
|
|
41
|
-
* @this {XCUITestDriver}
|
|
42
|
-
*/
|
|
43
|
-
export async function mobileGetAppearance() {
|
|
44
|
-
if (util.compareVersions(/** @type {string} */ (this.opts.platformVersion), '<', '12.0')) {
|
|
45
|
-
return {style: 'unsupported'};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** @type {Style|undefined} */
|
|
49
|
-
let style;
|
|
50
|
-
if (this.isSimulator()) {
|
|
51
|
-
try {
|
|
52
|
-
style = /** @type {Style} */ (
|
|
53
|
-
await /** @type {import('appium-ios-simulator').Simulator} */ (this.device).getAppearance()
|
|
54
|
-
);
|
|
55
|
-
} catch {}
|
|
56
|
-
}
|
|
57
|
-
if (!style) {
|
|
58
|
-
style = /** @type {Style} */ (
|
|
59
|
-
/** @type {any} */ (await this.proxyCommand('/wda/device/info', 'GET'))
|
|
60
|
-
?.userInterfaceStyle ?? 'unknown'
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
style,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|
|
70
|
-
* @typedef {import('./types').Style} Style
|
|
71
|
-
*/
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import {PermissionService} from './enum';
|
|
3
|
-
import {assertSimulator as _assertSimulator} from '../utils';
|
|
4
|
-
|
|
5
|
-
const assertSimulator = (driver) => _assertSimulator.call(driver, 'Permission-related operations');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Resets the given permission for the active application under test.
|
|
9
|
-
* Works for both Simulator and real devices using Xcode SDK 11.4+
|
|
10
|
-
*
|
|
11
|
-
* @param {PermissionService|number} service - One of the available service names. This could also be an integer protected resource identifier; see [this list](https://developer.apple.com/documentation/xctest/xcuiprotectedresource?language=objc)
|
|
12
|
-
* @throws {Error} If permission reset fails on the device.
|
|
13
|
-
* @this {XCUITestDriver}
|
|
14
|
-
*/
|
|
15
|
-
export async function mobileResetPermission(service) {
|
|
16
|
-
if (!service) {
|
|
17
|
-
throw new Error(`The 'service' option is expected to be present`);
|
|
18
|
-
}
|
|
19
|
-
let resource;
|
|
20
|
-
if (_.isString(service)) {
|
|
21
|
-
resource = PermissionService[_.toLower(service)];
|
|
22
|
-
if (!resource) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
`The 'service' value must be one of ` + `${JSON.stringify(_.keys(PermissionService))}`,
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
} else if (_.isInteger(service)) {
|
|
28
|
-
resource = service;
|
|
29
|
-
} else {
|
|
30
|
-
throw new Error(
|
|
31
|
-
`The 'service' value must be either a string or an integer. ` +
|
|
32
|
-
`'${service}' is passed instead`,
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
await this.proxyCommand('/wda/resetAppAuth', 'POST', {resource});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Gets application permission state on a simulated device.
|
|
41
|
-
*
|
|
42
|
-
* **This method requires [WIX applesimutils](https://github.com/wix/AppleSimulatorUtils) to be installed on the Appium server host.**
|
|
43
|
-
*
|
|
44
|
-
* @param {string} bundleId - Bundle identifier of the target application
|
|
45
|
-
* @param {import('./enum').PermissionService} service - Service name
|
|
46
|
-
* @returns {Promise<import('./types').PermissionState>} Either 'yes', 'no', 'unset' or 'limited'
|
|
47
|
-
* @throws {Error} If permission getting fails or the device is not a Simulator.
|
|
48
|
-
* @this {XCUITestDriver}
|
|
49
|
-
* @group Simulator Only
|
|
50
|
-
*/
|
|
51
|
-
export async function mobileGetPermission(bundleId, service) {
|
|
52
|
-
if (!service) {
|
|
53
|
-
throw new Error(`The 'service' option is expected to be present`);
|
|
54
|
-
}
|
|
55
|
-
assertSimulator(this);
|
|
56
|
-
|
|
57
|
-
return /** @type {import('./types').PermissionState} */ (
|
|
58
|
-
await /** @type {import('appium-ios-simulator').Simulator} */ (this.device).getPermission(
|
|
59
|
-
bundleId, String(service)
|
|
60
|
-
)
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Set application permission state on Simulator.
|
|
66
|
-
*
|
|
67
|
-
* @param {Record<Partial<import('./types').AccessRule>, import('./types').PermissionState>} access - One or more access rules to set.
|
|
68
|
-
* @param {string} bundleId - Bundle identifier of the target application
|
|
69
|
-
* @since Xcode SDK 11.4
|
|
70
|
-
* @throws {Error} If permission setting fails or the device is not a Simulator.
|
|
71
|
-
* @group Simulator Only
|
|
72
|
-
* @this {XCUITestDriver}
|
|
73
|
-
*/
|
|
74
|
-
export async function mobileSetPermissions(access, bundleId) {
|
|
75
|
-
if (!_.isPlainObject(access)) {
|
|
76
|
-
throw new Error(`The 'access' option is expected to be a map`);
|
|
77
|
-
}
|
|
78
|
-
assertSimulator(this);
|
|
79
|
-
|
|
80
|
-
await /** @type {import('appium-ios-simulator').Simulator} */ (this.device).setPermissions(bundleId, access);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|
|
85
|
-
*/
|