appium-android-driver 4.51.0 → 4.54.0

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.
@@ -2,72 +2,149 @@ import _ from 'lodash';
2
2
  import { retryInterval } from 'asyncbox';
3
3
  import log from '../logger';
4
4
 
5
+ const commands = {}, helpers = {}, extensions = {};
5
6
 
6
- let commands = {}, helpers = {}, extensions = {};
7
-
8
- const NETWORK_KEYS = [['bucketStart', 'activeTime', 'rxBytes', 'rxPackets', 'txBytes', 'txPackets', 'operations', 'bucketDuration'], ['st', 'activeTime', 'rb', 'rp', 'tb', 'tp', 'op', 'bucketDuration']];
7
+ const NETWORK_KEYS = [
8
+ ['bucketStart', 'activeTime', 'rxBytes', 'rxPackets', 'txBytes', 'txPackets', 'operations', 'bucketDuration'],
9
+ ['st', 'activeTime', 'rb', 'rp', 'tb', 'tp', 'op', 'bucketDuration']
10
+ ];
9
11
  const CPU_KEYS = ['user', 'kernel'];
10
12
  const BATTERY_KEYS = ['power'];
11
- const MEMORY_KEYS = ['totalPrivateDirty', 'nativePrivateDirty', 'dalvikPrivateDirty', 'eglPrivateDirty', 'glPrivateDirty', 'totalPss', 'nativePss', 'dalvikPss', 'eglPss', 'glPss', 'nativeHeapAllocatedSize', 'nativeHeapSize'];
12
-
13
- const SUPPORTED_PERFORMANCE_DATA_TYPES = {
13
+ const MEMORY_KEYS = [
14
+ 'totalPrivateDirty', 'nativePrivateDirty', 'dalvikPrivateDirty',
15
+ 'eglPrivateDirty', 'glPrivateDirty',
16
+ 'totalPss', 'nativePss', 'dalvikPss', 'eglPss', 'glPss',
17
+ 'nativeHeapAllocatedSize', 'nativeHeapSize',
18
+ 'nativeRss', 'dalvikRss', 'totalRss'
19
+ ];
20
+ const SUPPORTED_PERFORMANCE_DATA_TYPES = Object.freeze({
14
21
  cpuinfo: 'the amount of cpu by user and kernel process - cpu information for applications on real devices and simulators',
15
22
  memoryinfo: 'the amount of memory used by the process - memory information for applications on real devices and simulators',
16
23
  batteryinfo: 'the remaining battery power - battery power information for applications on real devices and simulators',
17
24
  networkinfo: 'the network statistics - network rx/tx information for applications on real devices and simulators'
18
- };
19
-
20
- const RETRY_PAUSE = 1000;
25
+ });
26
+ const MEMINFO_TITLES = Object.freeze({
27
+ NATIVE: 'Native',
28
+ DALVIK: 'Dalvik',
29
+ EGL: 'EGL',
30
+ GL: 'GL',
31
+ MTRACK: 'mtrack',
32
+ TOTAL: 'TOTAL',
33
+ HEAP: 'Heap'
34
+ });
35
+ const RETRY_PAUSE_MS = 1000;
36
+
37
+ /**
38
+ * API level between 18 and 30
39
+ * ['<System Type>', '<Memory Type>', <pss total>, <private dirty>, <private clean>, <swapPss dirty>, <heap size>, <heap alloc>, <heap free>]
40
+ * except 'TOTAL', which skips the second type name
41
+ * !!! valDict gets mutated
42
+ */
43
+ function parseMeminfoForApi19To29 (entries, valDict) {
44
+ const [type, subType] = entries;
45
+ if (type === MEMINFO_TITLES.NATIVE && subType === MEMINFO_TITLES.HEAP) {
46
+ [,, valDict.nativePss, valDict.nativePrivateDirty,,, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;
47
+ } else if (type === MEMINFO_TITLES.DALVIK && subType === MEMINFO_TITLES.HEAP) {
48
+ [,, valDict.dalvikPss, valDict.dalvikPrivateDirty] = entries;
49
+ } else if (type === MEMINFO_TITLES.EGL && subType === MEMINFO_TITLES.MTRACK) {
50
+ [,, valDict.eglPss, valDict.eglPrivateDirty] = entries;
51
+ } else if (type === MEMINFO_TITLES.GL && subType === MEMINFO_TITLES.MTRACK) {
52
+ [,, valDict.glPss, valDict.glPrivateDirty] = entries;
53
+ } else if (type === MEMINFO_TITLES.TOTAL && entries.length === 8) {
54
+ // there are two totals, and we only want the full listing, which has 8 entries
55
+ [, valDict.totalPss, valDict.totalPrivateDirty] = entries;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * ['<System Type', '<pps>', '<shared dirty>', '<private dirty>', '<heap size>', '<heap alloc>', '<heap free>']
61
+ * !!! valDict gets mutated
62
+ */
63
+ function parseMeminfoForApiBelow19 (entries, valDict) {
64
+ const type = entries[0];
65
+ if (type === MEMINFO_TITLES.NATIVE) {
66
+ [, valDict.nativePss,, valDict.nativePrivateDirty, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;
67
+ } else if (type === MEMINFO_TITLES.DALVIK) {
68
+ [, valDict.dalvikPss,, valDict.dalvikPrivateDirty] = entries;
69
+ } else if (type === MEMINFO_TITLES.EGL) {
70
+ [, valDict.eglPss,, valDict.eglPrivateDirty] = entries;
71
+ } else if (type === MEMINFO_TITLES.GL) {
72
+ [, valDict.glPss,, valDict.glPrivateDirty] = entries;
73
+ } else if (type === MEMINFO_TITLES.TOTAL) {
74
+ [, valDict.totalPss,, valDict.totalPrivateDirty] = entries;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * API level 30 and above
80
+ * ['<System Type>', '<Memory Type>', <pss total>, <private dirty>, <private clean>, <swapPss dirty>, <rss total>, <heap size>, <heap alloc>, <heap free>]
81
+ * !!! valDict gets mutated
82
+ */
83
+ function parseMeminfoForApiAbove29 (entries, valDict) {
84
+ const [type, subType] = entries;
85
+ if (type === MEMINFO_TITLES.NATIVE && subType === MEMINFO_TITLES.HEAP) {
86
+ [,, valDict.nativePss, valDict.nativePrivateDirty,,, valDict.nativeRss, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;
87
+ } else if (type === MEMINFO_TITLES.DALVIK && subType === MEMINFO_TITLES.HEAP) {
88
+ [,, valDict.dalvikPss, valDict.dalvikPrivateDirty,,, valDict.dalvikRss] = entries;
89
+ } else if (type === MEMINFO_TITLES.EGL && subType === MEMINFO_TITLES.MTRACK) {
90
+ [,, valDict.eglPss, valDict.eglPrivateDirty] = entries;
91
+ } else if (type === MEMINFO_TITLES.GL && subType === MEMINFO_TITLES.MTRACK) {
92
+ [,, valDict.glPss, valDict.glPrivateDirty] = entries;
93
+ } else if (type === MEMINFO_TITLES.TOTAL && entries.length === 9) {
94
+ // has 9 entries
95
+ [, valDict.totalPss, valDict.totalPrivateDirty,,, valDict.totalRss] = entries;
96
+ }
97
+ }
21
98
 
22
99
  //
23
100
  // returns the information type of the system state which is supported to read as like cpu, memory, network traffic, and battery.
24
101
  // output - array like below
25
- //[cpuinfo, batteryinfo, networkinfo, memoryinfo]
102
+ // [cpuinfo, batteryinfo, networkinfo, memoryinfo]
26
103
  //
27
104
  commands.getPerformanceDataTypes = function getPerformanceDataTypes () {
28
105
  return _.keys(SUPPORTED_PERFORMANCE_DATA_TYPES);
29
106
  };
30
107
 
31
- // returns the information type of the system state which is supported to read as like cpu, memory, network traffic, and battery.
32
- //input - (packageName) the package name of the application
33
- // (dataType) the type of system state which wants to read. It should be one of the keys of the SUPPORTED_PERFORMANCE_DATA_TYPES
34
- // (dataReadTimeout) the number of attempts to read
35
- // output - table of the performance data, The first line of the table represents the type of data. The remaining lines represent the values of the data.
36
- //
37
- // in case of battery info : [[power], [23]]
38
- // in case of memory info : [[totalPrivateDirty, nativePrivateDirty, dalvikPrivateDirty, eglPrivateDirty, glPrivateDirty, totalPss, nativePss, dalvikPss, eglPss, glPss, nativeHeapAllocatedSize, nativeHeapSize], [18360, 8296, 6132, null, null, 42588, 8406, 7024, null, null, 26519, 10344]]
39
- // in case of network info : [[bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations, bucketDuration,], [1478091600000, null, 1099075, 610947, 928, 114362, 769, 0, 3600000], [1478095200000, null, 1306300, 405997, 509, 46359, 370, 0, 3600000]]
40
- // in case of network info : [[st, activeTime, rb, rp, tb, tp, op, bucketDuration], [1478088000, null, null, 32115296, 34291, 2956805, 25705, 0, 3600], [1478091600, null, null, 2714683, 11821, 1420564, 12650, 0, 3600], [1478095200, null, null, 10079213, 19962, 2487705, 20015, 0, 3600], [1478098800, null, null, 4444433, 10227, 1430356, 10493, 0, 3600]]
41
- // in case of cpu info : [[user, kernel], [0.9, 1.3]]
42
- //
43
- commands.getPerformanceData = async function getPerformanceData (packageName, dataType, dataReadTimeout = 2) {
44
- let data;
45
- switch (dataType) {
108
+ /**
109
+ * @returns The information type of the system state which is supported to read as like cpu, memory, network traffic, and battery.
110
+ * input - (packageName) the package name of the application
111
+ * (dataType) the type of system state which wants to read. It should be one of the keys of the SUPPORTED_PERFORMANCE_DATA_TYPES
112
+ * (dataReadTimeout) the number of attempts to read
113
+ * output - table of the performance data, The first line of the table represents the type of data. The remaining lines represent the values of the data.
114
+ *
115
+ * in case of battery info : [[power], [23]]
116
+ * in case of memory info : [[totalPrivateDirty, nativePrivateDirty, dalvikPrivateDirty, eglPrivateDirty, glPrivateDirty, totalPss,
117
+ * nativePss, dalvikPss, eglPss, glPss, nativeHeapAllocatedSize, nativeHeapSize], [18360, 8296, 6132, null, null, 42588, 8406, 7024, null, null, 26519, 10344]]
118
+ * in case of network info : [[bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations, bucketDuration,],
119
+ * [1478091600000, null, 1099075, 610947, 928, 114362, 769, 0, 3600000], [1478095200000, null, 1306300, 405997, 509, 46359, 370, 0, 3600000]]
120
+ * in case of network info : [[st, activeTime, rb, rp, tb, tp, op, bucketDuration], [1478088000, null, null, 32115296, 34291, 2956805, 25705, 0, 3600],
121
+ * [1478091600, null, null, 2714683, 11821, 1420564, 12650, 0, 3600], [1478095200, null, null, 10079213, 19962, 2487705, 20015, 0, 3600],
122
+ * [1478098800, null, null, 4444433, 10227, 1430356, 10493, 0, 3600]]
123
+ * in case of cpu info : [[user, kernel], [0.9, 1.3]]
124
+ */
125
+ commands.getPerformanceData = async function getPerformanceData (packageName, dataType, retries = 2) {
126
+ switch (_.toLower(dataType)) {
46
127
  case 'batteryinfo':
47
- data = await this.getBatteryInfo(dataReadTimeout);
48
- break;
128
+ return await this.getBatteryInfo(retries);
49
129
  case 'cpuinfo':
50
- data = await this.getCPUInfo(packageName, dataReadTimeout);
51
- break;
130
+ return await this.getCPUInfo(packageName, retries);
52
131
  case 'memoryinfo':
53
- data = await this.getMemoryInfo(packageName, dataReadTimeout);
54
- break;
132
+ return await this.getMemoryInfo(packageName, retries);
55
133
  case 'networkinfo':
56
- data = await this.getNetworkTrafficInfo(dataReadTimeout);
57
- break;
134
+ return await this.getNetworkTrafficInfo(retries);
58
135
  default:
59
- throw new Error(`No performance data of type '${dataType}' found.`);
136
+ throw new Error(`No performance data of type '${dataType}' found. ` +
137
+ `Only the following values are supported: ${JSON.stringify(SUPPORTED_PERFORMANCE_DATA_TYPES, ' ', 2)}`);
60
138
  }
61
- return data;
62
139
  };
63
140
 
64
- helpers.getCPUInfo = async function getCPUInfo (packageName, dataReadTimeout = 2) {
141
+ helpers.getCPUInfo = async function getCPUInfo (packageName, retries = 2) {
65
142
  // TODO: figure out why this is
66
143
  // sometimes, the function of 'adb.shell' fails. when I tested this function on the target of 'Galaxy Note5',
67
144
  // adb.shell(dumpsys cpuinfo) returns cpu datas for other application packages, but I can't find the data for packageName.
68
145
  // It usually fails 30 times and success for the next time,
69
146
  // Since then, he has continued to succeed.
70
- return await retryInterval(dataReadTimeout, RETRY_PAUSE, async () => {
147
+ return await retryInterval(retries, RETRY_PAUSE_MS, async () => {
71
148
  let output;
72
149
  try {
73
150
  output = await this.adb.shell(['dumpsys', 'cpuinfo']);
@@ -90,8 +167,8 @@ helpers.getCPUInfo = async function getCPUInfo (packageName, dataReadTimeout = 2
90
167
  });
91
168
  };
92
169
 
93
- helpers.getBatteryInfo = async function getBatteryInfo (dataReadTimeout = 2) {
94
- return await retryInterval(dataReadTimeout, RETRY_PAUSE, async () => {
170
+ helpers.getBatteryInfo = async function getBatteryInfo (retries = 2) {
171
+ return await retryInterval(retries, RETRY_PAUSE_MS, async () => {
95
172
  let cmd = ['dumpsys', 'battery', '|', 'grep', 'level'];
96
173
  let data = await this.adb.shell(cmd);
97
174
  if (!data) throw new Error('No data from dumpsys'); //eslint-disable-line curly
@@ -104,91 +181,44 @@ helpers.getBatteryInfo = async function getBatteryInfo (dataReadTimeout = 2) {
104
181
  throw new Error(`Unable to parse battery data: '${data}'`);
105
182
  }
106
183
  });
107
-
108
184
  };
109
185
 
110
- helpers.getMemoryInfo = async function getMemoryInfo (packageName, dataReadTimeout = 2) {
111
- return await retryInterval(dataReadTimeout, RETRY_PAUSE, async () => {
112
- let cmd = ['dumpsys', 'meminfo', `'${packageName}'`, '|', 'grep', '-E', "'Native|Dalvik|EGL|GL|TOTAL'"];
113
- let data = await this.adb.shell(cmd);
114
- if (!data) throw new Error('No data from dumpsys'); //eslint-disable-line curly
115
-
116
- let totalPrivateDirty, totalPss,
117
- nativePrivateDirty, nativePss, nativeHeapSize, nativeHeapAllocatedSize,
118
- dalvikPrivateDirty, dalvikPss,
119
- eglPrivateDirty, eglPss,
120
- glPrivateDirty, glPss;
121
- let apilevel = await this.adb.getApiLevel();
122
- for (let line of data.split('\n')) {
123
- let entries = line.trim().split(' ').filter(Boolean);
124
- // entries will have the values
125
- // ['<System Type>', '<Memory Type>', <pss total>, <private dirty>, <private clean>, <swapPss dirty>, <heap size>, <heap alloc>, <heap free>]
126
- // except 'TOTAL', which skips the second type name
127
- //
128
- // and on API level 18 and below
129
- // ['<System Type', '<pps>', '<shared dirty>', '<private dirty>', '<heap size>', '<heap alloc>', '<heap free>']
130
-
131
- if (apilevel > 18) {
132
- let type = entries[0];
133
- let subType = entries[1];
134
- if (type === 'Native' && subType === 'Heap') {
135
- // native heap
136
- nativePss = entries[2];
137
- nativePrivateDirty = entries[3];
138
- nativeHeapSize = entries[6];
139
- nativeHeapAllocatedSize = entries[7];
140
- } else if (type === 'Dalvik' && subType === 'Heap') {
141
- // dalvik heap
142
- dalvikPss = entries[2];
143
- dalvikPrivateDirty = entries[3];
144
- } else if (type === 'EGL' && subType === 'mtrack') {
145
- // egl
146
- eglPss = entries[2];
147
- eglPrivateDirty = entries[3];
148
- } else if (type === 'GL' && subType === 'mtrack') {
149
- // gl
150
- glPss = entries[2];
151
- glPrivateDirty = entries[3];
152
- } else if (type === 'TOTAL' && entries.length === 8) {
153
- // there are two totals, and we only want the full listing, which has 8 entries
154
- totalPss = entries[1];
155
- totalPrivateDirty = entries[2];
156
- }
186
+ helpers.getMemoryInfo = async function getMemoryInfo (packageName, retries = 2) {
187
+ return await retryInterval(retries, RETRY_PAUSE_MS, async () => {
188
+ const cmd = [
189
+ 'dumpsys', 'meminfo', `'${packageName}'`,
190
+ '|', 'grep', '-E',
191
+ `'${MEMINFO_TITLES.NATIVE}|${MEMINFO_TITLES.DALVIK}|${MEMINFO_TITLES.EGL}` +
192
+ `|${MEMINFO_TITLES.GL}|${MEMINFO_TITLES.TOTAL}'`
193
+ ];
194
+ const data = await this.adb.shell(cmd);
195
+ if (!data) {
196
+ throw new Error('No data from dumpsys');
197
+ }
198
+ const valDict = {totalPrivateDirty: ''};
199
+ const apiLevel = await this.adb.getApiLevel();
200
+ for (const line of data.split('\n')) {
201
+ const entries = line.trim().split(/\s+/).filter(Boolean);
202
+ if (apiLevel >= 30) {
203
+ parseMeminfoForApiAbove29(entries, valDict);
204
+ } else if (apiLevel > 18 && apiLevel < 30) {
205
+ parseMeminfoForApi19To29(entries, valDict);
157
206
  } else {
158
- let type = entries[0];
159
- if (type === 'Native') {
160
- nativePss = entries[1];
161
- nativePrivateDirty = entries[3];
162
- nativeHeapSize = entries[4];
163
- nativeHeapAllocatedSize = entries[5];
164
- } else if (type === 'Dalvik') {
165
- dalvikPss = entries[1];
166
- dalvikPrivateDirty = entries[3];
167
- } else if (type === 'EGL') {
168
- eglPss = entries[1];
169
- eglPrivateDirty = entries[3];
170
- } else if (type === 'GL') {
171
- glPss = entries[1];
172
- glPrivateDirty = entries[3];
173
- } else if (type === 'TOTAL') {
174
- totalPss = entries[1];
175
- totalPrivateDirty = entries[3];
176
- }
207
+ parseMeminfoForApiBelow19(entries, valDict);
177
208
  }
178
209
  }
179
-
180
- if (totalPrivateDirty && totalPrivateDirty !== 'nodex') {
181
- let headers = _.clone(MEMORY_KEYS);
182
- let data = [totalPrivateDirty, nativePrivateDirty, dalvikPrivateDirty, eglPrivateDirty, glPrivateDirty, totalPss, nativePss, dalvikPss, eglPss, glPss, nativeHeapAllocatedSize, nativeHeapSize];
183
- return [headers, data];
184
- } else {
185
- throw new Error(`Unable to parse memory data: '${data}'`);
210
+ if (valDict.totalPrivateDirty && valDict.totalPrivateDirty !== 'nodex') {
211
+ const headers = _.clone(MEMORY_KEYS);
212
+ const values = headers.map((header) => valDict[header]);
213
+ return [headers, values];
186
214
  }
215
+
216
+ throw new Error(`Unable to parse memory data: '${data}'`);
187
217
  });
188
218
  };
189
219
 
190
- helpers.getNetworkTrafficInfo = async function getNetworkTrafficInfo (dataReadTimeout = 2) {
191
- return await retryInterval(dataReadTimeout, RETRY_PAUSE, async () => {
220
+ helpers.getNetworkTrafficInfo = async function getNetworkTrafficInfo (retries = 2) {
221
+ return await retryInterval(retries, RETRY_PAUSE_MS, async () => {
192
222
  let returnValue = [];
193
223
  let bucketDuration, bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations;
194
224
 
@@ -346,3 +376,4 @@ export {
346
376
  BATTERY_KEYS, NETWORK_KEYS,
347
377
  };
348
378
  export default extensions;
379
+
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "mobile",
10
10
  "mobile testing"
11
11
  ],
12
- "version": "4.51.0",
12
+ "version": "4.54.0",
13
13
  "author": "appium",
14
14
  "license": "Apache-2.0",
15
15
  "repository": {
@@ -36,24 +36,24 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@babel/runtime": "^7.0.0",
39
- "appium-adb": "^8.16.0",
39
+ "appium-adb": "^8.18.0",
40
40
  "appium-base-driver": "^7.0.0",
41
41
  "appium-chromedriver": "^4.13.0",
42
42
  "appium-support": "^2.47.1",
43
43
  "asyncbox": "^2.8.0",
44
44
  "axios": "^0.x",
45
45
  "bluebird": "^3.4.7",
46
- "io.appium.settings": "^3.3.0",
47
- "jimp": "^0.16.1",
46
+ "io.appium.settings": "^3.6.0",
47
+ "jimp": "^0.x",
48
48
  "lodash": "^4.17.4",
49
49
  "lru-cache": "^6.0.0",
50
50
  "moment": "^2.24.0",
51
51
  "moment-timezone": "^0.5.26",
52
52
  "portfinder": "^1.0.6",
53
53
  "portscanner": "2.2.0",
54
- "shared-preferences-builder": "^0.0.4",
54
+ "shared-preferences-builder": "^0.x",
55
55
  "semver": "^7.0.0",
56
- "source-map-support": "^0.5.5",
56
+ "source-map-support": "^0.x",
57
57
  "teen_process": "^1.9.0",
58
58
  "ws": "^8.0.0"
59
59
  },
@@ -77,6 +77,7 @@
77
77
  "precommit-test"
78
78
  ],
79
79
  "devDependencies": {
80
+ "@xmldom/xmldom": "^0.x",
80
81
  "android-apidemos": "^3.0.0",
81
82
  "appium-gulp-plugins": "^5.4.0",
82
83
  "appium-test-support": "^1.0.0",
@@ -87,8 +88,7 @@
87
88
  "mocha": "^9.0.0",
88
89
  "mock-fs": "^5.0.0",
89
90
  "pre-commit": "^1.1.3",
90
- "sinon": "^11.0.0",
91
- "xmldom": "^0.x",
91
+ "sinon": "^12.0.0",
92
92
  "xpath": "^0.x"
93
93
  }
94
94
  }