appium-uiautomator2-driver 6.6.1 → 6.6.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/README.md +14 -9
- package/build/lib/commands/screenshot.d.ts +17 -14
- package/build/lib/commands/screenshot.d.ts.map +1 -1
- package/build/lib/commands/screenshot.js +50 -36
- package/build/lib/commands/screenshot.js.map +1 -1
- package/build/lib/constraints.d.ts +3 -0
- package/build/lib/constraints.d.ts.map +1 -1
- package/build/test/unit/commands/general-specs.d.ts +2 -0
- package/build/test/unit/commands/general-specs.d.ts.map +1 -0
- package/build/test/unit/commands/general-specs.js +80 -0
- package/build/test/unit/commands/general-specs.js.map +1 -0
- package/build/test/unit/commands/screenshot-specs.d.ts +2 -0
- package/build/test/unit/commands/screenshot-specs.d.ts.map +1 -0
- package/build/test/unit/commands/screenshot-specs.js +124 -0
- package/build/test/unit/commands/screenshot-specs.js.map +1 -0
- package/build/test/unit/css-converter-specs.d.ts +2 -0
- package/build/test/unit/css-converter-specs.d.ts.map +1 -0
- package/build/test/unit/css-converter-specs.js +68 -0
- package/build/test/unit/css-converter-specs.js.map +1 -0
- package/build/test/unit/driver-specs.d.ts +2 -0
- package/build/test/unit/driver-specs.d.ts.map +1 -0
- package/build/test/unit/driver-specs.js +328 -0
- package/build/test/unit/driver-specs.js.map +1 -0
- package/build/test/unit/uiautomator2-specs.d.ts +2 -0
- package/build/test/unit/uiautomator2-specs.d.ts.map +1 -0
- package/build/test/unit/uiautomator2-specs.js +320 -0
- package/build/test/unit/uiautomator2-specs.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/lib/commands/screenshot.ts +146 -0
- package/npm-shrinkwrap.json +252 -387
- package/package.json +2 -3
- package/lib/commands/screenshot.js +0 -116
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [6.6.3](https://github.com/appium/appium-uiautomator2-driver/compare/v6.6.2...v6.6.3) (2025-12-08)
|
|
2
|
+
|
|
3
|
+
### Miscellaneous Chores
|
|
4
|
+
|
|
5
|
+
* Ditch usage of @appium/test-support ([#954](https://github.com/appium/appium-uiautomator2-driver/issues/954)) ([9351cfc](https://github.com/appium/appium-uiautomator2-driver/commit/9351cfc9ef911155634abc06d28b497e182657c2))
|
|
6
|
+
|
|
7
|
+
## [6.6.2](https://github.com/appium/appium-uiautomator2-driver/compare/v6.6.1...v6.6.2) (2025-12-03)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Update mobile: screenshots endpoint to properly handle virtual display ids ([#951](https://github.com/appium/appium-uiautomator2-driver/issues/951)) ([5e96d51](https://github.com/appium/appium-uiautomator2-driver/commit/5e96d518372c332b108d28f96a0303ac6f97a1e9))
|
|
12
|
+
|
|
1
13
|
## [6.6.1](https://github.com/appium/appium-uiautomator2-driver/compare/v6.6.0...v6.6.1) (2025-12-02)
|
|
2
14
|
|
|
3
15
|
### Miscellaneous Chores
|
package/README.md
CHANGED
|
@@ -258,6 +258,8 @@ className | This strategy is mapped to the native UiAutomator's `By.clazz` [loca
|
|
|
258
258
|
-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\"))
|
|
259
259
|
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\"]")
|
|
260
260
|
|
|
261
|
+
> [!NOTE] For testing multi-window applications, see the [Multi-Window Testing Guide](docs/android-multiwindow.md).
|
|
262
|
+
|
|
261
263
|
> [!WARNING]
|
|
262
264
|
> Google is going to [deprecate](https://developer.android.com/training/testing/other-components/ui-automator#ui-automator)
|
|
263
265
|
> and remove `UiCollection`, `UiObject`, `UiScrollable`, and `UiSelector` support from the UiAutomator framework.
|
|
@@ -306,8 +308,8 @@ actionAcknowledgmentTimeout | long | Maximum number of milliseconds to wait for
|
|
|
306
308
|
allowInvisibleElements | boolean | Whether to include elements that are not visible to the user (e. g. whose `displayed` attribute is `false`) to the XML source tree. `false` by default
|
|
307
309
|
ignoreUnimportantViews | boolean | Enables or disables layout hierarchy compression. If compression is enabled, the layout hierarchy derived from the Acessibility framework will only contain nodes that are important for uiautomator testing. Any unnecessary surrounding layout nodes that make viewing and searching the hierarchy inefficient are removed. `false` by default
|
|
308
310
|
elementResponseAttributes | string | Comma-separated list of element attribute names to be included into findElement response. By default only element UUID is present there, but it is also possible to add the following items: `name`, `text`, `rect`, `enabled`, `displayed`, `selected`, `attribute/<element_attribute_name>`. It is required that `shouldUseCompactResponses` setting is set to `false` in order for this one to apply.
|
|
309
|
-
enableMultiWindows | boolean | Whether to include all windows that the user can interact with (for example an on-screen keyboard) while building the XML page source (`true`). By default it is `false` and only the single active application window is included to the page source.
|
|
310
|
-
enableTopmostWindowFromActivePackage | boolean | Whether to limit the window with the highest Z-order from the active package for interactions and page source retrieval. By default it is `false` and the active application window, which may not necessarily have this order, is included to the page source.
|
|
311
|
+
enableMultiWindows | boolean | Whether to include all windows that the user can interact with (for example an on-screen keyboard) while building the XML page source (`true`). By default it is `false` and only the single active application window is included to the page source. See the [Multi-Window Testing Guide](docs/android-multiwindow.md) for detailed information.
|
|
312
|
+
enableTopmostWindowFromActivePackage | boolean | Whether to limit the window with the highest Z-order from the active package for interactions and page source retrieval. By default it is `false` and the active application window, which may not necessarily have this order, is included to the page source. See the [Multi-Window Testing Guide](docs/android-multiwindow.md) for detailed information.
|
|
311
313
|
enableNotificationListener | boolean | Whether to enable (`true`) toast notifications listener to listen for new toast notifications. By default this listener is enabled and UiAutomator2 server includes the text of toast messages to the generated XML page source, but not for longer than `3500` ms after the corresponding notification expires.
|
|
312
314
|
keyInjectionDelay | long | Delay in milliseconds between key presses when injecting text input. 0 ms by default
|
|
313
315
|
scrollAcknowledgmentTimeout | long | Timeout for waiting for an acknowledgement of an uiautomator scroll swipe action. The acknowledgment is an [AccessibilityEvent](http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html), corresponding to the scroll action, that lets the framework determine if the scroll action was successful. Generally, this timeout should not be modified. `200` ms by default
|
|
@@ -332,7 +334,8 @@ disableIdLocatorAutocompletion | boolean | According to internal Android standar
|
|
|
332
334
|
includeExtrasInPageSource | boolean | Whether to include `extras` element attribute in the XML page source result. Then, XPath locator can find the element by the extras. Its value consists of combined [getExtras](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getExtras()) as `keys=value` pair separated by a semicolon (`;`), thus you may need to find the element with partial matching like `contains` e.g. `driver.find_element :xpath, '//*[contains(@extras, "AccessibilityNodeInfo.roleDescription=")]'`. The value could be huge if elements in the XML page source have large `extras`. It could affect the performance of XML page source generation.
|
|
333
335
|
includeA11yActionsInPageSource | boolean | Whether to include `actions` element attribute in the XML page source result. Its value consists of names of available accessibility actions from [getActionList](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getActionList()), separated by a comma. The value could be huge if elements in the XML page source have a lot of actions and could affect the performance of XML page source generation.
|
|
334
336
|
snapshotMaxDepth | int | The number of maximum depth for the source tree snapshot. The default value is `70`. This number should be in range [1, 500]. A part of the elements source tree might be lost if the value is too low. Also, StackOverflowError might be caused if the value is too high (Issues [12545](https://github.com/appium/appium/issues/12545), [12892](https://github.com/appium/appium/issues/12892)). The available driver version is `2.27.0` or higher.
|
|
335
|
-
currentDisplayId | int | The id of the display that should be used when finding elements, taking screenshots, etc. It can be found in the output of `adb shell dumpsys display` (search for `mDisplayId`). The default value is [Display.DEFAULT_DISPLAY](https://developer.android.com/reference/android/view/Display#DEFAULT_DISPLAY).
|
|
337
|
+
currentDisplayId | int | The id of the display that should be used when finding elements, taking screenshots, etc. It can be found in the output of `adb shell dumpsys display` (search for `mDisplayId`). The default value is [Display.DEFAULT_DISPLAY](https://developer.android.com/reference/android/view/Display#DEFAULT_DISPLAY). See the [Multi-Window Testing Guide](docs/android-multiwindow.md) for detailed information about windows, displays, and how this setting affects element location. Set this setting to `-1`
|
|
338
|
+
in order to reset it.
|
|
336
339
|
alwaysTraversableViewClasses | string | Allows to continue the tree traversal for user defined classes even though the node itself is invisible. The default logic for the UI tree traversal (controlled by the `allowInvisibleElements` setting) is to stop recursing when an invisible node is found. However, with certain Jetpack Compose classes (e.g. androidx.compose.ui.viewinterop.ViewFactoryHolder), it is possible that invisible parent nodes have visible child nodes. See [Google issue \#354958193](https://issuetracker.google.com/issues/354958193) and [UIA2 server issue \#709](https://github.com/appium/appium-uiautomator2-server/issues/709) for more details. This setting only affects the XPath lookup and the page source buildup. You can provide a comma separated list of glob patterns, that will be used as an exemption list: `androidx.compose.ui.viewinterop.*,android.widget.ImageButton`.
|
|
337
340
|
|
|
338
341
|
|
|
@@ -1667,21 +1670,23 @@ These extensions allow to deal with short-living UI elements. Read [the document
|
|
|
1667
1670
|
Retrieves a screenshot of each display available to Android.
|
|
1668
1671
|
This functionality is only supported since Android 10.
|
|
1669
1672
|
|
|
1670
|
-
**Important:** This method uses **physical display IDs**, which are different from logical display IDs used by the `currentDisplayId` setting.
|
|
1671
|
-
- The `physicalId` field returned by [`mobile: listDisplays`](#mobile-listdisplays) (recommended)
|
|
1672
|
-
- The `physicalDisplayId` field returned by [`mobile: listWindows`](#mobile-listwindows)
|
|
1673
|
+
**Important:** This method uses **physical or virtual display IDs**, which are different from logical display IDs used by the `currentDisplayId` setting. Display IDs can be obtained from:
|
|
1674
|
+
- The `physicalId` or `virtualId` field returned by [`mobile: listDisplays`](#mobile-listdisplays) (recommended)
|
|
1675
|
+
- The `physicalDisplayId` or `virtualDisplayId` field returned by [`mobile: listWindows`](#mobile-listwindows)
|
|
1673
1676
|
- The `adb shell dumpsys SurfaceFlinger --display-id` command output
|
|
1674
1677
|
|
|
1678
|
+
**Note:** For physical displays, use the `physicalId` from `mobile: listDisplays` or `physicalDisplayId` from `mobile: listWindows`. For virtual displays, use the `virtualId` from `mobile: listDisplays` or `virtualDisplayId` from `mobile: listWindows`.
|
|
1679
|
+
|
|
1675
1680
|
#### Arguments
|
|
1676
1681
|
|
|
1677
1682
|
Name | Type | Required | Description | Example
|
|
1678
1683
|
--- | --- | --- | --- | ---
|
|
1679
|
-
displayId | number or string | no | **Physical display identifier** to take a screenshot for. If not provided then screenshots of all displays are going to be returned. If no matches were found then an error is thrown. **Note:** This is a physical display ID, not a logical display ID. Use `mobile: listDisplays` to get the correct `physicalId` value. | 1234567890
|
|
1684
|
+
displayId | number or string | no | **Physical or virtual display identifier** to take a screenshot for. If not provided then screenshots of all displays are going to be returned. If no matches were found then an error is thrown. **Note:** This is a physical or virtual display ID, not a logical display ID. Use `mobile: listDisplays` to get the correct `physicalId` (for physical displays) or `virtualId` (for virtual displays) value. | 1234567890
|
|
1680
1685
|
|
|
1681
1686
|
#### Returns
|
|
1682
1687
|
|
|
1683
|
-
A dictionary where each key is the physical display identifier (as a string) and the value has the following keys:
|
|
1684
|
-
- `id`: The physical display identifier (same as the key)
|
|
1688
|
+
A dictionary where each key is the physical or virtual display identifier (as a string) and the value has the following keys:
|
|
1689
|
+
- `id`: The physical or virtual display identifier (same as the key)
|
|
1685
1690
|
- `name`: Display name
|
|
1686
1691
|
- `isDefault`: Whether this display is the default one
|
|
1687
1692
|
- `payload`: The actual PNG screenshot data encoded to base64 string
|
|
@@ -1,27 +1,30 @@
|
|
|
1
|
+
import type { AndroidUiautomator2Driver } from '../driver';
|
|
2
|
+
import type { Screenshot } from './types';
|
|
3
|
+
import type { StringRecord } from '@appium/types';
|
|
1
4
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @
|
|
5
|
+
* Parses SurfaceFlinger display output to extract display information.
|
|
6
|
+
* @param displaysInfo - The raw output from `adb shell dumpsys SurfaceFlinger --display-id`
|
|
7
|
+
* @returns A record mapping display IDs to their information (without payload)
|
|
4
8
|
*/
|
|
5
|
-
export function
|
|
9
|
+
export declare function parseSurfaceFlingerDisplays(displaysInfo: string): Record<string, Partial<Screenshot>>;
|
|
6
10
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @returns {Promise<string>}
|
|
11
|
+
* Takes a screenshot of the current viewport
|
|
9
12
|
*/
|
|
10
|
-
export function
|
|
13
|
+
export declare function mobileViewportScreenshot(this: AndroidUiautomator2Driver): Promise<string>;
|
|
11
14
|
/**
|
|
12
|
-
*
|
|
13
|
-
* @returns {Promise<string>}
|
|
15
|
+
* Gets a screenshot of the current viewport
|
|
14
16
|
*/
|
|
15
|
-
export function
|
|
17
|
+
export declare function getViewportScreenshot(this: AndroidUiautomator2Driver): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Gets a screenshot of the current screen
|
|
20
|
+
*/
|
|
21
|
+
export declare function getScreenshot(this: AndroidUiautomator2Driver): Promise<string>;
|
|
16
22
|
/**
|
|
17
23
|
* Retrieves screenshots of each display available to Android.
|
|
18
24
|
* This functionality is only supported since Android 10.
|
|
19
|
-
* @
|
|
20
|
-
* @param {number | string} [displayId] Android display identifier to take a screenshot for.
|
|
25
|
+
* @param displayId - Android display identifier to take a screenshot for.
|
|
21
26
|
* If not provided then screenshots of all displays are going to be returned.
|
|
22
27
|
* If no matches were found then an error is thrown.
|
|
23
|
-
* @returns {Promise<import('@appium/types').StringRecord<import('./types').Screenshot>>}
|
|
24
28
|
*/
|
|
25
|
-
export function mobileScreenshots(this:
|
|
26
|
-
export type AndroidUiautomator2Driver = import("../driver").AndroidUiautomator2Driver;
|
|
29
|
+
export declare function mobileScreenshots(this: AndroidUiautomator2Driver, displayId?: number | string): Promise<StringRecord<Screenshot>>;
|
|
27
30
|
//# sourceMappingURL=screenshot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../lib/commands/screenshot.
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../lib/commands/screenshot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAOhD;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,MAAM,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CA4BrC;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,yBAAyB,EAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAC1B,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CA4CnC"}
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseSurfaceFlingerDisplays = parseSurfaceFlingerDisplays;
|
|
6
7
|
exports.mobileViewportScreenshot = mobileViewportScreenshot;
|
|
7
8
|
exports.getViewportScreenshot = getViewportScreenshot;
|
|
8
9
|
exports.getScreenshot = getScreenshot;
|
|
@@ -10,18 +11,46 @@ exports.mobileScreenshots = mobileScreenshots;
|
|
|
10
11
|
const lodash_1 = __importDefault(require("lodash"));
|
|
11
12
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
12
13
|
const support_1 = require("appium/support");
|
|
13
|
-
//
|
|
14
|
-
|
|
14
|
+
// Matches SurfaceFlinger output format:
|
|
15
|
+
// Physical: Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="EMU_display_0"
|
|
16
|
+
// Virtual: Display 11529215049243506835 (Virtual display): displayName="Emulator 2D Display" uniqueId="..."
|
|
17
|
+
const DISPLAY_PATTERN = /^Display\s+(\d+)\s+\((?:HWC\s+display\s+(\d+)|Virtual\s+display)\):.*?displayName="([^"]*)"/gm;
|
|
15
18
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
19
|
+
* Parses SurfaceFlinger display output to extract display information.
|
|
20
|
+
* @param displaysInfo - The raw output from `adb shell dumpsys SurfaceFlinger --display-id`
|
|
21
|
+
* @returns A record mapping display IDs to their information (without payload)
|
|
22
|
+
*/
|
|
23
|
+
function parseSurfaceFlingerDisplays(displaysInfo) {
|
|
24
|
+
const infos = {};
|
|
25
|
+
const lines = displaysInfo.split('\n');
|
|
26
|
+
for (const line of lines) {
|
|
27
|
+
let match;
|
|
28
|
+
// Try to match display header line
|
|
29
|
+
if ((match = DISPLAY_PATTERN.exec(line))) {
|
|
30
|
+
const [, matchedDisplayId, hwcId, displayName] = match; // Skip match[0] (full match), then Display ID, HWC ID (optional), Display name
|
|
31
|
+
// Determine if default: HWC display 0 is default, or first physical display if no HWC info
|
|
32
|
+
const isDefault = hwcId !== undefined
|
|
33
|
+
? hwcId === '0'
|
|
34
|
+
: !line.includes('Virtual') && Object.keys(infos).length === 0;
|
|
35
|
+
infos[matchedDisplayId] = {
|
|
36
|
+
id: matchedDisplayId,
|
|
37
|
+
isDefault,
|
|
38
|
+
name: displayName || undefined,
|
|
39
|
+
};
|
|
40
|
+
// Reset regex lastIndex for next iteration
|
|
41
|
+
DISPLAY_PATTERN.lastIndex = 0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return infos;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Takes a screenshot of the current viewport
|
|
18
48
|
*/
|
|
19
49
|
async function mobileViewportScreenshot() {
|
|
20
50
|
return await this.getViewportScreenshot();
|
|
21
51
|
}
|
|
22
52
|
/**
|
|
23
|
-
*
|
|
24
|
-
* @returns {Promise<string>}
|
|
53
|
+
* Gets a screenshot of the current viewport
|
|
25
54
|
*/
|
|
26
55
|
async function getViewportScreenshot() {
|
|
27
56
|
const screenshot = await this.getScreenshot();
|
|
@@ -29,8 +58,7 @@ async function getViewportScreenshot() {
|
|
|
29
58
|
return await support_1.imageUtil.cropBase64Image(screenshot, rect);
|
|
30
59
|
}
|
|
31
60
|
/**
|
|
32
|
-
*
|
|
33
|
-
* @returns {Promise<string>}
|
|
61
|
+
* Gets a screenshot of the current screen
|
|
34
62
|
*/
|
|
35
63
|
async function getScreenshot() {
|
|
36
64
|
if (this.mjpegStream) {
|
|
@@ -41,44 +69,31 @@ async function getScreenshot() {
|
|
|
41
69
|
this.log.warn('Tried to get screenshot from active MJPEG stream, but there ' +
|
|
42
70
|
'was no data yet. Falling back to regular screenshot methods.');
|
|
43
71
|
}
|
|
44
|
-
return String(await
|
|
72
|
+
return String(await this.uiautomator2.jwproxy.command('/screenshot', 'GET'));
|
|
45
73
|
}
|
|
46
74
|
/**
|
|
47
75
|
* Retrieves screenshots of each display available to Android.
|
|
48
76
|
* This functionality is only supported since Android 10.
|
|
49
|
-
* @
|
|
50
|
-
* @param {number | string} [displayId] Android display identifier to take a screenshot for.
|
|
77
|
+
* @param displayId - Android display identifier to take a screenshot for.
|
|
51
78
|
* If not provided then screenshots of all displays are going to be returned.
|
|
52
79
|
* If no matches were found then an error is thrown.
|
|
53
|
-
* @returns {Promise<import('@appium/types').StringRecord<import('./types').Screenshot>>}
|
|
54
80
|
*/
|
|
55
81
|
async function mobileScreenshots(displayId) {
|
|
56
|
-
const displaysInfo = await
|
|
82
|
+
const displaysInfo = await this.adb.shell([
|
|
57
83
|
'dumpsys',
|
|
58
84
|
'SurfaceFlinger',
|
|
59
85
|
'--display-id',
|
|
60
86
|
]);
|
|
61
|
-
|
|
62
|
-
const infos = {};
|
|
63
|
-
let match;
|
|
64
|
-
while ((match = DISPLAY_PATTERN.exec(displaysInfo))) {
|
|
65
|
-
infos[match[1]] = /** @type {any} */ ({
|
|
66
|
-
id: match[1],
|
|
67
|
-
isDefault: match[2] === '0',
|
|
68
|
-
name: match[3],
|
|
69
|
-
});
|
|
70
|
-
}
|
|
87
|
+
const infos = parseSurfaceFlingerDisplays(displaysInfo);
|
|
71
88
|
if (lodash_1.default.isEmpty(infos)) {
|
|
72
89
|
this.log.debug(displaysInfo);
|
|
73
90
|
throw new Error('Cannot determine the information about connected Android displays');
|
|
74
91
|
}
|
|
75
92
|
this.log.info(`Parsed Android display infos: ${JSON.stringify(infos)}`);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// @ts-ignore isNaN works properly here
|
|
81
|
-
const displayIdStr = isNaN(displayId) ? null : `${displayId}`;
|
|
93
|
+
const toB64Screenshot = async (dispId) => (await this.adb.takeScreenshot(dispId)).toString('base64');
|
|
94
|
+
const displayIdStr = lodash_1.default.isNil(displayId) || displayId === ''
|
|
95
|
+
? null
|
|
96
|
+
: String(displayId);
|
|
82
97
|
if (displayIdStr) {
|
|
83
98
|
if (!infos[displayIdStr]) {
|
|
84
99
|
throw new Error(`The provided display identifier '${displayId}' is not known. ` +
|
|
@@ -91,14 +106,13 @@ async function mobileScreenshots(displayId) {
|
|
|
91
106
|
},
|
|
92
107
|
};
|
|
93
108
|
}
|
|
94
|
-
const allInfos = lodash_1.default.values(infos);
|
|
95
|
-
const screenshots = await bluebird_1.default.all(allInfos.map((
|
|
96
|
-
for (const [info, payload] of
|
|
97
|
-
info
|
|
109
|
+
const allInfos = lodash_1.default.values(infos).filter((info) => !!info?.id);
|
|
110
|
+
const screenshots = await bluebird_1.default.all(allInfos.map((info) => toB64Screenshot(info.id)));
|
|
111
|
+
for (const [info, payload] of lodash_1.default.zip(allInfos, screenshots)) {
|
|
112
|
+
if (info && payload) {
|
|
113
|
+
info.payload = payload;
|
|
114
|
+
}
|
|
98
115
|
}
|
|
99
116
|
return infos;
|
|
100
117
|
}
|
|
101
|
-
/**
|
|
102
|
-
* @typedef {import('../driver').AndroidUiautomator2Driver} AndroidUiautomator2Driver
|
|
103
|
-
*/
|
|
104
118
|
//# sourceMappingURL=screenshot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../lib/commands/screenshot.
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../lib/commands/screenshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -252,6 +252,9 @@ declare const UIAUTOMATOR2_CONSTRAINTS: {
|
|
|
252
252
|
readonly allowDelayAdb: {
|
|
253
253
|
readonly isBoolean: true;
|
|
254
254
|
};
|
|
255
|
+
readonly adbListenAllNetwork: {
|
|
256
|
+
readonly isBoolean: true;
|
|
257
|
+
};
|
|
255
258
|
readonly ignoreUnimportantViews: {
|
|
256
259
|
readonly isBoolean: true;
|
|
257
260
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constraints.d.ts","sourceRoot":"","sources":["../../lib/constraints.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,wBAAwB
|
|
1
|
+
{"version":3,"file":"constraints.d.ts","sourceRoot":"","sources":["../../lib/constraints.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCE,CAAC;AAEjC,eAAe,wBAAwB,CAAC;AAExC,MAAM,MAAM,uBAAuB,GAAG,OAAO,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"general-specs.d.ts","sourceRoot":"","sources":["../../../../test/unit/commands/general-specs.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const sinon_1 = __importDefault(require("sinon"));
|
|
7
|
+
const driver_1 = require("../../../lib/driver");
|
|
8
|
+
const appium_adb_1 = require("appium-adb");
|
|
9
|
+
const chai_1 = __importDefault(require("chai"));
|
|
10
|
+
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
|
|
11
|
+
const { expect } = chai_1.default;
|
|
12
|
+
chai_1.default.use(chai_as_promised_1.default);
|
|
13
|
+
describe('General', function () {
|
|
14
|
+
let driver;
|
|
15
|
+
let mockDriver;
|
|
16
|
+
beforeEach(function () {
|
|
17
|
+
driver = new driver_1.AndroidUiautomator2Driver();
|
|
18
|
+
mockDriver = sinon_1.default.mock(driver);
|
|
19
|
+
});
|
|
20
|
+
afterEach(function () {
|
|
21
|
+
mockDriver.verify();
|
|
22
|
+
});
|
|
23
|
+
describe('getWindowRect', function () {
|
|
24
|
+
it('should get window size', async function () {
|
|
25
|
+
mockDriver.expects('getWindowSize').once().returns({ width: 300, height: 400 });
|
|
26
|
+
const result = await driver.getWindowRect();
|
|
27
|
+
expect(result).to.eql({
|
|
28
|
+
width: 300,
|
|
29
|
+
height: 400,
|
|
30
|
+
x: 0,
|
|
31
|
+
y: 0,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('mobile command', function () {
|
|
36
|
+
it('should raise error on non-existent mobile command', async function () {
|
|
37
|
+
await expect(driver.execute('mobile: fruta', {})).to.be.rejectedWith(/Unsupported/);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe('mobile: sensorSet', function () {
|
|
41
|
+
// note: this test does not depend on whether or not isEmulator returns
|
|
42
|
+
// true, because the "am I an emulator?" check happens in the sensorSet
|
|
43
|
+
// implementation, which is stubbed out.
|
|
44
|
+
it('should call sensorSet', async function () {
|
|
45
|
+
mockDriver.expects('sensorSet').once().withArgs('acceleration', '0:9.77631:0.812349');
|
|
46
|
+
await driver.execute('mobile: sensorSet', {
|
|
47
|
+
sensorType: 'acceleration',
|
|
48
|
+
value: '0:9.77631:0.812349',
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe('mobile: installMultipleApks', function () {
|
|
53
|
+
let adb;
|
|
54
|
+
let mockHelpers;
|
|
55
|
+
let mockAdb;
|
|
56
|
+
beforeEach(function () {
|
|
57
|
+
adb = new appium_adb_1.ADB();
|
|
58
|
+
mockAdb = sinon_1.default.mock(adb);
|
|
59
|
+
driver = new driver_1.AndroidUiautomator2Driver();
|
|
60
|
+
driver.adb = adb;
|
|
61
|
+
mockHelpers = sinon_1.default.mock(driver.helpers);
|
|
62
|
+
mockHelpers.expects('configureApp').returns('/path/to/test/apk.apk');
|
|
63
|
+
});
|
|
64
|
+
afterEach(function () {
|
|
65
|
+
mockHelpers.restore();
|
|
66
|
+
mockAdb.verify();
|
|
67
|
+
});
|
|
68
|
+
it('should call mobileInstallMultipleApks', async function () {
|
|
69
|
+
mockAdb.expects('installMultipleApks').once().withExactArgs(['/path/to/test/apk.apk'], undefined);
|
|
70
|
+
await driver.execute('mobile: installMultipleApks', { apks: ['/path/to/test/apk.apk'] });
|
|
71
|
+
});
|
|
72
|
+
it('should reject if no apks were given', async function () {
|
|
73
|
+
await expect(driver.execute('mobile: installMultipleApks', { apks: [] })).to.be.rejectedWith('No apks are given to install');
|
|
74
|
+
});
|
|
75
|
+
it('should reject with default args', async function () {
|
|
76
|
+
await expect(driver.execute('mobile: installMultipleApks')).to.be.rejected;
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=general-specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"general-specs.js","sourceRoot":"","sources":["../../../../test/unit/commands/general-specs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot-specs.d.ts","sourceRoot":"","sources":["../../../../test/unit/commands/screenshot-specs.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-check
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const chai_1 = require("chai");
|
|
5
|
+
const screenshot_1 = require("../../../lib/commands/screenshot");
|
|
6
|
+
describe('Screenshot - parseSurfaceFlingerDisplays', function () {
|
|
7
|
+
describe('physical displays', function () {
|
|
8
|
+
it('should parse physical display with HWC display ID 0 (default)', function () {
|
|
9
|
+
const output = 'Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="EMU_display_0"';
|
|
10
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
11
|
+
(0, chai_1.expect)(result).to.have.property('4619827259835644672');
|
|
12
|
+
(0, chai_1.expect)(result['4619827259835644672']).to.deep.include({
|
|
13
|
+
id: '4619827259835644672',
|
|
14
|
+
isDefault: true,
|
|
15
|
+
name: 'EMU_display_0',
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
it('should parse physical display with non-default HWC display ID', function () {
|
|
19
|
+
const output = 'Display 4619827259835644672 (HWC display 1): port=0 pnpId=GGL displayName="External Display"';
|
|
20
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
21
|
+
(0, chai_1.expect)(result).to.have.property('4619827259835644672');
|
|
22
|
+
(0, chai_1.expect)(result['4619827259835644672']).to.deep.include({
|
|
23
|
+
id: '4619827259835644672',
|
|
24
|
+
isDefault: false,
|
|
25
|
+
name: 'External Display',
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
it('should parse physical display with HWC display ID 2', function () {
|
|
29
|
+
const output = 'Display 4619827259835644672 (HWC display 2): port=1 pnpId=HDMI displayName="HDMI Display"';
|
|
30
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
31
|
+
(0, chai_1.expect)(result).to.have.property('4619827259835644672');
|
|
32
|
+
(0, chai_1.expect)(result['4619827259835644672']).to.deep.include({
|
|
33
|
+
id: '4619827259835644672',
|
|
34
|
+
isDefault: false,
|
|
35
|
+
name: 'HDMI Display',
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('virtual displays', function () {
|
|
40
|
+
it('should parse virtual display with displayName', function () {
|
|
41
|
+
const output = 'Display 11529215049243506835 (Virtual display): displayName="Emulator 2D Display" uniqueId="virtual:com.android.emulator.multidisplay:1234562"';
|
|
42
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
43
|
+
(0, chai_1.expect)(result).to.have.property('11529215049243506835');
|
|
44
|
+
(0, chai_1.expect)(result['11529215049243506835']).to.deep.include({
|
|
45
|
+
id: '11529215049243506835',
|
|
46
|
+
isDefault: false, // Virtual displays are never default
|
|
47
|
+
name: 'Emulator 2D Display',
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
it('should parse virtual display with different uniqueId format', function () {
|
|
51
|
+
const output = 'Display 11529215049243506835 (Virtual display): displayName="Virtual Screen" uniqueId="virtual:test:789"';
|
|
52
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
53
|
+
(0, chai_1.expect)(result).to.have.property('11529215049243506835');
|
|
54
|
+
(0, chai_1.expect)(result['11529215049243506835']).to.deep.include({
|
|
55
|
+
id: '11529215049243506835',
|
|
56
|
+
isDefault: false,
|
|
57
|
+
name: 'Virtual Screen',
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('multiple displays', function () {
|
|
62
|
+
it('should parse multiple physical displays with correct default detection', function () {
|
|
63
|
+
const output = `Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="First Display"
|
|
64
|
+
Display 4619827259835644673 (HWC display 1): port=1 pnpId=HDMI displayName="Second Display"`;
|
|
65
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
66
|
+
(0, chai_1.expect)(result).to.have.property('4619827259835644672');
|
|
67
|
+
(0, chai_1.expect)(result).to.have.property('4619827259835644673');
|
|
68
|
+
(0, chai_1.expect)(result['4619827259835644672'].isDefault).to.be.true;
|
|
69
|
+
(0, chai_1.expect)(result['4619827259835644673'].isDefault).to.be.false;
|
|
70
|
+
});
|
|
71
|
+
it('should parse mixed physical and virtual displays', function () {
|
|
72
|
+
const output = `Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="Physical Display"
|
|
73
|
+
Display 11529215049243506835 (Virtual display): displayName="Emulator 2D Display" uniqueId="virtual:com.android.emulator.multidisplay:1234562"`;
|
|
74
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
75
|
+
(0, chai_1.expect)(result).to.have.property('4619827259835644672');
|
|
76
|
+
(0, chai_1.expect)(result).to.have.property('11529215049243506835');
|
|
77
|
+
(0, chai_1.expect)(result['4619827259835644672']).to.deep.include({
|
|
78
|
+
id: '4619827259835644672',
|
|
79
|
+
isDefault: true,
|
|
80
|
+
name: 'Physical Display',
|
|
81
|
+
});
|
|
82
|
+
(0, chai_1.expect)(result['11529215049243506835']).to.deep.include({
|
|
83
|
+
id: '11529215049243506835',
|
|
84
|
+
isDefault: false,
|
|
85
|
+
name: 'Emulator 2D Display',
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
it('should handle multiple virtual displays', function () {
|
|
89
|
+
const output = `Display 11529215049243506835 (Virtual display): displayName="Virtual 1" uniqueId="virtual:test:1"
|
|
90
|
+
Display 11529215049243506836 (Virtual display): displayName="Virtual 2" uniqueId="virtual:test:2"`;
|
|
91
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
92
|
+
(0, chai_1.expect)(result).to.have.property('11529215049243506835');
|
|
93
|
+
(0, chai_1.expect)(result).to.have.property('11529215049243506836');
|
|
94
|
+
(0, chai_1.expect)(result['11529215049243506835'].isDefault).to.be.false;
|
|
95
|
+
(0, chai_1.expect)(result['11529215049243506836'].isDefault).to.be.false;
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
describe('edge cases', function () {
|
|
99
|
+
it('should handle empty input', function () {
|
|
100
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)('');
|
|
101
|
+
(0, chai_1.expect)(result).to.be.empty;
|
|
102
|
+
});
|
|
103
|
+
it('should handle input with no displays', function () {
|
|
104
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)('Some other text\nMore text');
|
|
105
|
+
(0, chai_1.expect)(result).to.be.empty;
|
|
106
|
+
});
|
|
107
|
+
it('should handle displayName with special characters', function () {
|
|
108
|
+
const output = 'Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="Display with spaces & symbols!@#"';
|
|
109
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
110
|
+
(0, chai_1.expect)(result['4619827259835644672'].name).to.equal('Display with spaces & symbols!@#');
|
|
111
|
+
});
|
|
112
|
+
it('should handle displayName at different positions in the line', function () {
|
|
113
|
+
const output = 'Display 4619827259835644672 (HWC display 0): displayName="Early Name" port=0 pnpId=GGL';
|
|
114
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
115
|
+
(0, chai_1.expect)(result['4619827259835644672'].name).to.equal('Early Name');
|
|
116
|
+
});
|
|
117
|
+
it('should handle multiple properties after displayName', function () {
|
|
118
|
+
const output = 'Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="My Display" extraProp="value" anotherProp=123';
|
|
119
|
+
const result = (0, screenshot_1.parseSurfaceFlingerDisplays)(output);
|
|
120
|
+
(0, chai_1.expect)(result['4619827259835644672'].name).to.equal('My Display');
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=screenshot-specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot-specs.js","sourceRoot":"","sources":["../../../../test/unit/commands/screenshot-specs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-converter-specs.d.ts","sourceRoot":"","sources":["../../../test/unit/css-converter-specs.ts"],"names":[],"mappings":""}
|