appium-uiautomator2-driver 2.6.0 → 2.7.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/README.md +238 -22
- package/build/lib/commands/actions.js.map +1 -0
- package/build/lib/commands/alert.js.map +1 -0
- package/build/lib/commands/battery.js.map +1 -0
- package/build/lib/commands/element.js.map +1 -0
- package/build/lib/commands/find.js.map +1 -0
- package/build/lib/commands/general.js.map +1 -0
- package/build/lib/commands/gestures.js.map +1 -0
- package/build/lib/commands/index.js.map +1 -0
- package/build/lib/commands/screenshot.js.map +1 -0
- package/build/lib/commands/touch.js.map +1 -0
- package/build/lib/commands/viewport.js.map +1 -0
- package/build/lib/css-converter.js.map +1 -0
- package/build/lib/desired-caps.js.map +1 -0
- package/build/lib/driver.js.map +1 -0
- package/build/lib/extensions.js.map +1 -0
- package/build/lib/helpers.js.map +1 -0
- package/build/lib/logger.js.map +1 -0
- package/build/lib/uiautomator2.js.map +1 -0
- package/npm-shrinkwrap.json +485 -1076
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -10,7 +10,11 @@ Appium UiAutomator2 Driver is a test automation framework for Android devices. A
|
|
|
10
10
|
|
|
11
11
|
UiAutomator2 Driver proxies most of the commands to [UiAutomator2 server](https://github.com/appium/appium-uiautomator2-server), which uses Google's [UiAutomator](https://developer.android.com/training/testing/ui-automator) framework under the hood. Some commands are proxied directly to [appium-adb](https://github.com/appium/appium-adb) and other helpers built on top of Android platform tools.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
> **Note**
|
|
14
|
+
>
|
|
15
|
+
> Since version 2.0.0 UiAutomator2 driver has dropped the support of Appium 1, and is only compatible to Appium 2.
|
|
16
|
+
> Use the `appium driver install uiautomator2` command to add it to your Appium 2 dist.
|
|
17
|
+
|
|
14
18
|
|
|
15
19
|
## Requirements
|
|
16
20
|
|
|
@@ -24,7 +28,6 @@ On top of standard Appium requirements UiAutomator2 driver also expects the foll
|
|
|
24
28
|
- Real Android devices must have [USB debugging enabled](https://developer.android.com/studio/debug/dev-options) and should be visible as `online` in `adb devices -l` output.
|
|
25
29
|
- The minimum version of Android API must be 5.0 (API level 21) (6.0 is recommended as version 5 has some known compatibility issues).
|
|
26
30
|
|
|
27
|
-
Since version 2.0.0 this driver is only compatible to Appium 2.
|
|
28
31
|
|
|
29
32
|
## Capabilities
|
|
30
33
|
|
|
@@ -45,7 +48,7 @@ appium:printPageSourceOnFindFailure | Enforces the server to dump the actual XML
|
|
|
45
48
|
|
|
46
49
|
Capability Name | Description
|
|
47
50
|
--- | ---
|
|
48
|
-
appium:systemPort | The number of the port the UiAutomator2 server is listening on. By default the first free port from 8200..8299 range is selected. It is recommended to set this value if you are running [parallel tests](
|
|
51
|
+
appium:systemPort | The number of the port the UiAutomator2 server is listening on. By default the first free port from 8200..8299 range is selected. It is recommended to set this value if you are running [parallel tests](#parallel-tests) on the same machine.
|
|
49
52
|
appium:skipServerInstallation | Skip the UiAutomator2 Server component installation on the device under test and all the related checks if set to `true`. This could help to speed up the session startup if you know for sure the correct server version is installed on the device. In case the server is not installed or an incorrect version of it is installed then you may get an unexpected error later. `false` by default
|
|
50
53
|
appium:uiautomator2ServerLaunchTimeout | The maximum number of milliseconds to wait util UiAutomator2Server is listening on the device. `30000` ms by default
|
|
51
54
|
appium:uiautomator2ServerInstallTimeout | The maximum number of milliseconds to wait util UiAutomator2Server is installed on the device. `20000` ms by default
|
|
@@ -58,12 +61,12 @@ appium:skipDeviceInitialization | If set to `true` then device startup checks (w
|
|
|
58
61
|
Capability Name | Description
|
|
59
62
|
--- | ---
|
|
60
63
|
appium:app | Full path to the application to be tested (the app must be located on the same machine where the server is running). Both `.apk` and `.apks` application extensions are supported. Could also be an URL to a remote location. If neither of the `app`, `appPackage` or `browserName` capabilities are provided then the driver starts from the Dashboard and expects the test knows what to do next. Do not provide both `app` and `browserName` capabilities at once.
|
|
61
|
-
browserName | The name of the browser to run the test on. If this capability is provided then the driver will try to start the test in Web context mode (Native mode is applied by default). Read [Automating hybrid apps](
|
|
62
|
-
appium:appPackage | Application package identifier to be started. If not provided then UiAutomator2 will try to detect it automatically from the package provided by the `app` capability. Read [How To Troubleshoot Activities Startup](
|
|
63
|
-
appium:appActivity | Main application activity identifier. If not provided then UiAutomator2 will try to detect it automatically from the package provided by the `app` capability. Read [How To Troubleshoot Activities Startup](
|
|
64
|
-
appium:appWaitActivity | Identifier of the first activity that the application invokes. If not provided then equals to `appium:appActivity`. Read [How To Troubleshoot Activities Startup](
|
|
65
|
-
appium:appWaitPackage | Identifier of the first package that is invoked first. If not provided then equals to `appium:appPackage`. Read [How To Troubleshoot Activities Startup](
|
|
66
|
-
appium:appWaitDuration | Maximum amount of milliseconds to wait until the application under test is started (e. g. an activity returns the control to the caller). `20000` ms by default. Read [How To Troubleshoot Activities Startup](
|
|
64
|
+
browserName | The name of the browser to run the test on. If this capability is provided then the driver will try to start the test in Web context mode (Native mode is applied by default). Read [Automating hybrid apps](docs/activity-startup.md) for more details. Usually equals to `chrome`.
|
|
65
|
+
appium:appPackage | Application package identifier to be started. If not provided then UiAutomator2 will try to detect it automatically from the package provided by the `app` capability. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details
|
|
66
|
+
appium:appActivity | Main application activity identifier. If not provided then UiAutomator2 will try to detect it automatically from the package provided by the `app` capability. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details
|
|
67
|
+
appium:appWaitActivity | Identifier of the first activity that the application invokes. If not provided then equals to `appium:appActivity`. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details
|
|
68
|
+
appium:appWaitPackage | Identifier of the first package that is invoked first. If not provided then equals to `appium:appPackage`. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details
|
|
69
|
+
appium:appWaitDuration | Maximum amount of milliseconds to wait until the application under test is started (e. g. an activity returns the control to the caller). `20000` ms by default. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details
|
|
67
70
|
appium:androidInstallTimeout | Maximum amount of milliseconds to wait until the application under test is installed. `90000` ms by default
|
|
68
71
|
appium:appWaitForLaunch | Whether to block until the app under test returns the control to the caller after its activity has been started by Activity Manager (`true`, the default value) or to continue the test without waiting for that (`false`).
|
|
69
72
|
appium:intentCategory | Set an optional intent category to be applied when starting the given appActivity by [Activity Manager](https://developer.android.com/studio/command-line/adb#am). Defaults to `android.intent.category.LAUNCHER`. Please use [mobile:startActivity](#mobile-startactivity) in case you don't set an explicit value.
|
|
@@ -108,10 +111,10 @@ appium:allowDelayAdb | Being set to `false` prevents emulator to use `-delay-adb
|
|
|
108
111
|
|
|
109
112
|
Capability Name | Description
|
|
110
113
|
--- | ---
|
|
111
|
-
appium:avd | The name of Android emulator to run the test on. The names of currently installed emulators could be listed using `avdmanager list avd` command. If the emulator with the given name is not running then it is going to be
|
|
114
|
+
appium:avd | The name of Android emulator to run the test on. The names of currently installed emulators could be listed using `avdmanager list avd` command. If the emulator with the given name is not running then it is going to be launched on automated session startup.
|
|
112
115
|
appium:avdLaunchTimeout | Maximum number of milliseconds to wait until Android Emulator is started. `60000` ms by default
|
|
113
116
|
appium:avdReadyTimeout | Maximum number of milliseconds to wait until Android Emulator is fully booted and is ready for usage. `60000` ms by default
|
|
114
|
-
appium:avdArgs | Either a string or an array of emulator [command line arguments](https://developer.android.com/studio/run/emulator-commandline).
|
|
117
|
+
appium:avdArgs | Either a string or an array of emulator [command line arguments](https://developer.android.com/studio/run/emulator-commandline). If arguments contain the `-wipe-data` one then the emulator is going to be killed on automated session startup in order to wipe its data.
|
|
115
118
|
appium:avdEnv | Mapping of emulator [environment variables](https://developer.android.com/studio/command-line/variables).
|
|
116
119
|
appium:networkSpeed | Sets the desired network speed limit for the emulator. It is only applied if the emulator is not running before the test starts. See emulator [command line arguments](https://developer.android.com/studio/run/emulator-commandline) description for more details.
|
|
117
120
|
appium:gpsEnabled | Sets whether to enable (`true`) or disable (`false`) GPS service in the Emulator. Unset by default, which means to not change the current value
|
|
@@ -157,8 +160,8 @@ appium:chromedriverPort | The port number to use for Chromedriver communication.
|
|
|
157
160
|
appium:chromedriverPorts | Array of possible port numbers to assign for Chromedriver communication. If none of the port in this array is free then an error is thrown.
|
|
158
161
|
appium:chromedriverArgs | Array of chromedriver [command line arguments](http://www.assertselenium.com/java/list-of-chrome-driver-command-line-arguments/). Note, that not all command line arguments that are available for the desktop browser are also available for the mobile one.
|
|
159
162
|
appium:chromedriverExecutable | Full path to the chromedriver executable on the server file system.
|
|
160
|
-
appium:chromedriverExecutableDir | Full path to the folder where chromedriver executables are located. This folder is used then to store the downloaded chromedriver executables if automatic download is enabled. Read [Automatic Chromedriver Discovery article](
|
|
161
|
-
appium:chromedriverChromeMappingFile | Full path to the chromedrivers mapping file. This file is used to statically map webview/browser versions to the chromedriver versions that are capable of automating them. Read [Automatic Chromedriver Discovery article](
|
|
163
|
+
appium:chromedriverExecutableDir | Full path to the folder where chromedriver executables are located. This folder is used then to store the downloaded chromedriver executables if automatic download is enabled. Read [Automatic Chromedriver Discovery article](#automatic-discovery-of-compatible-chromedriver) for more details.
|
|
164
|
+
appium:chromedriverChromeMappingFile | Full path to the chromedrivers mapping file. This file is used to statically map webview/browser versions to the chromedriver versions that are capable of automating them. Read [Automatic Chromedriver Discovery article](#automatic-discovery-of-compatible-chromedriver) for more details.
|
|
162
165
|
appium:chromedriverUseSystemExecutable | Set it to `true` in order to enforce the usage of chromedriver, which gets downloaded by Appium automatically upon installation. This driver might not be compatible with the destination browser or a web view. `false` by default.
|
|
163
166
|
appium:chromedriverDisableBuildCheck | Being set to `true` disables the compatibility validation between the current chromedriver and the destination browser/web view. Use it with care.
|
|
164
167
|
appium:autoWebviewTimeout | Set the maximum number of milliseconds to wait until a web view is available if `autoWebview` capability is set to `true`. `2000` ms by default
|
|
@@ -218,7 +221,7 @@ Name | Description | Example
|
|
|
218
221
|
id | This strategy is mapped to the native UiAutomator's `By.res` [locator](https://developer.android.com/reference/androidx/test/uiautomator/BySelector#res(java.lang.String)) (exact match of element's resource name). Package identifier prefix is added automatically if unset and is equal to the identifier of the current application under test. | 'com.mycompany:id/resourceId'
|
|
219
222
|
accessibilityId | This strategy is mapped to the native UiAutomator's `By.desc` [locator](https://developer.android.com/reference/androidx/test/uiautomator/BySelector#desc(java.lang.String)) (exact match of element's content description). | 'my description'
|
|
220
223
|
className | This strategy is mapped to the native UiAutomator's `By.clazz` [locator](https://developer.android.com/reference/androidx/test/uiautomator/BySelector#clazz(java.lang.String)) (exact match of element's class). | 'android.view.View'
|
|
221
|
-
`-android uiautomator` | This strategy is mapped to the native UiAutomator's `UiSelector` [locator](https://developer.android.com/reference/androidx/test/uiautomator/UiSelector)). It is even possible to perform some advanced operations, like scrolling, with this locator type | `new UiScrollable(new UiSelector().resourceId(\"android:id/list\")).scrollIntoView(new UiSelector().text(\"Radio Group\"))`
|
|
224
|
+
`-android uiautomator` | This strategy is mapped to the native UiAutomator's `UiSelector` [locator](https://developer.android.com/reference/androidx/test/uiautomator/UiSelector)). It is even possible to perform some advanced operations, like scrolling, with this locator type. Check [Guide on UiAutomator Locator Types](docs/uiautomator-uiselector.md) | `new UiScrollable(new UiSelector().resourceId(\"android:id/list\")).scrollIntoView(new UiSelector().text(\"Radio Group\"))`
|
|
222
225
|
xpath | For elements lookup Xpath strategy the driver uses the same XML tree that is generated by page source API. Only Xpath 1.0 is supported for appium-uiatomator2-server versions below 4.25.0. All server versions starting from 4.25.0 support both Xpath 1.0 and 2.0 | `By.xpath("//android.view.View[@text=\"Regular\" and @checkable=\"true\"]")`
|
|
223
226
|
|
|
224
227
|
|
|
@@ -289,7 +292,7 @@ Beside of standard W3C APIs the driver provides the following custom command ext
|
|
|
289
292
|
|
|
290
293
|
### mobile: shell
|
|
291
294
|
|
|
292
|
-
Executes the given shell command on the device under test via ADB connection. This extension exposes a potential security risk and thus is only enabled when explicitly activated by the `adb_shell` server
|
|
295
|
+
Executes the given shell command on the device under test via ADB connection. This extension exposes a potential security risk and thus is only enabled when explicitly activated by the `adb_shell` server command line feature specifier.
|
|
293
296
|
|
|
294
297
|
#### Arguments
|
|
295
298
|
|
|
@@ -307,7 +310,7 @@ Depending on the `includeStderr` value this API could either return a string, wh
|
|
|
307
310
|
### mobile: execEmuConsoleCommand
|
|
308
311
|
|
|
309
312
|
Executes a command through emulator telnet console interface and returns its output.
|
|
310
|
-
The `emulator_console` server
|
|
313
|
+
The `emulator_console` server feature must be enabled in order to use this method.
|
|
311
314
|
|
|
312
315
|
#### Arguments
|
|
313
316
|
|
|
@@ -336,7 +339,8 @@ UiAutomator2 provides several extensions that allow to automate popular mobile g
|
|
|
336
339
|
- mobile: swipeGesture
|
|
337
340
|
- mobile: scrollGesture
|
|
338
341
|
|
|
339
|
-
These gestures are documented in the [Automating Mobile Gestures](
|
|
342
|
+
These gestures are documented in the [Automating Mobile Gestures](docs/android-mobile-gestures.md) tutorial. Check [W3C Actions API](https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api) and
|
|
343
|
+
[Low-Level Insights on Android Input Events](docs/actions.md) if you need to automate more complicated gestures.
|
|
340
344
|
|
|
341
345
|
### mobile: scroll
|
|
342
346
|
|
|
@@ -455,11 +459,31 @@ Array of strings, where each string is a permission name. the array could be emp
|
|
|
455
459
|
|
|
456
460
|
### mobile: performEditorAction
|
|
457
461
|
|
|
458
|
-
Performs IME action on the
|
|
462
|
+
Performs IME action on the _currently focused_ edit element.
|
|
463
|
+
|
|
464
|
+
Very often Android developers use [onEditorAction](https://developer.android.com/reference/android/widget/TextView.OnEditorActionListener.html#onEditorAction(android.widget.TextView,%20int,%20android.view.KeyEvent)) callback with `actionId` argument to implement actions handling, for example, when `Search` or `Done` button is pressed on the on-screen keyboard. This mobile extension is supposed to emulate the invokation of such callback on the focused element.
|
|
465
|
+
|
|
466
|
+
#### Arguments
|
|
467
|
+
|
|
468
|
+
Name | Type | Required | Description | Example
|
|
469
|
+
--- | --- | --- | --- | ---
|
|
470
|
+
action | string | yes | The name or an integer code of the editor action to be executed. The following action names are supported: `normal, unspecified, none, go, search, send, next, done, previous`. Read [EditorInfo](https://developer.android.com/reference/android/view/inputmethod/EditorInfo) for more details on this topic. | search
|
|
471
|
+
|
|
472
|
+
#### Examples
|
|
473
|
+
|
|
474
|
+
```java
|
|
475
|
+
// Java
|
|
476
|
+
driver.executeScript("mobile: performEditorAction", ImmutableMap.of("action", "Go"));
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
```python
|
|
480
|
+
# Python
|
|
481
|
+
driver.execute_script('mobile: performEditorAction', {'action': 'previous'})
|
|
482
|
+
```
|
|
459
483
|
|
|
460
484
|
### mobile: startScreenStreaming
|
|
461
485
|
|
|
462
|
-
Starts device screen broadcast by creating MJPEG server. Multiple calls to this method have no effect unless the previous streaming session is stopped. This method only works if the `adb_screen_streaming`
|
|
486
|
+
Starts device screen broadcast by creating MJPEG server. Multiple calls to this method have no effect unless the previous streaming session is stopped. This method only works if the `adb_screen_streaming` feature is enabled on the server side. It is also required that [GStreamer](https://gstreamer.freedesktop.org/) with `gst-plugins-base`, `gst-plugins-good` and `gst-plugins-bad` packages are installed and available in PATH on the server machine.
|
|
463
487
|
|
|
464
488
|
#### Arguments
|
|
465
489
|
|
|
@@ -1015,6 +1039,199 @@ Useful links:
|
|
|
1015
1039
|
- https://appiumpro.com/editions/16-automating-the-clipboard-on-ios-and-android
|
|
1016
1040
|
|
|
1017
1041
|
|
|
1042
|
+
## Hybrid Mode
|
|
1043
|
+
|
|
1044
|
+
UIA2 driver supports automation of web pages opened in mobile Chrome or Chromium, and
|
|
1045
|
+
hybrid apps that use Chrome-based web views, by managing a
|
|
1046
|
+
[Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/) instance and
|
|
1047
|
+
proxying commands to it when necessary.
|
|
1048
|
+
|
|
1049
|
+
The following endpoints are used to control the current context:
|
|
1050
|
+
|
|
1051
|
+
- POST `/session/:sessionId/context`: To set the current context. The body contains a single mandatory `name` parameter, which has the name of the context to be set. The name of the default context is `NATIVE_APP`.
|
|
1052
|
+
- GET `/session/:sessionId/context`: To retrieve the name of the current context
|
|
1053
|
+
- GET `/session/:sessionId/contexts`: To retrieve the list of available context names
|
|
1054
|
+
- [mobile: getContexts](#mobile-getcontexts)
|
|
1055
|
+
|
|
1056
|
+
By default the driver starts in the native context, which means that most of REST API commands are being
|
|
1057
|
+
forwarded to the downstream [appium-uiautomator2-server](https://github.com/appium/appium-uiautomator2-server).
|
|
1058
|
+
This server is running on the device under test, and trasforms API commands to appropriate low-level UiAutomator framework calls. There is always only one native context, although multiple web contexts are possible.
|
|
1059
|
+
Each web context could contain zero or more pages/windows. It is possible to start UIA2 driver session in web context by default by setting the `browserName` capability value or by enabling the `appium:autoWebview` capability.
|
|
1060
|
+
|
|
1061
|
+
Web context(s) could be detected if a browser or a web view is active on the device. If a context is switched to
|
|
1062
|
+
a web one then UIA2 driver spins up a Chromedriver instance for it and forwards most of the commands
|
|
1063
|
+
to that Chromedriver instance. Note that web views must be properly configured and
|
|
1064
|
+
debuggable in order to connect to them or get their names in the list of available contexts.
|
|
1065
|
+
The availablity of a particular web view could be easily verified by using
|
|
1066
|
+
[Chrome Remote Debugger](https://developer.chrome.com/docs/devtools/remote-debugging/).
|
|
1067
|
+
You could switch between different contexts (and windows in them) at any time during the session.
|
|
1068
|
+
|
|
1069
|
+
The [appium-chromedriver](https://github.com/appium/appium-chromedriver) package bundled with UIA2 always
|
|
1070
|
+
tries to download the most recent version of Chromedriver known to it. Google requires that the used Chromedriver version must always match to the version of the browser or a web view engine being automated. If these versions do not match then Chromedriver fails its creation, and context switch API shows a failure message
|
|
1071
|
+
similar to:
|
|
1072
|
+
|
|
1073
|
+
```
|
|
1074
|
+
An unknown server-side error occurred while processing the command.
|
|
1075
|
+
Original error: unknown error: Chrome version must be >= 55.0.2883.0
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
To work around this issue it is necessary to provide UIA2 driver with a proper Chromedriver binary
|
|
1079
|
+
that matches to the Chrome engine version running on the device under test.
|
|
1080
|
+
Read the [Chromedriver/Chrome compatibility](#chromedriverchrome-compatibility) topic below to
|
|
1081
|
+
know more about finding a matching Chromedriver executable.
|
|
1082
|
+
|
|
1083
|
+
There are several ways to provide a customized Chromedriver to UIA2 driver:
|
|
1084
|
+
|
|
1085
|
+
#### When installing the driver
|
|
1086
|
+
|
|
1087
|
+
Specify the Chromedriver version in the `CHROMEDRIVER_VERSION` environment variable:
|
|
1088
|
+
|
|
1089
|
+
```bash
|
|
1090
|
+
CHROMEDRIVER_VERSION=2.20 appium install driver uiautomator2
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
#### When starting a session (manual discovery)
|
|
1094
|
+
|
|
1095
|
+
Chromedriver version can be specified in session capabilities, by providing the
|
|
1096
|
+
`appium:chromedriverExecutable` [capability](#web-context),
|
|
1097
|
+
containing the full path to a matching Chromedriver executable, which must be manually
|
|
1098
|
+
downloaded and put to the server file system.
|
|
1099
|
+
|
|
1100
|
+
#### When starting a session (automated discovery)
|
|
1101
|
+
|
|
1102
|
+
UIA2 driver could also try to detect the version of the target Chrome engine and
|
|
1103
|
+
download matching chromedriver for it automatically if it does not exist on the local file system.
|
|
1104
|
+
Read the [Automatic discovery of compatible Chromedriver](#automatic-discovery-of-compatible-chromedriver)
|
|
1105
|
+
topic below for more details.
|
|
1106
|
+
|
|
1107
|
+
### Chromedriver/Chrome Compatibility
|
|
1108
|
+
|
|
1109
|
+
Since version *2.46* Google has changed their rules for Chromedriver versioning, so now the major Chromedriver version corresponds to the major web view/browser version, that it can automate. Follow the [Version Selection](https://chromedriver.chromium.org/downloads/version-selection) document in order to manually find the Chromedriver, that supports your current browser/web view if its major version is equal or above *73*.
|
|
1110
|
+
|
|
1111
|
+
To find the minimum supported browsers for older Chromedriver versions (below *73*), get the
|
|
1112
|
+
[Chromium](https://www.chromium.org/Home)
|
|
1113
|
+
[source code](https://chromium.googlesource.com/chromium/src/+/master/docs/get_the_code.md),
|
|
1114
|
+
check out the release commit, and check the variable `kMinimumSupportedChromeVersion`
|
|
1115
|
+
in the file `src/chrome/test/chromedriver/chrome/version.cc`. (To find the
|
|
1116
|
+
release commits, you could use `git log --pretty=format:'%h | %s%d' | grep -i "Release Chromedriver version"`.)
|
|
1117
|
+
|
|
1118
|
+
The complete list of available Chromedriver releases and release notes is located at [Chromedriver Storage](https://chromedriver.storage.googleapis.com/index.html).
|
|
1119
|
+
|
|
1120
|
+
The list of Chromedriver versions and their matching minimum
|
|
1121
|
+
Chrome versions known to appium-chromedriver package is stored at
|
|
1122
|
+
https://raw.githubusercontent.com/appium/appium-chromedriver/master/config/mapping.json
|
|
1123
|
+
|
|
1124
|
+
### Automatic Discovery of Compatible Chromedriver
|
|
1125
|
+
|
|
1126
|
+
UIA2 driver is able to pick the correct Chromedriver for the
|
|
1127
|
+
version of Chrome/web view under test. While appium-chromedriver only comes bundled with the Chromedriver
|
|
1128
|
+
most recently released at the time of the corresponding package version's release, more Chromedriver
|
|
1129
|
+
versions could be downloaded and placed into a custom location indicated to UIA2 driver via the `appium:chromedriverExecutableDir` [capability](#web-context).
|
|
1130
|
+
|
|
1131
|
+
A custom mapping of Chromedrivers to the minimum
|
|
1132
|
+
Chrome/web view version they support could be given to UIA2 driver through the
|
|
1133
|
+
`appium:chromedriverChromeMappingFile` [capability](#web-context). This should be the
|
|
1134
|
+
absolute path to a file with the mapping
|
|
1135
|
+
in it. The contents of the file needs to be parsable as a JSON object, like:
|
|
1136
|
+
|
|
1137
|
+
```json
|
|
1138
|
+
{
|
|
1139
|
+
"2.42": "63.0.3239",
|
|
1140
|
+
"2.41": "62.0.3202"
|
|
1141
|
+
}
|
|
1142
|
+
```
|
|
1143
|
+
|
|
1144
|
+
There is a possibility to automatically download the necessary chromedriver(s) into `appium:chromedriverExecutableDir` from the official Google storage. The script will automatically search for the newest chromedriver version that supports the given browser/web view, download it (the hash sum is verified as well for the downloaded archive) and add to the `appium:chromedriverChromeMappingFile` mapping. Everything, which is needed to be done from your side is to execute the server with `chromedriver_autodownload` feature enabled (like `appium server --allow-insecure chromedriver_autodownload`).
|
|
1145
|
+
|
|
1146
|
+
### Troubleshooting Chromedriver Download Issues
|
|
1147
|
+
|
|
1148
|
+
When UIA2 driver is installed it automatically downloads Chromedriver, so there is a possibility
|
|
1149
|
+
of network or other issues leading to an installation failure.
|
|
1150
|
+
|
|
1151
|
+
By default Chromedriver is retrieved from `https://chromedriver.storage.googleapis.com/`.
|
|
1152
|
+
To use a mirror of the above URL change the value of `CHROMEDRIVER_CDNURL` environemnt variable:
|
|
1153
|
+
|
|
1154
|
+
```bash
|
|
1155
|
+
CHROMEDRIVER_CDNURL=https://npmmirror.com/mirrors/chromedriver appium driver install uiautomator2
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
It may also be necessary to adjust network proxy and firewall settings for the above to work.
|
|
1159
|
+
|
|
1160
|
+
In case you would like skip the download of Chromedriver entirely, do it by
|
|
1161
|
+
defining the `APPIUM_SKIP_CHROMEDRIVER_INSTALL` environment variable:
|
|
1162
|
+
|
|
1163
|
+
```bash
|
|
1164
|
+
APPIUM_SKIP_CHROMEDRIVER_INSTALL=1 appium driver install uiautomator2
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
### W3C Support in Web Context
|
|
1168
|
+
|
|
1169
|
+
Chromedriver did not follow the W3C standard until version 75. If you encounter proxy command error like [this issue](https://github.com/appium/python-client/issues/234), please update your Chromedriver version.
|
|
1170
|
+
Old Android devices can't use newer Chromedriver versions. You could avoid the error if you enforce
|
|
1171
|
+
Mobile JSON Wire Protocol for Chromedriver. This could be done by providing `{'w3c': False}` item
|
|
1172
|
+
to `appium:chromeOptions` capability value.
|
|
1173
|
+
Since major version *75* W3C mode is the default one for Chromedriver, although it could be still switched to JSONWP one as described above (keep in mind that eventually Chromedriver will drop the support of
|
|
1174
|
+
JSON Wire protocol completely).
|
|
1175
|
+
The history of W3C support in Chromedriver is available for reading at
|
|
1176
|
+
[downloads section](https://sites.google.com/a/chromium.org/chromedriver/downloads).
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
## Troubleshooting
|
|
1180
|
+
|
|
1181
|
+
### Activity Startup
|
|
1182
|
+
|
|
1183
|
+
If you experince issues with application activities being not found or not starting then consider checking [How To Troubleshoot Activities Startup](docs/activity-startup.md) article.
|
|
1184
|
+
|
|
1185
|
+
### Poor Elements Interaction Performance
|
|
1186
|
+
|
|
1187
|
+
If you observe automated tests need at least 10 seconds or more to locate/interact with a single element then consider changing the default value for [waitForIdleTimeout setting](#settings-api). By default, UiAutomator framework (and all other Accessiblity-based frameworks) always waits for the accessibility event stream to become idle before interacting with it (the default timeout there is 10000ms). This is needed to make sure all animations/transitions are finished before you, for example, interact with an element by clicking it. In case the application under test constantly runs some background animations or hogs the accessibility event stream in some other way these waits may significatly slow down the automation flow.
|
|
1188
|
+
|
|
1189
|
+
Setting the value of `waitForIdleTimeout` to zero `0` ms should completely disable any waits, and enforce interactions to happen immediately ignoring the accessibility event stream state. The downside of that would be that all interactions are never going to be delayed, so clicks and other actions might happen at wrong places of the application UI. That is why is it important to check the app under test first and fix its source to get rid of activities hogging the event loop. Sometimes it makes sence to disable animations completely for the app build under test, which could speed up your flows significantly in some situations.
|
|
1190
|
+
|
|
1191
|
+
> **Warning**
|
|
1192
|
+
> `waitForIdleTimeout` is a setting, not a capability.
|
|
1193
|
+
|
|
1194
|
+
### Session Startup Issues
|
|
1195
|
+
|
|
1196
|
+
Sometimes various legacy driver parts might be cached on the device under test (like settings.apk), which would prevent a new/upgraded driver version from starting a session. Run
|
|
1197
|
+
|
|
1198
|
+
```bash
|
|
1199
|
+
appium driver run uiautomator2 reset
|
|
1200
|
+
```
|
|
1201
|
+
|
|
1202
|
+
in order to cleanup the cached UIA2 driver binaries from all connected devices on the current machine.
|
|
1203
|
+
|
|
1204
|
+
### Element(s) Cannot be Found
|
|
1205
|
+
|
|
1206
|
+
All element location strategies in UIA2 driver work similarly under the hood except of the xpath one.
|
|
1207
|
+
If some element is not found, but you see/assume it is present in the page source then make sure no race condition
|
|
1208
|
+
happens. Add a timer and wait for a couple of seconds before giving up on the element location. In case the lookup
|
|
1209
|
+
still fails after the timeout and your non-xpath locator is used then, most likely, it contains a typo, or the
|
|
1210
|
+
destination element is not present. There is not much that could be done in UIA2 to change/influence that, since it passes such lookup calls directly to Google's UiAutomator framework.
|
|
1211
|
+
|
|
1212
|
+
In case of xpath locators you could also try to change values of the following settings:
|
|
1213
|
+
|
|
1214
|
+
1. [allowInvisibleElements](#settings-api)
|
|
1215
|
+
2. [ignoreUnimportantViews](#settings-api)
|
|
1216
|
+
3. [enableMultiWindows](#settings-api)
|
|
1217
|
+
|
|
1218
|
+
By default, the first setting is set to `false`, which hides
|
|
1219
|
+
elements that are not visible from the the page source and from the xpath location. Changing the setting value
|
|
1220
|
+
to `true` would add such invisible elements to the page source and make them locatable.
|
|
1221
|
+
|
|
1222
|
+
The second one is enabled by default (e.g. `true`). By disabling it the page source could receive more elements
|
|
1223
|
+
that are normally hidden, because of their unimportance.
|
|
1224
|
+
|
|
1225
|
+
The third setting being set to `true` extends the page source by adding the actual content of other windows that are currently present on the device's screen. For example, the on-screen keyboard in Android is not a part of the current app hierarchy, but rather belongs to a separate window.
|
|
1226
|
+
|
|
1227
|
+
> **Warning**
|
|
1228
|
+
> Default values for settings above have been selected to optimize xpath lookup and page source generation performance.
|
|
1229
|
+
> Having these settings always different from their default values may sometimes significantly (especially in case of huge accessbility hierarchies) reduce xpath lookup and page source generation speed.
|
|
1230
|
+
|
|
1231
|
+
> **Warning**
|
|
1232
|
+
> All items above are settings, not capabilities.
|
|
1233
|
+
|
|
1234
|
+
|
|
1018
1235
|
## Usage Examples
|
|
1019
1236
|
|
|
1020
1237
|
```python
|
|
@@ -1037,15 +1254,14 @@ def generate_options():
|
|
|
1037
1254
|
app_options = UiAutomator2Options().load_capabilities(common_caps)
|
|
1038
1255
|
app_options.app = '/Projects/myapp.apk'
|
|
1039
1256
|
# It might also be necessary to provide more info about app activities
|
|
1040
|
-
# Read
|
|
1257
|
+
# Read [How To Troubleshoot Activities Startup](docs/activity-startup.md)
|
|
1041
1258
|
# for more details
|
|
1042
1259
|
# app_options.appPackage = 'com.mypackage'
|
|
1043
1260
|
# app_options.appActivity = '.myMainActivity'
|
|
1044
1261
|
# app_options.appWaitActivity = '.mySplashScreenActivity'
|
|
1045
1262
|
chrome_options = UiAutomator2Options().load_capabilities(common_caps)
|
|
1046
1263
|
chrome_options.browser_name = 'chrome'
|
|
1047
|
-
# Read
|
|
1048
|
-
# Read https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/hybrid.md
|
|
1264
|
+
# Read [Hybrid Mode](#hybrid-mode)
|
|
1049
1265
|
chrome_options.chromedriver_executable = '/Project/chromedriver_linux64'
|
|
1050
1266
|
return [app_options, chrome_options]
|
|
1051
1267
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","names":["commands","helpers","extensions","pressKeyCode","keycode","metastate","flags","uiautomator2","jwproxy","command","longPressKeyCode","doSwipe","swipeOpts","doDrag","dragOpts","getOrientation","setOrientation","orientation","toUpperCase","Object","assign"],"sources":["../../../lib/commands/actions.js"],"sourcesContent":["\n\nlet commands = {}, helpers = {}, extensions = {};\n\ncommands.pressKeyCode = async function (keycode, metastate = null, flags = null) {\n return await this.uiautomator2.jwproxy.command('/appium/device/press_keycode', 'POST', {\n keycode,\n metastate,\n flags,\n });\n};\n\ncommands.longPressKeyCode = async function (keycode, metastate = null, flags = null) {\n return await this.uiautomator2.jwproxy.command('/appium/device/long_press_keycode', 'POST', {\n keycode,\n metastate,\n flags\n });\n};\n\ncommands.doSwipe = async function (swipeOpts) {\n return await this.uiautomator2.jwproxy.command(`/touch/perform`, 'POST', swipeOpts);\n};\n\ncommands.doDrag = async function (dragOpts) {\n return await this.uiautomator2.jwproxy.command(`/touch/drag`, 'POST', dragOpts);\n};\n\ncommands.getOrientation = async function () {\n return await this.uiautomator2.jwproxy.command(`/orientation`, 'GET', {});\n};\n\ncommands.setOrientation = async function (orientation) {\n orientation = orientation.toUpperCase();\n return await this.uiautomator2.jwproxy.command(`/orientation`, 'POST', {orientation});\n};\n\nObject.assign(extensions, commands, helpers);\nexport { commands, helpers };\nexport default extensions;\n"],"mappings":";;;;;;;;;AAEA,IAAIA,QAAQ,GAAG,EAAf;AAAA,IAAmBC,OAAO,GAAG,EAA7B;AAAA,IAAiCC,UAAU,GAAG,EAA9C;;;;AAEAF,QAAQ,CAACG,YAAT,GAAwB,gBAAgBC,OAAhB,EAAyBC,SAAS,GAAG,IAArC,EAA2CC,KAAK,GAAG,IAAnD,EAAyD;EAC/E,OAAO,MAAM,KAAKC,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,8BAAlC,EAAkE,MAAlE,EAA0E;IACrFL,OADqF;IAErFC,SAFqF;IAGrFC;EAHqF,CAA1E,CAAb;AAKD,CAND;;AAQAN,QAAQ,CAACU,gBAAT,GAA4B,gBAAgBN,OAAhB,EAAyBC,SAAS,GAAG,IAArC,EAA2CC,KAAK,GAAG,IAAnD,EAAyD;EACnF,OAAO,MAAM,KAAKC,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,mCAAlC,EAAuE,MAAvE,EAA+E;IAC1FL,OAD0F;IAE1FC,SAF0F;IAG1FC;EAH0F,CAA/E,CAAb;AAKD,CAND;;AAQAN,QAAQ,CAACW,OAAT,GAAmB,gBAAgBC,SAAhB,EAA2B;EAC5C,OAAO,MAAM,KAAKL,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAmC,gBAAnC,EAAoD,MAApD,EAA4DG,SAA5D,CAAb;AACD,CAFD;;AAIAZ,QAAQ,CAACa,MAAT,GAAkB,gBAAgBC,QAAhB,EAA0B;EAC1C,OAAO,MAAM,KAAKP,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAmC,aAAnC,EAAiD,MAAjD,EAAyDK,QAAzD,CAAb;AACD,CAFD;;AAIAd,QAAQ,CAACe,cAAT,GAA0B,kBAAkB;EAC1C,OAAO,MAAM,KAAKR,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAmC,cAAnC,EAAkD,KAAlD,EAAyD,EAAzD,CAAb;AACD,CAFD;;AAIAT,QAAQ,CAACgB,cAAT,GAA0B,gBAAgBC,WAAhB,EAA6B;EACrDA,WAAW,GAAGA,WAAW,CAACC,WAAZ,EAAd;EACA,OAAO,MAAM,KAAKX,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAmC,cAAnC,EAAkD,MAAlD,EAA0D;IAACQ;EAAD,CAA1D,CAAb;AACD,CAHD;;AAKAE,MAAM,CAACC,MAAP,CAAclB,UAAd,EAA0BF,QAA1B,EAAoCC,OAApC;eAEeC,U"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert.js","names":["commands","helpers","extensions","getAlertText","uiautomator2","jwproxy","command","mobileAcceptAlert","opts","postAcceptAlert","mobileDismissAlert","postDismissAlert","Object","assign"],"sources":["../../../lib/commands/alert.js"],"sourcesContent":["let commands = {}, helpers = {}, extensions = {};\n\ncommands.getAlertText = async function () {\n return await this.uiautomator2.jwproxy.command('/alert/text', 'GET', {});\n};\n\n/**\n * @typedef {Object} AcceptAlertOptions\n * @property {?string} buttonLabel - The name of the button to click in order to\n * accept the alert. If the name is not provided\n * then the script will try to detect the button\n * automatically.\n */\n\n/**\n * @param {AcceptAlertOptions} opts\n * @throws {InvalidElementStateError} If no matching button, that can accept the alert,\n * can be found\n * @throws {NoAlertOpenError} If no alert is present\n */\ncommands.mobileAcceptAlert = async function (opts = {}) {\n return await this.uiautomator2.jwproxy.command('/alert/accept', 'POST', opts);\n};\n\ncommands.postAcceptAlert = async function () {\n return await this.mobileAcceptAlert();\n};\n\n/**\n * @typedef {Object} DismissAlertOptions\n * @property {?string} buttonLabel - The name of the button to click in order to\n * dismiss the alert. If the name is not provided\n * then the script will try to detect the button\n * automatically.\n */\n\n/**\n * @param {DismissAlertOptions} opts\n * @throws {InvalidElementStateError} If no matching button, that can dismiss the alert,\n * can be found\n * @throws {NoAlertOpenError} If no alert is present\n */\ncommands.mobileDismissAlert = async function (opts = {}) {\n return await this.uiautomator2.jwproxy.command('/alert/dismiss', 'POST', opts);\n};\n\ncommands.postDismissAlert = async function () {\n return await this.mobileDismissAlert();\n};\n\nObject.assign(extensions, commands, helpers);\nexport { commands, helpers };\nexport default extensions;\n"],"mappings":";;;;;;;;;AAAA,IAAIA,QAAQ,GAAG,EAAf;AAAA,IAAmBC,OAAO,GAAG,EAA7B;AAAA,IAAiCC,UAAU,GAAG,EAA9C;;;;AAEAF,QAAQ,CAACG,YAAT,GAAwB,kBAAkB;EACxC,OAAO,MAAM,KAAKC,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,aAAlC,EAAiD,KAAjD,EAAwD,EAAxD,CAAb;AACD,CAFD;;AAkBAN,QAAQ,CAACO,iBAAT,GAA6B,gBAAgBC,IAAI,GAAG,EAAvB,EAA2B;EACtD,OAAO,MAAM,KAAKJ,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,eAAlC,EAAmD,MAAnD,EAA2DE,IAA3D,CAAb;AACD,CAFD;;AAIAR,QAAQ,CAACS,eAAT,GAA2B,kBAAkB;EAC3C,OAAO,MAAM,KAAKF,iBAAL,EAAb;AACD,CAFD;;AAkBAP,QAAQ,CAACU,kBAAT,GAA8B,gBAAgBF,IAAI,GAAG,EAAvB,EAA2B;EACvD,OAAO,MAAM,KAAKJ,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,gBAAlC,EAAoD,MAApD,EAA4DE,IAA5D,CAAb;AACD,CAFD;;AAIAR,QAAQ,CAACW,gBAAT,GAA4B,kBAAkB;EAC5C,OAAO,MAAM,KAAKD,kBAAL,EAAb;AACD,CAFD;;AAIAE,MAAM,CAACC,MAAP,CAAcX,UAAd,EAA0BF,QAA1B,EAAoCC,OAApC;eAEeC,U"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"battery.js","names":["extensions","commands","mobileGetBatteryInfo","result","uiautomator2","jwproxy","command","state","status","Object","assign"],"sources":["../../../lib/commands/battery.js"],"sourcesContent":["let extensions = {}, commands = {};\n\n/**\n * @typedef {Object} BatteryInfo\n *\n * @property {number} level - Battery level in range [0.0, 1.0], where\n * 1.0 means 100% charge.\n * -1 is returned if the actual value cannot be\n * retrieved from the system.\n * @property {number} state - Battery state. The following values are possible:\n * BATTERY_STATUS_UNKNOWN = 1\n * BATTERY_STATUS_CHARGING = 2\n * BATTERY_STATUS_DISCHARGING = 3\n * BATTERY_STATUS_NOT_CHARGING = 4\n * BATTERY_STATUS_FULL = 5\n * -1 is returned if the actual value cannot be retrieved from the system.\n */\n\n/**\n * Reads the battery information from the device under test.\n *\n * @returns {BatteryInfo} The actual battery info\n */\ncommands.mobileGetBatteryInfo = async function () {\n const result = await this.uiautomator2.jwproxy.command('/appium/device/battery_info', 'GET', {});\n // Give it the same name as in iOS\n result.state = result.status;\n delete result.status;\n return result;\n};\n\nObject.assign(extensions, commands);\nexport { commands };\nexport default extensions;\n"],"mappings":";;;;;;;;;AAAA,IAAIA,UAAU,GAAG,EAAjB;AAAA,IAAqBC,QAAQ,GAAG,EAAhC;;;AAuBAA,QAAQ,CAACC,oBAAT,GAAgC,kBAAkB;EAChD,MAAMC,MAAM,GAAG,MAAM,KAAKC,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,6BAAlC,EAAiE,KAAjE,EAAwE,EAAxE,CAArB;EAEAH,MAAM,CAACI,KAAP,GAAeJ,MAAM,CAACK,MAAtB;EACA,OAAOL,MAAM,CAACK,MAAd;EACA,OAAOL,MAAP;AACD,CAND;;AAQAM,MAAM,CAACC,MAAP,CAAcV,UAAd,EAA0BC,QAA1B;eAEeD,U"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element.js","names":["commands","helpers","extensions","toBool","s","_","isString","toLowerCase","active","uiautomator2","jwproxy","command","getAttribute","attribute","elementId","elementDisplayed","elementEnabled","elementSelected","getName","getLocation","getSize","touchLongClick","element","x","y","duration","params","touchDown","touchUp","touchMove","doSetElementValue","setValueImmediate","keys","text","isArray","join","replace","unicodeKeyboard","opts","getText","click","getElementScreenshot","tap","count","areCoordinatesDefined","util","hasValue","Error","i","W3C_ELEMENT_KEY","clear","getElementRect","isWebContext","log","debug","chromedriver","downstreamProtocol","PROTOCOLS","MJSONWP","width","height","Object","assign"],"sources":["../../../lib/commands/element.js"],"sourcesContent":["import _ from 'lodash';\nimport { util } from 'appium/support';\nimport { PROTOCOLS, W3C_ELEMENT_KEY } from 'appium/driver';\n\nlet commands = {}, helpers = {}, extensions = {};\n\nfunction toBool (s) {\n return _.isString(s) ? (s.toLowerCase() === 'true') : !!s;\n}\n\ncommands.active = async function active () {\n return await this.uiautomator2.jwproxy.command('/element/active', 'GET');\n};\n\ncommands.getAttribute = async function (attribute, elementId) {\n return await this.uiautomator2.jwproxy.command(`/element/${elementId}/attribute/${attribute}`, 'GET', {});\n};\n\ncommands.elementDisplayed = async function (elementId) {\n return toBool(await this.getAttribute('displayed', elementId));\n};\n\ncommands.elementEnabled = async function (elementId) {\n return toBool(await this.getAttribute('enabled', elementId));\n};\n\ncommands.elementSelected = async function (elementId) {\n return toBool(await this.getAttribute('selected', elementId));\n};\n\ncommands.getName = async function (elementId) {\n return await this.uiautomator2.jwproxy.command(`/element/${elementId}/name`, 'GET', {});\n};\n\ncommands.getLocation = async function (elementId) {\n return await this.uiautomator2.jwproxy.command(`/element/${elementId}/location`, 'GET', {});\n};\n\ncommands.getSize = async function (elementId) {\n return await this.uiautomator2.jwproxy.command(`/element/${elementId}/size`, 'GET', {});\n};\n\ncommands.touchLongClick = async function (element, x, y, duration) {\n let params = {element, x, y, duration};\n return await this.uiautomator2.jwproxy.command(`/touch/longclick`, 'POST', {params});\n};\n\ncommands.touchDown = async function (element, x, y) {\n let params = {element, x, y};\n return await this.uiautomator2.jwproxy.command(`/touch/down`, 'POST', {params});\n};\n\ncommands.touchUp = async function (element, x, y) {\n let params = {element, x, y};\n return await this.uiautomator2.jwproxy.command(`/touch/up`, 'POST', {params});\n};\n\ncommands.touchMove = async function (element, x, y) {\n let params = {element, x, y};\n return await this.uiautomator2.jwproxy.command(`/touch/move`, 'POST', {params});\n};\n\nhelpers.doSetElementValue = async function (params) {\n return await this.uiautomator2.jwproxy.command(`/element/${params.elementId}/value`, 'POST', params);\n};\n\ncommands.setValueImmediate = async function (keys, elementId) {\n return await this.uiautomator2.jwproxy.command(`/element/${elementId}/value`, 'POST', {\n elementId,\n text: _.isArray(keys) ? keys.join('') : keys,\n replace: false,\n unicodeKeyboard: this.opts.unicodeKeyboard,\n });\n};\n\ncommands.getText = async function (elementId) {\n return await this.uiautomator2.jwproxy.command(`/element/${elementId}/text`, 'GET', {});\n};\n\ncommands.click = async function (element) {\n return await this.uiautomator2.jwproxy.command(`/element/${element}/click`, 'POST', {element});\n};\n\ncommands.getElementScreenshot = async function (element) {\n return await this.uiautomator2.jwproxy.command(`/element/${element}/screenshot`, 'GET', {});\n};\n\ncommands.tap = async function (elementId = null, x = null, y = null, count = 1) {\n const areCoordinatesDefined = util.hasValue(x) && util.hasValue(y);\n if (!util.hasValue(elementId) && !areCoordinatesDefined) {\n throw new Error(`Either element id to tap or both absolute coordinates should be defined`);\n }\n\n for (let i = 0; i < count; i++) {\n if (util.hasValue(elementId) && !areCoordinatesDefined) {\n // we are either tapping on the default location of the element\n // or an offset from the top left corner\n await this.uiautomator2.jwproxy.command(`/element/${elementId}/click`, 'POST');\n } else {\n await this.uiautomator2.jwproxy.command(`/appium/tap`, 'POST', {\n x, y,\n [W3C_ELEMENT_KEY]: elementId,\n });\n }\n }\n};\n\ncommands.clear = async function (elementId) {\n return await this.uiautomator2.jwproxy.command(`/element/${elementId}/clear`, 'POST', {elementId});\n};\n\ncommands.getElementRect = async function (elementId) {\n if (this.isWebContext()) {\n this.log.debug(`Detected downstream chromedriver protocol: ${this.chromedriver.jwproxy.downstreamProtocol}`);\n if (this.chromedriver.jwproxy.downstreamProtocol === PROTOCOLS.MJSONWP) {\n const {x, y} = await this.chromedriver.jwproxy.command(`/element/${elementId}/location`, 'GET');\n const {width, height} = await this.chromedriver.jwproxy.command(`/element/${elementId}/size`, 'GET');\n return {x, y, width, height};\n }\n return await this.chromedriver.jwproxy.command(`/element/${elementId}/rect`, 'GET');\n }\n return await this.uiautomator2.jwproxy.command(`/element/${elementId}/rect`, 'GET');\n};\n\nObject.assign(extensions, commands, helpers);\nexport { commands, helpers };\nexport default extensions;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find.js","names":["helpers","MAGIC_FIRST_VIS_CHILD_SEL","MAGIC_SCROLLABLE_SEL","MAGIC_SCROLLABLE_BY","doFindElementOrEls","params","strategy","test","selector","elementId","context","uiautomator2","jwproxy","command","CssConverter","opts","appPackage","toUiAutomatorSelector","multiple"],"sources":["../../../lib/commands/find.js"],"sourcesContent":["import CssConverter from '../css-converter';\n\nconst helpers = {};\n\n// we override the xpath search for this first-visible-child selector, which\n// looks like /*[@firstVisible=\"true\"]\nconst MAGIC_FIRST_VIS_CHILD_SEL = /\\/\\*\\[@firstVisible ?= ?('|\")true\\1\\]/;\n\nconst MAGIC_SCROLLABLE_SEL = /\\/\\/\\*\\[@scrollable ?= ?('|\")true\\1\\]/;\nconst MAGIC_SCROLLABLE_BY = 'new UiSelector().scrollable(true)';\n\n/**\n * Overriding helpers.doFindElementOrEls functionality of appium-android-driver,\n * this.element initialized in find.js of appium-android-drive.\n */\nhelpers.doFindElementOrEls = async function (params) {\n if (params.strategy === 'xpath' && MAGIC_FIRST_VIS_CHILD_SEL.test(params.selector)) {\n let elementId = params.context;\n return await this.uiautomator2.jwproxy.command(`/appium/element/${elementId}/first_visible`, 'GET', {});\n }\n if (params.strategy === 'xpath' && MAGIC_SCROLLABLE_SEL.test(params.selector)) {\n params.strategy = '-android uiautomator';\n params.selector = MAGIC_SCROLLABLE_BY;\n }\n if (params.strategy === 'css selector') {\n params.strategy = '-android uiautomator';\n params.selector = new CssConverter(params.selector, this.opts.appPackage)\n .toUiAutomatorSelector();\n }\n return await this.uiautomator2.jwproxy.command(`/element${params.multiple ? 's' : ''}`, 'POST', params);\n};\n\nexport { helpers };\nexport default helpers;\n"],"mappings":";;;;;;;;;;;AAAA;;AAEA,MAAMA,OAAO,GAAG,EAAhB;;AAIA,MAAMC,yBAAyB,GAAG,uCAAlC;AAEA,MAAMC,oBAAoB,GAAG,uCAA7B;AACA,MAAMC,mBAAmB,GAAG,mCAA5B;;AAMAH,OAAO,CAACI,kBAAR,GAA6B,gBAAgBC,MAAhB,EAAwB;EACnD,IAAIA,MAAM,CAACC,QAAP,KAAoB,OAApB,IAA+BL,yBAAyB,CAACM,IAA1B,CAA+BF,MAAM,CAACG,QAAtC,CAAnC,EAAoF;IAClF,IAAIC,SAAS,GAAGJ,MAAM,CAACK,OAAvB;IACA,OAAO,MAAM,KAAKC,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAmC,mBAAkBJ,SAAU,gBAA/D,EAAgF,KAAhF,EAAuF,EAAvF,CAAb;EACD;;EACD,IAAIJ,MAAM,CAACC,QAAP,KAAoB,OAApB,IAA+BJ,oBAAoB,CAACK,IAArB,CAA0BF,MAAM,CAACG,QAAjC,CAAnC,EAA+E;IAC7EH,MAAM,CAACC,QAAP,GAAkB,sBAAlB;IACAD,MAAM,CAACG,QAAP,GAAkBL,mBAAlB;EACD;;EACD,IAAIE,MAAM,CAACC,QAAP,KAAoB,cAAxB,EAAwC;IACtCD,MAAM,CAACC,QAAP,GAAkB,sBAAlB;IACAD,MAAM,CAACG,QAAP,GAAkB,IAAIM,qBAAJ,CAAiBT,MAAM,CAACG,QAAxB,EAAkC,KAAKO,IAAL,CAAUC,UAA5C,EACfC,qBADe,EAAlB;EAED;;EACD,OAAO,MAAM,KAAKN,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAmC,WAAUR,MAAM,CAACa,QAAP,GAAkB,GAAlB,GAAwB,EAAG,EAAxE,EAA2E,MAA3E,EAAmFb,MAAnF,CAAb;AACD,CAfD;;eAkBeL,O"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"general.js","names":["extensions","commands","helpers","getPageSource","uiautomator2","jwproxy","command","getClipboard","adb","getApiLevel","doSendKeys","params","keyevent","keycode","metastate","log","debug","back","getStrings","language","getDeviceLanguage","info","preprocessStringsMap","mapping","result","key","value","_","toPairs","isString","JSON","stringify","apkStrings","opts","app","appPackage","errorAndThrow","tmpRoot","tempDir","openDir","pullApk","err","message","fs","exists","extractStringsFromApk","rimraf","getDisplayDensity","getWindowSize","getWindowRect","width","height","x","y","executeMobile","mobileCommand","mobileCommandsMapping","shell","execEmuConsoleCommand","dragGesture","flingGesture","doubleClickGesture","clickGesture","longClickGesture","pinchCloseGesture","pinchOpenGesture","swipeGesture","scrollGesture","scrollBackTo","scroll","viewportScreenshot","viewportRect","deepLink","startLogsBroadcast","stopLogsBroadcast","acceptAlert","dismissAlert","batteryInfo","deviceInfo","getDeviceTime","changePermissions","getPermissions","performEditorAction","startScreenStreaming","stopScreenStreaming","getNotifications","listSms","type","sensorSet","pushFile","pullFile","pullFolder","deleteFile","isAppInstalled","queryAppState","activateApp","removeApp","terminateApp","installApp","clearApp","startActivity","startService","stopService","broadcast","getContexts","installMultipleApks","unlock","refreshGpsCache","startMediaProjectionRecording","isMediaProjectionRecordingRunning","stopMediaProjectionRecording","has","errors","UnknownCommandError","keys","mobileViewportScreenshot","getViewportScreenshot","mobileViewPortRect","getViewPortRect","setUrl","url","startUri","mobileDeepLink","package","pkg","waitForLaunch","openNotifications","updateSettings","settings","update","getSettings","driverSettings","serverSettings","wrapBootstrapDisconnect","wrapped","suspendChromedriverProxy","chromedriver","proxyReqRes","bind","proxyCommand","jwpProxyActive","mobileGetDeviceInfo","mobileType","text","isUndefined","typeUnicode","mobileInstallMultipleApks","isArray","apks","isEmpty","InvalidArgumentError","B","all","map","configureApp","APK_EXTENSION","options","Object","assign"],"sources":["../../../lib/commands/general.js"],"sourcesContent":["import _ from 'lodash';\nimport B from 'bluebird';\nimport { errors } from 'appium/driver';\nimport { fs, tempDir } from 'appium/support';\nimport { APK_EXTENSION } from '../extensions';\n\nlet extensions = {},\n commands = {},\n helpers = {};\n\ncommands.getPageSource = async function () {\n return await this.uiautomator2.jwproxy.command('/source', 'GET', {});\n};\n\ncommands.getClipboard = async function () {\n return (await this.adb.getApiLevel() < 29)\n ? (await this.uiautomator2.jwproxy.command('/appium/device/get_clipboard', 'POST', {}))\n : (await this.adb.getClipboard());\n};\n\n// Need to override this for correct unicode support\ncommands.doSendKeys = async function (params) {\n await this.uiautomator2.jwproxy.command('/keys', 'POST', params);\n};\n\n// uiautomator2 doesn't support metastate for keyevents\ncommands.keyevent = async function (keycode, metastate) {\n this.log.debug(`Ignoring metastate ${metastate}`);\n await this.adb.keyevent(keycode);\n};\n\n// Use ADB since we don't have UiAutomator\ncommands.back = async function () {\n await this.adb.keyevent(4);\n};\n\ncommands.getStrings = async function (language) {\n if (!language) {\n language = await this.adb.getDeviceLanguage();\n this.log.info(`No language specified, returning strings for: ${language}`);\n }\n\n // Clients require the resulting mapping to have both keys\n // and values of type string\n const preprocessStringsMap = function (mapping) {\n const result = {};\n for (const [key, value] of _.toPairs(mapping)) {\n result[key] = _.isString(value) ? value : JSON.stringify(value);\n }\n return result;\n };\n\n if (this.apkStrings[language]) {\n // Return cached strings\n return preprocessStringsMap(this.apkStrings[language]);\n }\n\n if (!this.opts.app && !this.opts.appPackage) {\n this.log.errorAndThrow(\"One of 'app' or 'appPackage' capabilities should must be specified\");\n }\n\n let app = this.opts.app;\n const tmpRoot = await tempDir.openDir();\n try {\n if (!app) {\n try {\n app = await this.adb.pullApk(this.opts.appPackage, tmpRoot);\n } catch (err) {\n this.log.errorAndThrow(`Failed to pull an apk from '${this.opts.appPackage}'. Original error: ${err.message}`);\n }\n }\n\n if (!await fs.exists(app)) {\n this.log.errorAndThrow(`The app at '${app}' does not exist`);\n }\n\n try {\n const {apkStrings} = await this.adb.extractStringsFromApk(app, language, tmpRoot);\n this.apkStrings[language] = apkStrings;\n return preprocessStringsMap(apkStrings);\n } catch (err) {\n this.log.errorAndThrow(`Cannot extract strings from '${app}'. Original error: ${err.message}`);\n }\n } finally {\n await fs.rimraf(tmpRoot);\n }\n};\n\ncommands.getDisplayDensity = async function getDisplayDensity () {\n return await this.uiautomator2.jwproxy.command('/appium/device/display_density', 'GET', {});\n};\n\n// memoized in constructor\ncommands.getWindowSize = async function () {\n return await this.uiautomator2.jwproxy.command('/window/current/size', 'GET', {});\n};\n\n// For W3C\ncommands.getWindowRect = async function () {\n const {width, height} = await this.getWindowSize();\n return {\n width,\n height,\n x: 0,\n y: 0,\n };\n};\n\nextensions.executeMobile = async function (mobileCommand, opts = {}) {\n const mobileCommandsMapping = {\n shell: 'mobileShell',\n\n execEmuConsoleCommand: 'mobileExecEmuConsoleCommand',\n\n dragGesture: 'mobileDragGesture',\n flingGesture: 'mobileFlingGesture',\n doubleClickGesture: 'mobileDoubleClickGesture',\n clickGesture: 'mobileClickGesture',\n longClickGesture: 'mobileLongClickGesture',\n pinchCloseGesture: 'mobilePinchCloseGesture',\n pinchOpenGesture: 'mobilePinchOpenGesture',\n swipeGesture: 'mobileSwipeGesture',\n scrollGesture: 'mobileScrollGesture',\n scrollBackTo: 'mobileScrollBackTo',\n scroll: 'mobileScroll',\n viewportScreenshot: 'mobileViewportScreenshot',\n viewportRect: 'mobileViewPortRect',\n\n deepLink: 'mobileDeepLink',\n\n startLogsBroadcast: 'mobileStartLogsBroadcast',\n stopLogsBroadcast: 'mobileStopLogsBroadcast',\n\n acceptAlert: 'mobileAcceptAlert',\n dismissAlert: 'mobileDismissAlert',\n\n batteryInfo: 'mobileGetBatteryInfo',\n\n deviceInfo: 'mobileGetDeviceInfo',\n\n getDeviceTime: 'mobileGetDeviceTime',\n\n changePermissions: 'mobileChangePermissions',\n getPermissions: 'mobileGetPermissions',\n\n performEditorAction: 'mobilePerformEditorAction',\n\n startScreenStreaming: 'mobileStartScreenStreaming',\n stopScreenStreaming: 'mobileStopScreenStreaming',\n\n getNotifications: 'mobileGetNotifications',\n\n listSms: 'mobileListSms',\n\n type: 'mobileType',\n sensorSet: 'sensorSet',\n\n pushFile: 'mobilePushFile',\n pullFile: 'mobilePullFile',\n pullFolder: 'mobilePullFolder',\n deleteFile: 'mobileDeleteFile',\n\n isAppInstalled: 'mobileIsAppInstalled',\n queryAppState: 'mobileQueryAppState',\n activateApp: 'mobileActivateApp',\n removeApp: 'mobileRemoveApp',\n terminateApp: 'mobileTerminateApp',\n installApp: 'mobileInstallApp',\n clearApp: 'mobileClearApp',\n\n startActivity: 'mobileStartActivity',\n startService: 'mobileStartService',\n stopService: 'mobileStopService',\n broadcast: 'mobileBroadcast',\n\n getContexts: 'mobileGetContexts',\n\n installMultipleApks: 'mobileInstallMultipleApks',\n\n unlock: 'mobileUnlock',\n\n refreshGpsCache: 'mobileRefreshGpsCache',\n\n startMediaProjectionRecording: 'mobileStartMediaProjectionRecording',\n isMediaProjectionRecordingRunning: 'mobileIsMediaProjectionRecordingRunning',\n stopMediaProjectionRecording: 'mobileStopMediaProjectionRecording',\n };\n\n if (!_.has(mobileCommandsMapping, mobileCommand)) {\n throw new errors.UnknownCommandError(`Unknown mobile command \"${mobileCommand}\". ` +\n `Only ${_.keys(mobileCommandsMapping)} commands are supported.`);\n }\n return await this[mobileCommandsMapping[mobileCommand]](opts);\n};\n\ncommands.mobileViewportScreenshot = async function () {\n return await this.getViewportScreenshot();\n};\n\n/**\n * @typedef {object} Rectangle\n * @property {number} left - The left coordinate of the Rectangle.\n * @property {number} top - The top coordinate of the Rectangle.\n * @property {number} width - The width of Rectangle.\n * @property {number} height - The height of Rectangle.\n */\n\n/**\n * Returns the viewport coordinates.\n * @returns {Rectangle} The viewport coordinates.\n */\ncommands.mobileViewPortRect = async function mobileViewPortRect () {\n return await this.getViewPortRect();\n};\n\ncommands.setUrl = async function (url) {\n await this.adb.startUri(url, this.opts.appPackage);\n};\n\n/**\n * @typedef {object} DeepLinkOpts\n * @property {!string} url - The name of URL to start.\n * @property {!string} package - The name of the package to start the URI with.\n * @property {?boolean} waitForLaunch [true] - if `false` then adb won't wait\n * for the started activity to return the control\n */\n\n/**\n * Start URL that take users directly to specific content in the app\n * @param {DeepLinkOpts} opts\n */\ncommands.mobileDeepLink = async function (opts = {}) {\n const {\n url,\n package: pkg,\n waitForLaunch,\n } = opts;\n return await this.adb.startUri(url, pkg, { waitForLaunch });\n};\n\ncommands.openNotifications = async function () {\n return await this.uiautomator2.jwproxy.command('/appium/device/open_notifications', 'POST', {});\n};\n\ncommands.updateSettings = async function (settings) {\n await this.settings.update(settings);\n await this.uiautomator2.jwproxy.command('/appium/settings', 'POST', {settings});\n};\n\ncommands.getSettings = async function () {\n const driverSettings = this.settings.getSettings();\n const serverSettings = await this.uiautomator2.jwproxy.command('/appium/settings', 'GET');\n return {...driverSettings, ...serverSettings};\n};\n\n/**\n * Overriding appium-android-driver's wrapBootstrapDisconnect,\n * unlike in appium-android-driver avoiding adb restarting as it intern\n * kills UiAutomator2 server running in the device.\n **/\nhelpers.wrapBootstrapDisconnect = async function (wrapped) {\n await wrapped();\n};\n\n// Stop proxying to any Chromedriver and redirect to uiautomator2\nhelpers.suspendChromedriverProxy = function () {\n this.chromedriver = null;\n this.proxyReqRes = this.uiautomator2.proxyReqRes.bind(this.uiautomator2);\n this.proxyCommand = this.uiautomator2.proxyCommand.bind(this.uiautomator2);\n this.jwpProxyActive = true;\n};\n\n/**\n * The list of available info entries can be found at\n * https://github.com/appium/appium-uiautomator2-server/blob/master/app/src/main/java/io/appium/uiautomator2/handler/GetDeviceInfo.java\n */\ncommands.mobileGetDeviceInfo = async function () {\n return await this.uiautomator2.jwproxy.command('/appium/device/info', 'GET');\n};\n\n/**\n * @typedef {Object} TypingOptions\n * @property {!string|number|boolean} text - The text to type\n */\n\n/**\n * Types the given Unicode string.\n * It is expected that the focus is already put\n * to the destination input field before this method is called.\n *\n * @param {TypingOptions} opts\n * @returns {boolean} `true` if the input text has been successfully sent to adb\n * @throws {Error} if `text` property has not been provided\n */\ncommands.mobileType = async function mobileType (opts = {}) {\n const {\n text,\n } = opts;\n if (_.isUndefined(text)) {\n this.log.errorAndThrow(`The 'text' argument is mandatory`);\n }\n return await this.adb.typeUnicode(text);\n};\n\n\n/**\n * @typedef {Object} InstallOptions\n * @property {boolean} allowTestPackages [false] - Set to true in order to allow test\n * packages installation.\n * @property {boolean} useSdcard [false] - Set to true to install the app on sdcard\n * instead of the device memory.\n * @property {boolean} grantPermissions [false] - Set to true in order to grant all the\n * permissions requested in the application's manifest\n * automatically after the installation is completed\n * under Android 6+.\n * @property {boolean} replace [true] - Set it to false if you don't want\n * the application to be upgraded/reinstalled\n * if it is already present on the device.\n * @property {boolean} partialInstall [false] - Install apks partially. It is used for 'install-multiple'.\n * https://android.stackexchange.com/questions/111064/what-is-a-partial-application-install-via-adb\n */\n\n/**\n * @typedef {Object} InstallMultipleApksOptions\n * @property {Array<string>} apks - The list of APKs to install. Each APK should be a path to a apk\n * or downloadable URL as HTTP/HTTPS.\n * @property {InstallOptions} options\n */\n\n/**\n * Install multiple APKs with `install-multiple` option.\n *\n * @param {InstallMultipleApksOptions} opts\n * @throws {Error} if an error occured while installing the given APKs.\n */\ncommands.mobileInstallMultipleApks = async function (opts = {}) {\n if (!_.isArray(opts.apks) || _.isEmpty(opts.apks)) {\n throw new errors.InvalidArgumentError('No apks are given to install');\n }\n const apks = await B.all(opts.apks\n .map((app) => this.helpers.configureApp(app, [APK_EXTENSION])));\n await this.adb.installMultipleApks(apks, opts.options);\n};\n\nObject.assign(extensions, commands, helpers);\n\nexport default extensions;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gestures.js","names":["commands","toOrigin","element","util","wrapElement","unwrapElement","undefined","toPoint","x","y","_","isFinite","toRect","left","top","width","height","some","v","mobileClickGesture","opts","elementId","uiautomator2","jwproxy","command","origin","offset","mobileLongClickGesture","duration","mobileDoubleClickGesture","mobileDragGesture","startX","startY","endX","endY","speed","start","end","mobileFlingGesture","direction","area","mobilePinchCloseGesture","percent","mobilePinchOpenGesture","mobileSwipeGesture","mobileScrollGesture","mobileScrollBackTo","elementToId","errors","InvalidArgumentError","mobileScroll","strategy","selector","maxSwipes","params"],"sources":["../../../lib/commands/gestures.js"],"sourcesContent":["import { util } from 'appium/support';\nimport _ from 'lodash';\nimport { errors } from 'appium/driver';\n\nconst commands = {};\n\n\nfunction toOrigin (element) {\n return element ? util.wrapElement(util.unwrapElement(element)) : undefined;\n}\n\nfunction toPoint (x, y) {\n return _.isFinite(x) && _.isFinite(y) ? {x, y} : undefined;\n}\n\nfunction toRect (left, top, width, height) {\n return [left, top, width, height].some((v) => !_.isFinite(v))\n ? undefined\n : {left, top, width, height};\n}\n\n/**\n * @typedef {Object} ClickOptions\n * @property {?string} elementId - The id of the element to be clicked.\n * If the element is missing then both click offset coordinates must be provided.\n * If both the element id and offset are provided then the coordinates\n * are parsed as relative offsets from the top left corner of the element.\n * @property {?number} x - The x coordinate to click on\n * @property {?number} y - The y coordinate to click on\n */\n\n/**\n * Performs a simple click/tap gesture\n *\n * @param {?ClickOptions} opts\n * @throws {Error} if provided options are not valid\n */\ncommands.mobileClickGesture = async function mobileClickGesture (opts = {}) {\n const {\n elementId,\n x, y,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/click', 'POST', {\n origin: toOrigin(elementId),\n offset: toPoint(x, y),\n });\n};\n\n/**\n * @typedef {Object} LongClickOptions\n * @property {?string} elementId - The id of the element to be clicked.\n * If the element is missing then both click offset coordinates must be provided.\n * If both the element id and offset are provided then the coordinates\n * are parsed as relative offsets from the top left corner of the element.\n * @property {?number} x - The x coordinate to click on\n * @property {?number} y - The y coordinate to click on\n * @property {?number} duration [500] - Click duration in milliseconds.\n * The value must not be negative\n */\n\n/**\n * Performs a click that lasts for the given duration\n *\n * @param {?LongClickOptions} opts\n * @throws {Error} if provided options are not valid\n */\ncommands.mobileLongClickGesture = async function mobileLongClickGesture (opts = {}) {\n const {\n elementId,\n x, y,\n duration,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/long_click', 'POST', {\n origin: toOrigin(elementId),\n offset: toPoint(x, y),\n duration,\n });\n};\n\n/**\n * @typedef {Object} DoubleClickOptions\n * @property {?string} elementId - The id of the element to be double clicked.\n * If the element is missing then both click offset coordinates must be provided.\n * If both the element id and offset are provided then the coordinates\n * are parsed as relative offsets from the top left corner of the element.\n * @property {?number} x - The x coordinate to double click on\n * @property {?number} y - The y coordinate to double click on\n */\n\n/**\n * Performs a click that lasts for the given duration\n *\n * @param {?DoubleClickOptions} opts\n * @throws {Error} if provided options are not valid\n */\ncommands.mobileDoubleClickGesture = async function mobileDoubleClickGesture (opts = {}) {\n const {\n elementId,\n x, y,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/double_click', 'POST', {\n origin: toOrigin(elementId),\n offset: toPoint(x, y),\n });\n};\n\n/**\n * @typedef {Object} DragOptions\n * @property {?string} elementId - The id of the element to be dragged.\n * If the element id is missing then the start coordinates must be provided.\n * If both the element id and the start coordinates are provided then these\n * coordinates are considered as offsets from the top left element corner.\n * @property {?number} startX - The x coordinate where the dragging starts\n * @property {?number} startY - The y coordinate where the dragging starts\n * @property {!number} endX - The x coordinate where the dragging ends\n * @property {!number} endY - The y coordinate where the dragging ends\n * @property {?number} speed [2500 * displayDensity] - The speed at which to perform\n * this gesture in pixels per second. The value must not be negative\n */\n\n/**\n * Drags this object to the specified location.\n *\n * @param {?DragOptions} opts\n * @throws {Error} if provided options are not valid\n */\ncommands.mobileDragGesture = async function mobileDragGesture (opts = {}) {\n const {\n elementId,\n startX, startY,\n endX, endY,\n speed,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/drag', 'POST', {\n origin: toOrigin(elementId),\n start: toPoint(startX, startY),\n end: toPoint(endX, endY),\n speed,\n });\n};\n\n/**\n * @typedef {Object} FlingOptions\n * @property {?string} elementId - The id of the element to be flinged.\n * If the element id is missing then fling bounding area must be provided.\n * If both the element id and the fling bounding area are provided then this\n * area is effectively ignored.\n * @property {?number} left - The left coordinate of the fling bounding area\n * @property {?number} top - The top coordinate of the fling bounding area\n * @property {?number} width - The width of the fling bounding area\n * @property {?number} height - The height of the fling bounding area\n * @property {!string} direction - Direction of the fling.\n * Acceptable values are: `up`, `down`, `left` and `right` (case insensitive)\n * @property {?number} speed [7500 * displayDensity] - The speed at which to perform this\n * gesture in pixels per second. The value must be greater than the minimum fling\n * velocity for the given view (50 by default)\n */\n\n/**\n * Drags to the specified location.\n *\n * @param {?FlingOptions} opts\n * @throws {Error} if provided options are not valid\n * @returns {boolean} True if the object can still scroll in the given direction.\n */\ncommands.mobileFlingGesture = async function mobileFlingGesture (opts = {}) {\n const {\n elementId,\n left, top, width, height,\n direction,\n speed,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/fling', 'POST', {\n origin: toOrigin(elementId),\n area: toRect(left, top, width, height),\n direction,\n speed,\n });\n};\n\n/**\n * @typedef {Object} PinchOptions\n * @property {?string} elementId - The id of the element to be pinched.\n * If the element id is missing then pinch bounding area must be provided.\n * If both the element id and the pinch bounding area are provided then the\n * area is effectively ignored.\n * @property {?number} left - The left coordinate of the pinch bounding area\n * @property {?number} top - The top coordinate of the pinch bounding area\n * @property {?number} width - The width of the pinch bounding area\n * @property {?number} height - The height of the pinch bounding area\n * @property {!number} percent - The size of the pinch as a percentage of the pinch area size.\n * Valid values must be float numbers in range 0..1, where 1.0 is 100%\n * @property {?number} speed [2500 * displayDensity] - The speed at which to perform\n * this gesture in pixels per second. The value must not be negative\n */\n\n/**\n * Performs a pinch close gesture.\n *\n * @param {?PinchOptions} opts\n * @throws {Error} if provided options are not valid\n */\ncommands.mobilePinchCloseGesture = async function mobilePinchCloseGesture (opts = {}) {\n const {\n elementId,\n left, top, width, height,\n percent,\n speed,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/pinch_close', 'POST', {\n origin: toOrigin(elementId),\n area: toRect(left, top, width, height),\n percent,\n speed,\n });\n};\n\n/**\n * Performs a pinch open gesture.\n *\n * @param {?PinchOptions} opts\n * @throws {Error} if provided options are not valid\n */\ncommands.mobilePinchOpenGesture = async function mobilePinchOpenGesture (opts = {}) {\n const {\n elementId,\n left, top, width, height,\n percent,\n speed,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/pinch_open', 'POST', {\n origin: toOrigin(elementId),\n area: toRect(left, top, width, height),\n percent,\n speed,\n });\n};\n\n/**\n * @typedef {Object} SwipeOptions\n * @property {?string} elementId - The id of the element to be swiped.\n * If the element id is missing then swipe bounding area must be provided.\n * If both the element id and the swipe bounding area are provided then the\n * area is effectively ignored.\n * @property {?number} left - The left coordinate of the swipe bounding area\n * @property {?number} top - The top coordinate of the swipe bounding area\n * @property {?number} width - The width of the swipe bounding area\n * @property {?number} height - The height of the swipe bounding area\n * @property {!string} direction - Direction of the swipe.\n * Acceptable values are: `up`, `down`, `left` and `right` (case insensitive)\n * @property {!number} percent - The size of the swipe as a percentage of the swipe area size.\n * Valid values must be float numbers in range 0..1, where 1.0 is 100%\n * @property {?number} speed [5000 * displayDensity] - The speed at which to perform this\n * gesture in pixels per second. The value must not be negative\n */\n\n/**\n * Performs a swipe gesture.\n *\n * @param {?SwipeOptions} opts\n * @throws {Error} if provided options are not valid\n */\ncommands.mobileSwipeGesture = async function mobileSwipeGesture (opts = {}) {\n const {\n elementId,\n left, top, width, height,\n direction,\n percent,\n speed,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/swipe', 'POST', {\n origin: toOrigin(elementId),\n area: toRect(left, top, width, height),\n direction,\n percent,\n speed,\n });\n};\n\n/**\n * @typedef {Object} ScrollOptions\n * @property {?string} elementId - The id of the element to be scrolled.\n * If the element id is missing then scroll bounding area must be provided.\n * If both the element id and the scroll bounding area are provided then this\n * area is effectively ignored.\n * @property {?number} left - The left coordinate of the scroll bounding area\n * @property {?number} top - The top coordinate of the scroll bounding area\n * @property {?number} width - The width of the scroll bounding area\n * @property {?number} height - The height of the scroll bounding area\n * @property {!string} direction - Direction of the scroll.\n * Acceptable values are: `up`, `down`, `left` and `right` (case insensitive)\n * @property {!number} percent - The size of the scroll as a percentage of the scrolling area size.\n * Valid values must be float numbers greater than zero, where 1.0 is 100%\n * @property {?number} speed [5000 * displayDensity] - The speed at which to perform this gesture\n * in pixels per second. The value must not be negative\n */\n\n/**\n * Performs a scroll gesture.\n *\n * @param {?ScrollOptions} opts\n * @throws {Error} if provided options are not valid\n * @returns {boolean} True if the object can still scroll in the given direction.\n */\ncommands.mobileScrollGesture = async function mobileScrollGesture (opts = {}) {\n const {\n elementId,\n left, top, width, height,\n direction,\n percent,\n speed,\n } = opts;\n return await this.uiautomator2.jwproxy.command('/appium/gestures/scroll', 'POST', {\n origin: toOrigin(elementId),\n area: toRect(left, top, width, height),\n direction,\n percent,\n speed,\n });\n};\n\n/**\n * @typedef {Object} ScrollElementToElementOpts\n * @property {string} elementId The identifier of the scrollable element,\n * which is going to be scrolled. It is required this element\n * is a valid scrollable container and it was located by `-android uiautomator`\n * strategy.\n * @property {string} elementToId The identifier of the item, which belongs\n * to the scrollable element above, and which should become visible after\n * the scrolling operation is finished. It is required this element\n * was located by `-android uiautomator` strategy.\n */\n\n/**\n * Scrolls the given scrollable element `elementId` until `elementToId`\n * becomes visible. This function returns immediately if the `elementToId`\n * is already visible in the view port. Otherwise it would scroll\n * to the very beginning of the scrollable control and tries to reach the destination element\n * by scrolling its parent to the end step by step. The scroll direction (vertical or horizontal)\n * is detected automatically.\n *\n * @param {ScrollElementToElementOpts} opts\n * @throws {Error} if the scrolling operation cannot be performed\n */\ncommands.mobileScrollBackTo = async function (opts = {}) {\n const {elementId, elementToId} = opts;\n if (!elementId || !elementToId) {\n throw new errors.InvalidArgumentError(`Both elementId and elementToId arguments must be provided`);\n }\n return await this.uiautomator2.jwproxy.command(\n `/appium/element/${util.unwrapElement(elementId)}/scroll_to/${util.unwrapElement(elementToId)}`, 'POST', {});\n};\n\n/**\n * @typedef {Object} ScrollOpts\n * @property {?string} elementId The identifier of an element. It is required this element\n * is a valid scrollable container and it was located by `-android uiautomator`\n * strategy. If this property is not provided then the first currently available scrollable view\n * is selected for the interaction.\n * @property {!string} strategy The following strategies are supported:\n * - `accessibility id` (UiSelector().description)\n * - `class name` (UiSelector().className)\n * - `-android uiautomator` (UiSelector)\n * @property {!string} selector The corresponding lookup value for the given\n * strategy.\n * @property {?number} maxSwipes The maximum number of swipes to perform\n * on the target scrollable view in order to reach the destination element.\n * In case this value is unset then it would be retrieved from the scrollable\n * element itself (vua `getMaxSearchSwipes()` property).\n */\n\n/**\n * Scrolls the given scrollable element until the element identified\n * by `strategy` and `selector` becomes visible. This function returns immediately if the\n * destination element is already visible in the view port. Otherwise it would scroll\n * to the very beginning of the scrollable control and tries to reach the destination element\n * by scrolling its parent to the end step by step. The scroll direction (vertical or horizontal)\n * is detected automatically.\n *\n * @param {ScrollOpts} opts\n * @throws {Error} if the scrolling operation cannot be performed\n */\ncommands.mobileScroll = async function (opts = {}) {\n const {\n element, elementId, // `element` is deprecated, use `elementId` instead\n strategy, selector, maxSwipes\n } = opts;\n if (!strategy || !selector) {\n throw new errors.InvalidArgumentError(`Both strategy and selector arguments must be provided`);\n }\n return await this.uiautomator2.jwproxy.command('/touch/scroll', 'POST', {\n origin: toOrigin(elementId || element),\n params: {strategy, selector, maxSwipes},\n });\n};\n\nexport default commands;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["commands","Object","assign","alertCmds","findCmds","generalCmds","touchCmds","actionsCmds","elementCmds","viewportCmds","screenshotCmds","batteryCmds","gesturesCmds"],"sources":["../../../lib/commands/index.js"],"sourcesContent":["import alertCmds from './alert';\nimport findCmds from './find';\nimport generalCmds from './general';\nimport touchCmds from './touch';\nimport elementCmds from './element';\nimport actionsCmds from './actions';\nimport viewportCmds from './viewport';\nimport screenshotCmds from './screenshot';\nimport batteryCmds from './battery';\nimport gesturesCmds from './gestures';\n\nlet commands = {};\nObject.assign(\n commands,\n alertCmds,\n findCmds,\n generalCmds,\n touchCmds,\n actionsCmds,\n elementCmds,\n viewportCmds,\n screenshotCmds,\n batteryCmds,\n gesturesCmds,\n // add other command types here\n);\n\nexport default commands;\n\n"],"mappings":";;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAEA,IAAIA,QAAQ,GAAG,EAAf;AACAC,MAAM,CAACC,MAAP,CACEF,QADF,EAEEG,cAFF,EAGEC,aAHF,EAIEC,gBAJF,EAKEC,cALF,EAMEC,gBANF,EAOEC,gBAPF,EAQEC,iBARF,EASEC,mBATF,EAUEC,gBAVF,EAWEC,iBAXF;eAeeZ,Q"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.js","names":["commands","getScreenshot","mjpegStream","data","lastChunkPNGBase64","log","warn","uiautomator2","jwproxy","command"],"sources":["../../../lib/commands/screenshot.js"],"sourcesContent":["const commands = {};\n\ncommands.getScreenshot = async function () {\n if (this.mjpegStream) {\n const data = await this.mjpegStream.lastChunkPNGBase64();\n if (data) {\n return data;\n }\n this.log.warn('Tried to get screenshot from active MJPEG stream, but there ' +\n 'was no data yet. Falling back to regular screenshot methods.');\n }\n return await this.uiautomator2.jwproxy.command('/screenshot', 'GET');\n};\n\nexport default commands;\n"],"mappings":";;;;;;;;;AAAA,MAAMA,QAAQ,GAAG,EAAjB;;AAEAA,QAAQ,CAACC,aAAT,GAAyB,kBAAkB;EACzC,IAAI,KAAKC,WAAT,EAAsB;IACpB,MAAMC,IAAI,GAAG,MAAM,KAAKD,WAAL,CAAiBE,kBAAjB,EAAnB;;IACA,IAAID,IAAJ,EAAU;MACR,OAAOA,IAAP;IACD;;IACD,KAAKE,GAAL,CAASC,IAAT,CAAc,iEACZ,8DADF;EAED;;EACD,OAAO,MAAM,KAAKC,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,aAAlC,EAAiD,KAAjD,CAAb;AACD,CAVD;;eAYeT,Q"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"touch.js","names":["commands","extensions","doPerformMultiAction","elementId","states","opts","actions","uiautomator2","jwproxy","command","performActions","log","debug","JSON","stringify","preprocessedActions","map","action","Object","assign","type","parameters","pointerType"],"sources":["../../../lib/commands/touch.js"],"sourcesContent":["let commands = {}, extensions = {};\n\ncommands.doPerformMultiAction = async function (elementId, states) {\n let opts;\n if (elementId) {\n opts = {\n elementId,\n actions: states\n };\n\n return await this.uiautomator2.jwproxy.command('/touch/multi/perform', 'POST', opts);\n } else {\n opts = {\n actions: states\n };\n return await this.uiautomator2.jwproxy.command('/touch/multi/perform', 'POST', opts);\n }\n};\n\ncommands.performActions = async function (actions) {\n this.log.debug(`Received the following W3C actions: ${JSON.stringify(actions, null, ' ')}`);\n // This is mandatory, since Selenium API uses MOUSE as the default pointer type\n const preprocessedActions = actions\n .map((action) => Object.assign({}, action, action.type === 'pointer' ? {\n parameters: {\n pointerType: 'touch'\n }\n } : {}));\n this.log.debug(`Preprocessed actions: ${JSON.stringify(preprocessedActions, null, ' ')}`);\n return await this.uiautomator2.jwproxy.command('/actions', 'POST', {actions: preprocessedActions});\n};\n\nObject.assign(extensions, commands);\nexport default extensions;\n"],"mappings":";;;;;;;;;AAAA,IAAIA,QAAQ,GAAG,EAAf;AAAA,IAAmBC,UAAU,GAAG,EAAhC;;AAEAD,QAAQ,CAACE,oBAAT,GAAgC,gBAAgBC,SAAhB,EAA2BC,MAA3B,EAAmC;EACjE,IAAIC,IAAJ;;EACA,IAAIF,SAAJ,EAAe;IACbE,IAAI,GAAG;MACLF,SADK;MAELG,OAAO,EAAEF;IAFJ,CAAP;IAKA,OAAO,MAAM,KAAKG,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,sBAAlC,EAA0D,MAA1D,EAAkEJ,IAAlE,CAAb;EACD,CAPD,MAOO;IACLA,IAAI,GAAG;MACLC,OAAO,EAAEF;IADJ,CAAP;IAGA,OAAO,MAAM,KAAKG,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,sBAAlC,EAA0D,MAA1D,EAAkEJ,IAAlE,CAAb;EACD;AACF,CAfD;;AAiBAL,QAAQ,CAACU,cAAT,GAA0B,gBAAgBJ,OAAhB,EAAyB;EACjD,KAAKK,GAAL,CAASC,KAAT,CAAgB,uCAAsCC,IAAI,CAACC,SAAL,CAAeR,OAAf,EAAwB,IAAxB,EAA8B,IAA9B,CAAoC,EAA1F;EAEA,MAAMS,mBAAmB,GAAGT,OAAO,CAChCU,GADyB,CACpBC,MAAD,IAAYC,MAAM,CAACC,MAAP,CAAc,EAAd,EAAkBF,MAAlB,EAA0BA,MAAM,CAACG,IAAP,KAAgB,SAAhB,GAA4B;IACrEC,UAAU,EAAE;MACVC,WAAW,EAAE;IADH;EADyD,CAA5B,GAIvC,EAJa,CADS,CAA5B;EAMA,KAAKX,GAAL,CAASC,KAAT,CAAgB,yBAAwBC,IAAI,CAACC,SAAL,CAAeC,mBAAf,EAAoC,IAApC,EAA0C,IAA1C,CAAgD,EAAxF;EACA,OAAO,MAAM,KAAKR,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,UAAlC,EAA8C,MAA9C,EAAsD;IAACH,OAAO,EAAES;EAAV,CAAtD,CAAb;AACD,CAXD;;AAaAG,MAAM,CAACC,MAAP,CAAclB,UAAd,EAA0BD,QAA1B;eACeC,U"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewport.js","names":["extensions","commands","getStatusBarHeight","statusBar","uiautomator2","jwproxy","command","getDevicePixelRatio","getViewportScreenshot","screenshot","getScreenshot","rect","getViewPortRect","imageUtil","cropBase64Image","windowSize","getWindowSize","statusBarHeight","left","top","width","height","Object","assign"],"sources":["../../../lib/commands/viewport.js"],"sourcesContent":["import { imageUtil } from 'appium/support';\n\n\nlet extensions = {}, commands = {};\n\n// memoized in constructor\ncommands.getStatusBarHeight = async function () {\n const {statusBar} = await this.uiautomator2.jwproxy.command(`/appium/device/system_bars`, 'GET', {});\n return statusBar;\n};\n\n// memoized in constructor\ncommands.getDevicePixelRatio = async function () {\n return await this.uiautomator2.jwproxy.command('/appium/device/pixel_ratio', 'GET', {});\n};\n\ncommands.getViewportScreenshot = async function () {\n const screenshot = await this.getScreenshot();\n const rect = await this.getViewPortRect();\n return await imageUtil.cropBase64Image(screenshot, rect);\n};\n\ncommands.getViewPortRect = async function () {\n const windowSize = await this.getWindowSize();\n const statusBarHeight = await this.getStatusBarHeight();\n // android returns the upscaled window size, so to get the true size of the\n // rect we have to downscale\n return {\n left: 0,\n top: statusBarHeight,\n width: windowSize.width,\n height: windowSize.height - statusBarHeight\n };\n};\n\nObject.assign(extensions, commands);\nexport { commands };\nexport default extensions;\n"],"mappings":";;;;;;;;;AAAA;;AAGA,IAAIA,UAAU,GAAG,EAAjB;AAAA,IAAqBC,QAAQ,GAAG,EAAhC;;;AAGAA,QAAQ,CAACC,kBAAT,GAA8B,kBAAkB;EAC9C,MAAM;IAACC;EAAD,IAAc,MAAM,KAAKC,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAmC,4BAAnC,EAAgE,KAAhE,EAAuE,EAAvE,CAA1B;EACA,OAAOH,SAAP;AACD,CAHD;;AAMAF,QAAQ,CAACM,mBAAT,GAA+B,kBAAkB;EAC/C,OAAO,MAAM,KAAKH,YAAL,CAAkBC,OAAlB,CAA0BC,OAA1B,CAAkC,4BAAlC,EAAgE,KAAhE,EAAuE,EAAvE,CAAb;AACD,CAFD;;AAIAL,QAAQ,CAACO,qBAAT,GAAiC,kBAAkB;EACjD,MAAMC,UAAU,GAAG,MAAM,KAAKC,aAAL,EAAzB;EACA,MAAMC,IAAI,GAAG,MAAM,KAAKC,eAAL,EAAnB;EACA,OAAO,MAAMC,kBAAA,CAAUC,eAAV,CAA0BL,UAA1B,EAAsCE,IAAtC,CAAb;AACD,CAJD;;AAMAV,QAAQ,CAACW,eAAT,GAA2B,kBAAkB;EAC3C,MAAMG,UAAU,GAAG,MAAM,KAAKC,aAAL,EAAzB;EACA,MAAMC,eAAe,GAAG,MAAM,KAAKf,kBAAL,EAA9B;EAGA,OAAO;IACLgB,IAAI,EAAE,CADD;IAELC,GAAG,EAAEF,eAFA;IAGLG,KAAK,EAAEL,UAAU,CAACK,KAHb;IAILC,MAAM,EAAEN,UAAU,CAACM,MAAX,GAAoBJ;EAJvB,CAAP;AAMD,CAXD;;AAaAK,MAAM,CAACC,MAAP,CAAcvB,UAAd,EAA0BC,QAA1B;eAEeD,U"}
|