appium-uiautomator2-driver 6.6.0 → 6.6.2
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 +6 -0
- 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/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 +325 -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 +12 -12
- package/package.json +3 -3
- package/lib/commands/screenshot.js +0 -116
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [6.6.2](https://github.com/appium/appium-uiautomator2-driver/compare/v6.6.1...v6.6.2) (2025-12-03)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* 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))
|
|
6
|
+
|
|
7
|
+
## [6.6.1](https://github.com/appium/appium-uiautomator2-driver/compare/v6.6.0...v6.6.1) (2025-12-02)
|
|
8
|
+
|
|
9
|
+
### Miscellaneous Chores
|
|
10
|
+
|
|
11
|
+
* Document new properties on list.. methods ([#950](https://github.com/appium/appium-uiautomator2-driver/issues/950)) ([1c74692](https://github.com/appium/appium-uiautomator2-driver/commit/1c7469240bd1be919bf017ea682806288eb7b526))
|
|
12
|
+
|
|
1
13
|
## [6.6.0](https://github.com/appium/appium-uiautomator2-driver/compare/v6.5.0...v6.6.0) (2025-12-01)
|
|
2
14
|
|
|
3
15
|
### Features
|
package/README.md
CHANGED
|
@@ -566,6 +566,7 @@ Name | Type | Description | Example
|
|
|
566
566
|
windowId | number \| null | Window identifier (may be null if the window ID cannot be determined) | 42
|
|
567
567
|
displayId | number | Display identifier where the window is located | 0
|
|
568
568
|
physicalDisplayId | string \| null | Physical display identifier (may be null). Returned as a string to avoid JavaScript number precision issues with large values. | '1234567890'
|
|
569
|
+
virtualDisplayId | string \| null | Virtual display identifier (may be null). Only set for virtual displays, null otherwise. Parsed from 'dumpsys SurfaceFlinger --displays' output by matching display name. | '12345'
|
|
569
570
|
rect | object | Window bounds rectangle with `left`, `top`, `right`, `bottom` properties | `{left: 0, top: 0, right: 1080, bottom: 1920}`
|
|
570
571
|
packageName | string \| null | Package name of the application that owns this window (may be null) | `com.example.app`
|
|
571
572
|
screenshot | string \| null | Base64-encoded PNG screenshot of the window (may be null). Only available on Android API 34+ and when `skipScreenshots` is `false`. | `iVBORw0KGgoAAAANSUhEUgAA...`
|
|
@@ -588,7 +589,9 @@ The extension returns an array of display information objects. Each object conta
|
|
|
588
589
|
Name | Type | Description | Example
|
|
589
590
|
--- | --- | --- | ---
|
|
590
591
|
id | number | Display identifier (logical display ID). This is the value used by the `currentDisplayId` setting. | 0
|
|
592
|
+
name | string \| null | Display name (may be null) | 'Built-in Screen'
|
|
591
593
|
physicalId | string \| null | Physical display identifier (may be null). Returned as a string to avoid JavaScript number precision issues with large values. This is the value used by the `mobile: screenshots` method. | '1234567890'
|
|
594
|
+
virtualId | string \| null | Virtual display identifier (may be null). Only set for virtual displays, null otherwise. Parsed from 'dumpsys SurfaceFlinger --displays' output by matching display name. | '12345'
|
|
592
595
|
metrics | object | Display metrics containing size and density information. See below for details. | See metrics table
|
|
593
596
|
isDefault | boolean | Whether this is the default display | true
|
|
594
597
|
|
|
@@ -613,7 +616,10 @@ displays = driver.execute_script('mobile: listDisplays')
|
|
|
613
616
|
|
|
614
617
|
for display in displays:
|
|
615
618
|
print(f"Display ID: {display['id']}")
|
|
619
|
+
print(f" Name: {display['name']}")
|
|
616
620
|
print(f" Physical ID: {display['physicalId']}")
|
|
621
|
+
if display.get('virtualId'):
|
|
622
|
+
print(f" Virtual ID: {display['virtualId']}")
|
|
617
623
|
print(f" Is default: {display['isDefault']}")
|
|
618
624
|
print(f" Size: {display['metrics']['widthPixels']}x{display['metrics']['heightPixels']}")
|
|
619
625
|
print(f" Density: {display['metrics']['density']} ({display['metrics']['densityDpi']} DPI)")
|
|
@@ -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":";;;;;AAiBA,kEA8BC;AAKD,4DAIC;AAKD,sDAMC;AAKD,sCAgBC;AASD,8CA+CC;AAhJD,oDAAuB;AACvB,wDAAyB;AACzB,4CAAyC;AAKzC,wCAAwC;AACxC,sGAAsG;AACtG,4GAA4G;AAC5G,MAAM,eAAe,GAAG,+FAA+F,CAAC;AAExH;;;;GAIG;AACH,SAAgB,2BAA2B,CACzC,YAAoB;IAEpB,MAAM,KAAK,GAAwC,EAAE,CAAC;IACtD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,KAA6B,CAAC;QAElC,mCAAmC;QACnC,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACzC,MAAM,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC,+EAA+E;YAEvI,2FAA2F;YAC3F,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS;gBACnC,CAAC,CAAC,KAAK,KAAK,GAAG;gBACf,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;YAEjE,KAAK,CAAC,gBAAgB,CAAC,GAAG;gBACxB,EAAE,EAAE,gBAAgB;gBACpB,SAAS;gBACT,IAAI,EAAE,WAAW,IAAI,SAAS;aAC/B,CAAC;YAEF,2CAA2C;YAC3C,eAAe,CAAC,SAAS,GAAG,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,wBAAwB;IAG5C,OAAO,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;AAC5C,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,qBAAqB;IAGzC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;IAC1C,OAAO,MAAM,mBAAS,CAAC,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,aAAa;IAGjC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC;QACzD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,8DAA8D;YAC5D,8DAA8D,CACjE,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CACX,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAC9D,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,iBAAiB,CAErC,SAA2B;IAE3B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;QACxC,SAAS;QACT,gBAAgB;QAChB,cAAc;KACf,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,2BAA2B,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,gBAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iCAAiC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAExE,MAAM,eAAe,GAAG,KAAK,EAAE,MAAc,EAAmB,EAAE,CAChE,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE7D,MAAM,YAAY,GAChB,gBAAC,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,EAAE;QACpC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAExB,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,oCAAoC,SAAS,kBAAkB;gBAC7D,mDAAmD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAC7E,CAAC;QACJ,CAAC;QACD,OAAO;YACL,CAAC,YAAY,CAAC,EAAE;gBACd,GAAG,KAAK,CAAC,YAAY,CAAC;gBACtB,OAAO,EAAE,MAAM,eAAe,CAAC,YAAY,CAAC;aAC/B;SAChB,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,gBAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAA8C,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC1G,MAAM,WAAW,GAAG,MAAM,kBAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAClF,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,gBAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAyC,EAAE,CAAC;QACnG,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,KAAiC,CAAC;AAC3C,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":";;;;;AAAA,kDAA0B;AAC1B,gDAA8D;AAC9D,2CAAiC;AACjC,gDAAwB;AACxB,wEAA8C;AAE9C,MAAM,EAAC,MAAM,EAAC,GAAG,cAAI,CAAC;AACtB,cAAI,CAAC,GAAG,CAAC,0BAAc,CAAC,CAAC;AAEzB,QAAQ,CAAC,SAAS,EAAE;IAClB,IAAI,MAAiC,CAAC;IACtC,IAAI,UAA2B,CAAC;IAEhC,UAAU,CAAC;QACT,MAAM,GAAG,IAAI,kCAAyB,EAAE,CAAC;QACzC,UAAU,GAAG,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC;QACR,UAAU,CAAC,MAAM,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE;QACxB,EAAE,CAAC,wBAAwB,EAAE,KAAK;YAChC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAC,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC;gBACpB,KAAK,EAAE,GAAG;gBACV,MAAM,EAAE,GAAG;gBACX,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,CAAC;aACL,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE;QACzB,EAAE,CAAC,mDAAmD,EAAE,KAAK;YAC3D,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAClE,aAAa,CACd,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE;QAC5B,uEAAuE;QACvE,uEAAuE;QACvE,wCAAwC;QACxC,EAAE,CAAC,uBAAuB,EAAE,KAAK;YAC/B,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,CAC7C,cAAc,EACd,oBAAoB,CACrB,CAAC;YACF,MAAM,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE;gBACxC,UAAU,EAAE,cAAc;gBAC1B,KAAK,EAAE,oBAAoB;aAC5B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6BAA6B,EAAE;QACtC,IAAI,GAAQ,CAAC;QACb,IAAI,WAA4B,CAAC;QACjC,IAAI,OAAwB,CAAC;QAE7B,UAAU,CAAC;YACT,GAAG,GAAG,IAAI,gBAAG,EAAE,CAAC;YAChB,OAAO,GAAG,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAE1B,MAAM,GAAG,IAAI,kCAAyB,EAAE,CAAC;YACzC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;YAEjB,WAAW,GAAG,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzC,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC;YACR,WAAW,CAAC,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK;YAC/C,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,CAAC,uBAAuB,CAAC,EAAE,SAAS,CAAC,CAAC;YAClG,MAAM,MAAM,CAAC,OAAO,CAAC,6BAA6B,EAAE,EAAC,IAAI,EAAE,CAAC,uBAAuB,CAAC,EAAC,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK;YAC7C,MAAM,MAAM,CACV,MAAM,CAAC,OAAO,CAAC,6BAA6B,EAAE,EAAC,IAAI,EAAE,EAAE,EAAC,CAAC,CAC1D,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,8BAA8B,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK;YACzC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;QAC7E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -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":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
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 css_converter_1 = __importDefault(require("../../lib/css-converter"));
|
|
7
|
+
const chai_1 = require("chai");
|
|
8
|
+
describe('css-converter.js', function () {
|
|
9
|
+
describe('simple cases', function () {
|
|
10
|
+
const simpleCases = [
|
|
11
|
+
['android.widget.TextView', 'new UiSelector().className("android.widget.TextView")'],
|
|
12
|
+
['TextView', 'new UiSelector().classNameMatches("TextView")'],
|
|
13
|
+
['.TextView', 'new UiSelector().classNameMatches("TextView")'],
|
|
14
|
+
['.widget.TextView', 'new UiSelector().classNameMatches("widget\\.TextView")'],
|
|
15
|
+
['*[checkable=true]', 'new UiSelector().checkable(true)'],
|
|
16
|
+
['*[checkable]', 'new UiSelector().checkable(true)'],
|
|
17
|
+
['*:checked', 'new UiSelector().checked(true)'],
|
|
18
|
+
['*[checked]', 'new UiSelector().checked(true)'],
|
|
19
|
+
['TextView[description="Some description"]', 'new UiSelector().classNameMatches("TextView").description("Some description")'],
|
|
20
|
+
['*[description]', 'new UiSelector().descriptionMatches("")'],
|
|
21
|
+
['*[description^=blah]', 'new UiSelector().descriptionStartsWith("blah")'],
|
|
22
|
+
['*[description$=bar]', 'new UiSelector().descriptionMatches("bar$")'],
|
|
23
|
+
['*[description*=bar]', 'new UiSelector().descriptionContains("bar")'],
|
|
24
|
+
['#identifier[description=foo]', 'new UiSelector().resourceId("android:id/identifier").description("foo")'],
|
|
25
|
+
['*[id=foo]', 'new UiSelector().resourceId("android:id/foo")'],
|
|
26
|
+
['*[description$="hello [ ^ $ . | ? * + ( ) world"]', 'new UiSelector().descriptionMatches("hello \\[ \\^ \\$ \\. \\| \\? \\* \\+ \\( \\) world$")'],
|
|
27
|
+
['TextView:iNdEx(4)', 'new UiSelector().classNameMatches("TextView").index(4)'],
|
|
28
|
+
['*:long-clickable', 'new UiSelector().longClickable(true)'],
|
|
29
|
+
['*[lOnG-cLiCkAbLe]', 'new UiSelector().longClickable(true)'],
|
|
30
|
+
['*:nth-child(3)', 'new UiSelector().index(3)'],
|
|
31
|
+
['*:instance(3)', 'new UiSelector().instance(3)'],
|
|
32
|
+
[
|
|
33
|
+
'android.widget.TextView[checkable] android.widget.WidgetView[focusable]:nth-child(1)',
|
|
34
|
+
'new UiSelector().className("android.widget.TextView").checkable(true).childSelector(new UiSelector().className("android.widget.WidgetView").focusable(true).index(1))'
|
|
35
|
+
],
|
|
36
|
+
['* *[clickable=true][focused]', 'new UiSelector().childSelector(new UiSelector().clickable(true).focused(true))'],
|
|
37
|
+
[
|
|
38
|
+
'*[clickable=true], *[clickable=false]',
|
|
39
|
+
'new UiSelector().clickable(true)',
|
|
40
|
+
],
|
|
41
|
+
['*[description~="word"]', 'new UiSelector().descriptionMatches("\\b(\\w*word\\w*)\\b")'],
|
|
42
|
+
[
|
|
43
|
+
'android.widget.ListView android.widget.TextView',
|
|
44
|
+
'new UiSelector().className("android.widget.ListView").childSelector(new UiSelector().className("android.widget.TextView"))'
|
|
45
|
+
],
|
|
46
|
+
];
|
|
47
|
+
for (const [cssSelector, uiAutomatorSelector] of simpleCases) {
|
|
48
|
+
it(`should convert '${cssSelector}' to '${uiAutomatorSelector}'`, function () {
|
|
49
|
+
(0, chai_1.expect)(new css_converter_1.default(cssSelector).toUiAutomatorSelector()).to.equal(uiAutomatorSelector);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
describe('unsupported css', function () {
|
|
54
|
+
const testCases = [
|
|
55
|
+
'*[checked="ItS ChEcKeD"]',
|
|
56
|
+
'*[foo="bar"]',
|
|
57
|
+
'*:checked("ischecked")',
|
|
58
|
+
`This isn't valid[ css`,
|
|
59
|
+
'p ~ a',
|
|
60
|
+
];
|
|
61
|
+
for (const cssSelector of testCases) {
|
|
62
|
+
it(`should reject '${cssSelector}'`, function () {
|
|
63
|
+
(0, chai_1.expect)(() => new css_converter_1.default(cssSelector).toUiAutomatorSelector()).to.throw();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=css-converter-specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-converter-specs.js","sourceRoot":"","sources":["../../../test/unit/css-converter-specs.ts"],"names":[],"mappings":";;;;;AAAA,4EAAmD;AACnD,+BAA4B;AAE5B,QAAQ,CAAC,kBAAkB,EAAE;IAC3B,QAAQ,CAAC,cAAc,EAAE;QACvB,MAAM,WAAW,GAA4B;YAC3C,CAAC,yBAAyB,EAAE,uDAAuD,CAAC;YACpF,CAAC,UAAU,EAAE,+CAA+C,CAAC;YAC7D,CAAC,WAAW,EAAE,+CAA+C,CAAC;YAC9D,CAAC,kBAAkB,EAAE,wDAAwD,CAAC;YAC9E,CAAC,mBAAmB,EAAE,kCAAkC,CAAC;YACzD,CAAC,cAAc,EAAE,kCAAkC,CAAC;YACpD,CAAC,WAAW,EAAE,gCAAgC,CAAC;YAC/C,CAAC,YAAY,EAAE,gCAAgC,CAAC;YAChD,CAAC,0CAA0C,EAAE,+EAA+E,CAAC;YAC7H,CAAC,gBAAgB,EAAE,yCAAyC,CAAC;YAC7D,CAAC,sBAAsB,EAAE,gDAAgD,CAAC;YAC1E,CAAC,qBAAqB,EAAE,6CAA6C,CAAC;YACtE,CAAC,qBAAqB,EAAE,6CAA6C,CAAC;YACtE,CAAC,8BAA8B,EAAE,yEAAyE,CAAC;YAC3G,CAAC,WAAW,EAAE,+CAA+C,CAAC;YAC9D,CAAC,mDAAmD,EAAE,6FAA6F,CAAC;YACpJ,CAAC,mBAAmB,EAAE,wDAAwD,CAAC;YAC/E,CAAC,kBAAkB,EAAE,sCAAsC,CAAC;YAC5D,CAAC,mBAAmB,EAAE,sCAAsC,CAAC;YAC7D,CAAC,gBAAgB,EAAE,2BAA2B,CAAC;YAC/C,CAAC,eAAe,EAAE,8BAA8B,CAAC;YACjD;gBACE,sFAAsF;gBACtF,uKAAuK;aACxK;YACD,CAAC,8BAA8B,EAAE,gFAAgF,CAAC;YAClH;gBACE,uCAAuC;gBACvC,kCAAkC;aACnC;YACD,CAAC,wBAAwB,EAAE,6DAA6D,CAAC;YACzF;gBACE,iDAAiD;gBACjD,4HAA4H;aAC7H;SACF,CAAC;QACF,KAAK,MAAM,CAAC,WAAW,EAAE,mBAAmB,CAAC,IAAI,WAAW,EAAE,CAAC;YAC7D,EAAE,CAAC,mBAAmB,WAAW,SAAS,mBAAmB,GAAG,EAAE;gBAChE,IAAA,aAAM,EAAC,IAAI,uBAAY,CAAC,WAAW,CAAC,CAAC,qBAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC9F,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,iBAAiB,EAAE;QAC1B,MAAM,SAAS,GAAa;YAC1B,0BAA0B;YAC1B,cAAc;YACd,wBAAwB;YACxB,uBAAuB;YACvB,OAAO;SACR,CAAC;QACF,KAAK,MAAM,WAAW,IAAI,SAAS,EAAE,CAAC;YACpC,EAAE,CAAC,kBAAkB,WAAW,GAAG,EAAE;gBACnC,IAAA,aAAM,EAAC,GAAG,EAAE,CAAC,IAAI,uBAAY,CAAC,WAAW,CAAC,CAAC,qBAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YACjF,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-specs.d.ts","sourceRoot":"","sources":["../../../test/unit/driver-specs.ts"],"names":[],"mappings":""}
|