appium-uiautomator2-driver 1.72.0 → 2.0.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.
- package/README.md +25 -5
- package/build/index.js +1 -1
- package/build/lib/commands/actions.js +1 -1
- package/build/lib/commands/alert.js +1 -1
- package/build/lib/commands/element.js +9 -9
- package/build/lib/commands/find.js +6 -12
- package/build/lib/commands/general.js +11 -10
- package/build/lib/commands/gestures.js +7 -7
- package/build/lib/commands/viewport.js +3 -3
- package/build/lib/css-converter.js +120 -113
- package/build/lib/driver.js +13 -13
- package/build/lib/extensions.js +1 -1
- package/build/lib/helpers.js +5 -5
- package/build/lib/logger.js +3 -3
- package/build/lib/server.js +5 -5
- package/build/lib/uiautomator2.js +13 -13
- package/lib/.DS_Store +0 -0
- package/lib/commands/element.js +2 -2
- package/lib/commands/find.js +5 -9
- package/lib/commands/general.js +4 -2
- package/lib/commands/gestures.js +2 -2
- package/lib/commands/viewport.js +1 -1
- package/lib/css-converter.js +178 -170
- package/lib/driver.js +17 -6
- package/lib/helpers.js +1 -1
- package/lib/logger.js +1 -1
- package/lib/server.js +1 -1
- package/lib/uiautomator2.js +2 -2
- package/package.json +21 -15
package/lib/css-converter.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { CssSelectorParser } from 'css-selector-parser';
|
|
2
2
|
import { escapeRegExp } from 'lodash';
|
|
3
|
-
import { errors } from 'appium
|
|
4
|
-
|
|
5
|
-
const CssConverter = {};
|
|
3
|
+
import { errors } from '@appium/base-driver';
|
|
6
4
|
|
|
7
5
|
const parser = new CssSelectorParser();
|
|
8
6
|
parser.registerSelectorPseudos('has');
|
|
@@ -113,16 +111,6 @@ function getWordMatcherRegex (word) {
|
|
|
113
111
|
return `\\b(\\w*${escapeRegExp(word)}\\w*)\\b`;
|
|
114
112
|
}
|
|
115
113
|
|
|
116
|
-
/**
|
|
117
|
-
* Add android:id/ to beginning of string if it's not there already
|
|
118
|
-
*
|
|
119
|
-
* @param {string} locator The initial locator
|
|
120
|
-
* @returns {string} String with `android:id/` prepended (if it wasn't already)
|
|
121
|
-
*/
|
|
122
|
-
function formatIdLocator (locator) {
|
|
123
|
-
return ID_LOCATOR_PATTERN.test(locator) ? locator : `android:id/${locator}`;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
114
|
/**
|
|
127
115
|
* @typedef {Object} CssAttr
|
|
128
116
|
* @property {?string} valueType Type of attribute (must be string or empty)
|
|
@@ -131,62 +119,20 @@ function formatIdLocator (locator) {
|
|
|
131
119
|
*/
|
|
132
120
|
|
|
133
121
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* @
|
|
137
|
-
* @
|
|
122
|
+
* @typedef {Object} CssRule
|
|
123
|
+
* @property {?string} nestingOperator The nesting operator (aka: combinator https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors)
|
|
124
|
+
* @property {?string} tagName The tag name (aka: type selector https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors)
|
|
125
|
+
* @property {?string[]} classNames An array of CSS class names
|
|
126
|
+
* @property {?CssAttr[]} attrs An array of CSS attributes
|
|
127
|
+
* @property {?CssPseudo[]} attrs An array of CSS pseudos
|
|
128
|
+
* @property {?string} id CSS identifier
|
|
129
|
+
* @property {?CssRule} rule A descendant of this CSS rule
|
|
138
130
|
*/
|
|
139
|
-
function parseAttr (cssAttr) {
|
|
140
|
-
if (cssAttr.valueType && cssAttr.valueType !== 'string') {
|
|
141
|
-
throw new Error(`'${cssAttr.name}=${cssAttr.value}' is an invalid attribute. ` +
|
|
142
|
-
`Only 'string' and empty attribute types are supported. Found '${cssAttr.valueType}'`);
|
|
143
|
-
}
|
|
144
|
-
const attrName = assertGetAttrName(cssAttr);
|
|
145
|
-
const methodName = toSnakeCase(attrName);
|
|
146
|
-
|
|
147
|
-
// Validate that it's a supported attribute
|
|
148
|
-
if (!STR_ATTRS.includes(attrName) && !BOOLEAN_ATTRS.includes(attrName)) {
|
|
149
|
-
throw new Error(`'${attrName}' is not supported. Supported attributes are ` +
|
|
150
|
-
`'${[...STR_ATTRS, ...BOOLEAN_ATTRS].join(', ')}'`);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Parse boolean, if it's a boolean attribute
|
|
154
|
-
if (BOOLEAN_ATTRS.includes(attrName)) {
|
|
155
|
-
return `.${methodName}(${assertGetBool(cssAttr)})`;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Otherwise parse as string
|
|
159
|
-
let value = cssAttr.value || '';
|
|
160
|
-
if (attrName === RESOURCE_ID) {
|
|
161
|
-
value = formatIdLocator(value);
|
|
162
|
-
}
|
|
163
|
-
if (value === '') {
|
|
164
|
-
return `.${methodName}Matches("")`;
|
|
165
|
-
}
|
|
166
131
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (['description', 'text'].includes(attrName)) {
|
|
172
|
-
return `.${methodName}Contains("${value}")`;
|
|
173
|
-
}
|
|
174
|
-
return `.${methodName}Matches("${escapeRegExp(value)}")`;
|
|
175
|
-
case '^=':
|
|
176
|
-
if (['description', 'text'].includes(attrName)) {
|
|
177
|
-
return `.${methodName}StartsWith("${value}")`;
|
|
178
|
-
}
|
|
179
|
-
return `.${methodName}Matches("^${escapeRegExp(value)}")`;
|
|
180
|
-
case '$=':
|
|
181
|
-
return `.${methodName}Matches("${escapeRegExp(value)}$")`;
|
|
182
|
-
case '~=':
|
|
183
|
-
return `.${methodName}Matches("${getWordMatcherRegex(value)}")`;
|
|
184
|
-
default:
|
|
185
|
-
// Unreachable, but adding error in case a new CSS attribute is added.
|
|
186
|
-
throw new Error(`Unsupported CSS attribute operator '${cssAttr.operator}'. ` +
|
|
187
|
-
` '=', '*=', '^=', '$=' and '~=' are supported.`);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
132
|
+
/**
|
|
133
|
+
* @typedef {Object} CssObject
|
|
134
|
+
* @property {?string} type Type of CSS object. 'rule', 'ruleset' or 'selectors'
|
|
135
|
+
*/
|
|
190
136
|
|
|
191
137
|
/**
|
|
192
138
|
* @typedef {Object} CssPseudo
|
|
@@ -195,126 +141,188 @@ function parseAttr (cssAttr) {
|
|
|
195
141
|
* @property {?string} value The value of the pseudo selector
|
|
196
142
|
*/
|
|
197
143
|
|
|
198
|
-
|
|
199
|
-
* Convert a CSS pseudo class to a UiSelector
|
|
200
|
-
*
|
|
201
|
-
* @param {CssPseudo} cssPseudo CSS Pseudo class
|
|
202
|
-
* @returns {string} Pseudo selector parsed as UiSelector
|
|
203
|
-
*/
|
|
204
|
-
function parsePseudo (cssPseudo) {
|
|
205
|
-
if (cssPseudo.valueType && cssPseudo.valueType !== 'string') {
|
|
206
|
-
throw new Error(`'${cssPseudo.name}=${cssPseudo.value}'. ` +
|
|
207
|
-
`Unsupported css pseudo class value type: '${cssPseudo.valueType}'. Only 'string' type or empty is supported.`);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const pseudoName = assertGetAttrName(cssPseudo);
|
|
144
|
+
class CssConverter {
|
|
211
145
|
|
|
212
|
-
|
|
213
|
-
|
|
146
|
+
constructor (selector, pkg) {
|
|
147
|
+
this.selector = selector;
|
|
148
|
+
this.pkg = pkg;
|
|
214
149
|
}
|
|
215
150
|
|
|
216
|
-
|
|
217
|
-
|
|
151
|
+
/**
|
|
152
|
+
* Add `<pkgName>:id/` prefix to beginning of string if it's not there already
|
|
153
|
+
*
|
|
154
|
+
* @param {string} locator The initial locator
|
|
155
|
+
* @returns {string} String with `<pkgName>:id/` prepended (if it wasn't already)
|
|
156
|
+
*/
|
|
157
|
+
formatIdLocator (locator) {
|
|
158
|
+
return ID_LOCATOR_PATTERN.test(locator)
|
|
159
|
+
? locator
|
|
160
|
+
: `${this.pkg || 'android'}:id/${locator}`;
|
|
218
161
|
}
|
|
219
|
-
}
|
|
220
162
|
|
|
221
|
-
/**
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Convert a CSS attribute into a UiSelector method call
|
|
165
|
+
*
|
|
166
|
+
* @param {CssAttr} cssAttr CSS attribute object
|
|
167
|
+
* @returns {string} CSS attribute parsed as UiSelector
|
|
168
|
+
*/
|
|
169
|
+
parseAttr (cssAttr) {
|
|
170
|
+
if (cssAttr.valueType && cssAttr.valueType !== 'string') {
|
|
171
|
+
throw new Error(`'${cssAttr.name}=${cssAttr.value}' is an invalid attribute. ` +
|
|
172
|
+
`Only 'string' and empty attribute types are supported. Found '${cssAttr.valueType}'`);
|
|
173
|
+
}
|
|
174
|
+
const attrName = assertGetAttrName(cssAttr);
|
|
175
|
+
const methodName = toSnakeCase(attrName);
|
|
231
176
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const { nestingOperator } = cssRule;
|
|
238
|
-
if (nestingOperator && nestingOperator !== ' ') {
|
|
239
|
-
throw new Error(`'${nestingOperator}' is not a supported combinator. ` +
|
|
240
|
-
`Only child combinator (>) and descendant combinator are supported.`);
|
|
241
|
-
}
|
|
177
|
+
// Validate that it's a supported attribute
|
|
178
|
+
if (!STR_ATTRS.includes(attrName) && !BOOLEAN_ATTRS.includes(attrName)) {
|
|
179
|
+
throw new Error(`'${attrName}' is not supported. Supported attributes are ` +
|
|
180
|
+
`'${[...STR_ATTRS, ...BOOLEAN_ATTRS].join(', ')}'`);
|
|
181
|
+
}
|
|
242
182
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (cssRule.classNames) {
|
|
247
|
-
for (const cssClassNames of cssRule.classNames) {
|
|
248
|
-
androidClass.push(cssClassNames);
|
|
249
|
-
}
|
|
250
|
-
uiAutomatorSelector += `.className("${androidClass.join('.')}")`;
|
|
251
|
-
} else {
|
|
252
|
-
uiAutomatorSelector += `.classNameMatches("${cssRule.tagName}")`;
|
|
183
|
+
// Parse boolean, if it's a boolean attribute
|
|
184
|
+
if (BOOLEAN_ATTRS.includes(attrName)) {
|
|
185
|
+
return `.${methodName}(${assertGetBool(cssAttr)})`;
|
|
253
186
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
if (cssRule.attrs) {
|
|
261
|
-
for (const attr of cssRule.attrs) {
|
|
262
|
-
uiAutomatorSelector += parseAttr(attr);
|
|
187
|
+
|
|
188
|
+
// Otherwise parse as string
|
|
189
|
+
let value = cssAttr.value || '';
|
|
190
|
+
if (attrName === RESOURCE_ID) {
|
|
191
|
+
value = this.formatIdLocator(value);
|
|
263
192
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
193
|
+
if (value === '') {
|
|
194
|
+
return `.${methodName}Matches("")`;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
switch (cssAttr.operator) {
|
|
198
|
+
case '=':
|
|
199
|
+
return `.${methodName}("${value}")`;
|
|
200
|
+
case '*=':
|
|
201
|
+
if (['description', 'text'].includes(attrName)) {
|
|
202
|
+
return `.${methodName}Contains("${value}")`;
|
|
203
|
+
}
|
|
204
|
+
return `.${methodName}Matches("${escapeRegExp(value)}")`;
|
|
205
|
+
case '^=':
|
|
206
|
+
if (['description', 'text'].includes(attrName)) {
|
|
207
|
+
return `.${methodName}StartsWith("${value}")`;
|
|
208
|
+
}
|
|
209
|
+
return `.${methodName}Matches("^${escapeRegExp(value)}")`;
|
|
210
|
+
case '$=':
|
|
211
|
+
return `.${methodName}Matches("${escapeRegExp(value)}$")`;
|
|
212
|
+
case '~=':
|
|
213
|
+
return `.${methodName}Matches("${getWordMatcherRegex(value)}")`;
|
|
214
|
+
default:
|
|
215
|
+
// Unreachable, but adding error in case a new CSS attribute is added.
|
|
216
|
+
throw new Error(`Unsupported CSS attribute operator '${cssAttr.operator}'. ` +
|
|
217
|
+
` '=', '*=', '^=', '$=' and '~=' are supported.`);
|
|
268
218
|
}
|
|
269
219
|
}
|
|
270
|
-
|
|
271
|
-
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Convert a CSS pseudo class to a UiSelector
|
|
223
|
+
*
|
|
224
|
+
* @param {CssPseudo} cssPseudo CSS Pseudo class
|
|
225
|
+
* @returns {string} Pseudo selector parsed as UiSelector
|
|
226
|
+
*/
|
|
227
|
+
parsePseudo (cssPseudo) {
|
|
228
|
+
if (cssPseudo.valueType && cssPseudo.valueType !== 'string') {
|
|
229
|
+
throw new Error(`'${cssPseudo.name}=${cssPseudo.value}'. ` +
|
|
230
|
+
`Unsupported css pseudo class value type: '${cssPseudo.valueType}'. Only 'string' type or empty is supported.`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const pseudoName = assertGetAttrName(cssPseudo);
|
|
234
|
+
|
|
235
|
+
if (BOOLEAN_ATTRS.includes(pseudoName)) {
|
|
236
|
+
return `.${toSnakeCase(pseudoName)}(${assertGetBool(cssPseudo)})`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (NUMERIC_ATTRS.includes(pseudoName)) {
|
|
240
|
+
return `.${pseudoName}(${cssPseudo.value})`;
|
|
241
|
+
}
|
|
272
242
|
}
|
|
273
|
-
return uiAutomatorSelector;
|
|
274
|
-
}
|
|
275
243
|
|
|
276
|
-
/**
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
244
|
+
/**
|
|
245
|
+
* Convert a CSS rule to a UiSelector
|
|
246
|
+
* @param {CssRule} cssRule CSS rule definition
|
|
247
|
+
*/
|
|
248
|
+
parseCssRule (cssRule) {
|
|
249
|
+
const { nestingOperator } = cssRule;
|
|
250
|
+
if (nestingOperator && nestingOperator !== ' ') {
|
|
251
|
+
throw new Error(`'${nestingOperator}' is not a supported combinator. ` +
|
|
252
|
+
`Only child combinator (>) and descendant combinator are supported.`);
|
|
253
|
+
}
|
|
280
254
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
255
|
+
let uiAutomatorSelector = 'new UiSelector()';
|
|
256
|
+
if (cssRule.tagName && cssRule.tagName !== '*') {
|
|
257
|
+
let androidClass = [cssRule.tagName];
|
|
258
|
+
if (cssRule.classNames) {
|
|
259
|
+
for (const cssClassNames of cssRule.classNames) {
|
|
260
|
+
androidClass.push(cssClassNames);
|
|
261
|
+
}
|
|
262
|
+
uiAutomatorSelector += `.className("${androidClass.join('.')}")`;
|
|
263
|
+
} else {
|
|
264
|
+
uiAutomatorSelector += `.classNameMatches("${cssRule.tagName}")`;
|
|
265
|
+
}
|
|
266
|
+
} else if (cssRule.classNames) {
|
|
267
|
+
uiAutomatorSelector += `.classNameMatches("${cssRule.classNames.join('\\.')}")`;
|
|
268
|
+
}
|
|
269
|
+
if (cssRule.id) {
|
|
270
|
+
uiAutomatorSelector += `.resourceId("${this.formatIdLocator(cssRule.id)}")`;
|
|
271
|
+
}
|
|
272
|
+
if (cssRule.attrs) {
|
|
273
|
+
for (const attr of cssRule.attrs) {
|
|
274
|
+
uiAutomatorSelector += this.parseAttr(attr);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (cssRule.pseudos) {
|
|
278
|
+
for (const pseudo of cssRule.pseudos) {
|
|
279
|
+
uiAutomatorSelector += this.parsePseudo(pseudo);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (cssRule.rule) {
|
|
283
|
+
uiAutomatorSelector += `.childSelector(${this.parseCssRule(cssRule.rule)})`;
|
|
284
|
+
}
|
|
285
|
+
return uiAutomatorSelector;
|
|
298
286
|
}
|
|
299
|
-
}
|
|
300
287
|
|
|
301
|
-
/**
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
288
|
+
/**
|
|
289
|
+
* Convert CSS object to UiAutomator2 selector
|
|
290
|
+
* @param {CssObject} css CSS object
|
|
291
|
+
* @returns {string} The CSS object parsed as a UiSelector
|
|
292
|
+
*/
|
|
293
|
+
parseCssObject (css) {
|
|
294
|
+
switch (css.type) {
|
|
295
|
+
case 'rule':
|
|
296
|
+
return this.parseCssRule(css);
|
|
297
|
+
case 'ruleSet':
|
|
298
|
+
return this.parseCssObject(css.rule);
|
|
299
|
+
case 'selectors':
|
|
300
|
+
return css.selectors.map((selector) => this.parseCssObject(selector)).join('; ');
|
|
301
|
+
|
|
302
|
+
default:
|
|
303
|
+
// This is never reachable, but if it ever is do this.
|
|
304
|
+
throw new Error(`UiAutomator does not support '${css.type}' css. Only supports 'rule', 'ruleSet', 'selectors' `);
|
|
305
|
+
}
|
|
312
306
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Convert a CSS selector to a UiAutomator2 selector
|
|
310
|
+
*
|
|
311
|
+
* @returns {string} The CSS selector converted to a UiSelector
|
|
312
|
+
*/
|
|
313
|
+
toUiAutomatorSelector () {
|
|
314
|
+
let cssObj;
|
|
315
|
+
try {
|
|
316
|
+
cssObj = parser.parse(this.selector);
|
|
317
|
+
} catch (e) {
|
|
318
|
+
throw new errors.InvalidSelectorError(`Invalid CSS selector '${this.selector}'. Reason: '${e}'`);
|
|
319
|
+
}
|
|
320
|
+
try {
|
|
321
|
+
return this.parseCssObject(cssObj);
|
|
322
|
+
} catch (e) {
|
|
323
|
+
throw new errors.InvalidSelectorError(`Unsupported CSS selector '${this.selector}'. Reason: '${e}'`);
|
|
324
|
+
}
|
|
317
325
|
}
|
|
318
|
-
}
|
|
326
|
+
}
|
|
319
327
|
|
|
320
328
|
export default CssConverter;
|
package/lib/driver.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import { BaseDriver, DeviceSettings } from 'appium
|
|
2
|
+
import { BaseDriver, DeviceSettings } from '@appium/base-driver';
|
|
3
3
|
import {
|
|
4
4
|
UiAutomator2Server, SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID
|
|
5
5
|
} from './uiautomator2';
|
|
6
|
-
import { fs, util, mjpeg } from 'appium
|
|
6
|
+
import { fs, util, mjpeg } from '@appium/support';
|
|
7
7
|
import { retryInterval } from 'asyncbox';
|
|
8
8
|
import B from 'bluebird';
|
|
9
9
|
import logger from './logger';
|
|
@@ -67,7 +67,6 @@ const NO_PROXY = [
|
|
|
67
67
|
['GET', new RegExp('^/session/[^/]+/element/[^/]+/selected')],
|
|
68
68
|
['GET', new RegExp('^/session/[^/]+/ime/[^/]+')],
|
|
69
69
|
['GET', new RegExp('^/session/[^/]+/location')],
|
|
70
|
-
['GET', new RegExp('^/session/[^/]+/log/types')],
|
|
71
70
|
['GET', new RegExp('^/session/[^/]+/network_connection')],
|
|
72
71
|
['GET', new RegExp('^/session/[^/]+/screenshot')],
|
|
73
72
|
['GET', new RegExp('^/session/[^/]+/timeouts')],
|
|
@@ -94,7 +93,6 @@ const NO_PROXY = [
|
|
|
94
93
|
['POST', new RegExp('^/session/[^/]+/ime/[^/]+')],
|
|
95
94
|
['POST', new RegExp('^/session/[^/]+/keys')],
|
|
96
95
|
['POST', new RegExp('^/session/[^/]+/location')],
|
|
97
|
-
['POST', new RegExp('^/session/[^/]+/log')],
|
|
98
96
|
['POST', new RegExp('^/session/[^/]+/network_connection')],
|
|
99
97
|
['POST', new RegExp('^/session/[^/]+/timeouts')],
|
|
100
98
|
['POST', new RegExp('^/session/[^/]+/touch/multi/perform')],
|
|
@@ -102,12 +100,18 @@ const NO_PROXY = [
|
|
|
102
100
|
['POST', new RegExp('^/session/[^/]+/url')],
|
|
103
101
|
|
|
104
102
|
// MJSONWP commands
|
|
103
|
+
['GET', new RegExp('^/session/[^/]+/log/types')],
|
|
105
104
|
['POST', new RegExp('^/session/[^/]+/execute')],
|
|
106
105
|
['POST', new RegExp('^/session/[^/]+/execute_async')],
|
|
106
|
+
['POST', new RegExp('^/session/[^/]+/log')],
|
|
107
107
|
// W3C commands
|
|
108
|
+
// For Selenium v4 (W3C does not have this route)
|
|
109
|
+
['GET', new RegExp('^/session/[^/]+/se/log/types')],
|
|
108
110
|
['GET', new RegExp('^/session/[^/]+/window/rect')],
|
|
109
111
|
['POST', new RegExp('^/session/[^/]+/execute/async')],
|
|
110
112
|
['POST', new RegExp('^/session/[^/]+/execute/sync')],
|
|
113
|
+
// For Selenium v4 (W3C does not have this route)
|
|
114
|
+
['POST', new RegExp('^/session/[^/]+/se/log')],
|
|
111
115
|
];
|
|
112
116
|
|
|
113
117
|
// This is a set of methods and paths that we never want to proxy to Chromedriver.
|
|
@@ -115,11 +119,9 @@ const CHROME_NO_PROXY = [
|
|
|
115
119
|
['GET', new RegExp('^/session/[^/]+/appium')],
|
|
116
120
|
['GET', new RegExp('^/session/[^/]+/context')],
|
|
117
121
|
['GET', new RegExp('^/session/[^/]+/element/[^/]+/rect')],
|
|
118
|
-
['GET', new RegExp('^/session/[^/]+/log/types$')],
|
|
119
122
|
['GET', new RegExp('^/session/[^/]+/orientation')],
|
|
120
123
|
['POST', new RegExp('^/session/[^/]+/appium')],
|
|
121
124
|
['POST', new RegExp('^/session/[^/]+/context')],
|
|
122
|
-
['POST', new RegExp('^/session/[^/]+/log$')],
|
|
123
125
|
['POST', new RegExp('^/session/[^/]+/orientation')],
|
|
124
126
|
['POST', new RegExp('^/session/[^/]+/touch/multi/perform')],
|
|
125
127
|
['POST', new RegExp('^/session/[^/]+/touch/perform')],
|
|
@@ -127,6 +129,15 @@ const CHROME_NO_PROXY = [
|
|
|
127
129
|
// this is needed to make the mobile: commands working in web context
|
|
128
130
|
['POST', new RegExp('^/session/[^/]+/execute$')],
|
|
129
131
|
['POST', new RegExp('^/session/[^/]+/execute/sync')],
|
|
132
|
+
|
|
133
|
+
// MJSONWP commands
|
|
134
|
+
['GET', new RegExp('^/session/[^/]+/log/types$')],
|
|
135
|
+
['POST', new RegExp('^/session/[^/]+/log$')],
|
|
136
|
+
// W3C commands
|
|
137
|
+
// For Selenium v4 (W3C does not have this route)
|
|
138
|
+
['GET', new RegExp('^/session/[^/]+/se/log/types$')],
|
|
139
|
+
// For Selenium v4 (W3C does not have this route)
|
|
140
|
+
['POST', new RegExp('^/session/[^/]+/se/log$')],
|
|
130
141
|
];
|
|
131
142
|
|
|
132
143
|
const MEMOIZED_FUNCTIONS = [
|
package/lib/helpers.js
CHANGED
package/lib/logger.js
CHANGED
package/lib/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import log from './logger';
|
|
2
|
-
import { server as baseServer, routeConfiguringFunction as makeRouter } from 'appium
|
|
2
|
+
import { server as baseServer, routeConfiguringFunction as makeRouter } from '@appium/base-driver';
|
|
3
3
|
import AndroidUiautomator2Driver from './driver';
|
|
4
4
|
|
|
5
5
|
|
package/lib/uiautomator2.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import { JWProxy, errors } from 'appium
|
|
2
|
+
import { JWProxy, errors } from '@appium/base-driver';
|
|
3
3
|
import { waitForCondition } from 'asyncbox';
|
|
4
4
|
import log from './logger';
|
|
5
5
|
import {
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from 'appium-uiautomator2-server';
|
|
10
10
|
import {
|
|
11
11
|
util, logger, tempDir, fs, timing
|
|
12
|
-
} from 'appium
|
|
12
|
+
} from '@appium/support';
|
|
13
13
|
import B from 'bluebird';
|
|
14
14
|
import helpers from './helpers';
|
|
15
15
|
import axios from 'axios';
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"automated testing",
|
|
8
8
|
"android"
|
|
9
9
|
],
|
|
10
|
-
"version": "
|
|
10
|
+
"version": "2.0.0",
|
|
11
11
|
"author": "appium",
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
13
|
"repository": {
|
|
@@ -40,20 +40,20 @@
|
|
|
40
40
|
"build/lib"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"@appium/base-driver": "^8.0.0",
|
|
44
|
+
"@appium/support": "^2.55.3",
|
|
43
45
|
"@babel/runtime": "^7.0.0",
|
|
44
|
-
"appium-adb": "^
|
|
45
|
-
"appium-android-driver": "^
|
|
46
|
-
"appium-
|
|
47
|
-
"appium-
|
|
48
|
-
"appium-support": "^2.49.0",
|
|
49
|
-
"appium-uiautomator2-server": "^4.28.0",
|
|
46
|
+
"appium-adb": "^9.0.0",
|
|
47
|
+
"appium-android-driver": "^5.0.0",
|
|
48
|
+
"appium-chromedriver": "^5.0.1",
|
|
49
|
+
"appium-uiautomator2-server": "^5.0.0",
|
|
50
50
|
"asyncbox": "^2.3.1",
|
|
51
51
|
"axios": "^0.x",
|
|
52
52
|
"bluebird": "^3.5.1",
|
|
53
53
|
"css-selector-parser": "^1.4.1",
|
|
54
54
|
"lodash": "^4.17.4",
|
|
55
|
-
"portscanner": "2.2.0",
|
|
56
|
-
"source-map-support": "^0.
|
|
55
|
+
"portscanner": "^2.2.0",
|
|
56
|
+
"source-map-support": "^0.x",
|
|
57
57
|
"teen_process": "^1.3.1"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
@@ -81,13 +81,19 @@
|
|
|
81
81
|
"test"
|
|
82
82
|
],
|
|
83
83
|
"devDependencies": {
|
|
84
|
+
"@appium/gulp-plugins": "^6.0.0",
|
|
85
|
+
"@appium/eslint-config-appium": "^5.0.0",
|
|
86
|
+
"@appium/test-support": "^1.0.0",
|
|
87
|
+
"@babel/core": "^7.16.0",
|
|
88
|
+
"@babel/eslint-parser": "^7.16.3",
|
|
84
89
|
"@xmldom/xmldom": "^0.x",
|
|
85
|
-
"android-apidemos": "^
|
|
86
|
-
"appium-gulp-plugins": "^5.4.0",
|
|
87
|
-
"appium-test-support": "^1.0.0",
|
|
90
|
+
"android-apidemos": "^4.0.0",
|
|
88
91
|
"chai": "^4.1.0",
|
|
89
92
|
"chai-as-promised": "^7.1.1",
|
|
90
|
-
"eslint
|
|
93
|
+
"eslint": "^7.32.0",
|
|
94
|
+
"eslint-plugin-import": "^2.25.3",
|
|
95
|
+
"eslint-plugin-mocha": "^9.0.0",
|
|
96
|
+
"eslint-plugin-promise": "^6.0.0",
|
|
91
97
|
"gps-demo-app": "^2.1.1",
|
|
92
98
|
"gulp": "^4.0.0",
|
|
93
99
|
"mocha": "^9.0.0",
|
|
@@ -97,8 +103,8 @@
|
|
|
97
103
|
"pre-commit": "^1.2.2",
|
|
98
104
|
"rimraf": "^3.0.0",
|
|
99
105
|
"sinon": "^12.0.0",
|
|
100
|
-
"unzipper": "^0.
|
|
101
|
-
"
|
|
106
|
+
"unzipper": "^0.x",
|
|
107
|
+
"webdriverio": "^7.0.0",
|
|
102
108
|
"xpath": "^0.x"
|
|
103
109
|
}
|
|
104
110
|
}
|