appium-xcuitest-driver 11.9.0 → 11.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +5 -7
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/css/class-chain-emitter.d.ts +14 -0
- package/build/lib/css/class-chain-emitter.d.ts.map +1 -0
- package/build/lib/css/class-chain-emitter.js +98 -0
- package/build/lib/css/class-chain-emitter.js.map +1 -0
- package/build/lib/css/constants.d.ts +5 -0
- package/build/lib/css/constants.d.ts.map +1 -0
- package/build/lib/css/constants.js +8 -0
- package/build/lib/css/constants.js.map +1 -0
- package/build/lib/css/index.d.ts +10 -0
- package/build/lib/css/index.d.ts.map +1 -0
- package/build/lib/css/index.js +55 -0
- package/build/lib/css/index.js.map +1 -0
- package/build/lib/css/schema.d.ts +3 -0
- package/build/lib/css/schema.d.ts.map +1 -0
- package/build/lib/css/schema.js +18 -0
- package/build/lib/css/schema.js.map +1 -0
- package/lib/commands/find.ts +2 -4
- package/lib/css/class-chain-emitter.ts +122 -0
- package/lib/css/constants.ts +5 -0
- package/lib/css/index.ts +55 -0
- package/lib/css/schema.ts +16 -0
- package/npm-shrinkwrap.json +46 -21
- package/package.json +2 -2
- package/build/lib/css-converter.d.ts +0 -4
- package/build/lib/css-converter.d.ts.map +0 -1
- package/build/lib/css-converter.js +0 -244
- package/build/lib/css-converter.js.map +0 -1
- package/lib/css-converter.ts +0 -300
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [11.9.1](https://github.com/appium/appium-xcuitest-driver/compare/v11.9.0...v11.9.1) (2026-06-08)
|
|
2
|
+
|
|
3
|
+
### Miscellaneous Chores
|
|
4
|
+
|
|
5
|
+
* Refactor css locator transformer ([#2864](https://github.com/appium/appium-xcuitest-driver/issues/2864)) ([74c6765](https://github.com/appium/appium-xcuitest-driver/commit/74c67655048d15f83053e17736d3f8a459d0cf67))
|
|
6
|
+
|
|
1
7
|
## [11.9.0](https://github.com/appium/appium-xcuitest-driver/compare/v11.8.1...v11.9.0) (2026-06-03)
|
|
2
8
|
|
|
3
9
|
### Features
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../lib/commands/find.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,OAAO,EAAe,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,WAAW,CAAC;AAG9C;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,GAAG,GACZ,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AACtB,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,KAAK,EACX,OAAO,CAAC,EAAE,GAAG,GACZ,OAAO,CAAC,OAAO,CAAC,CAAC;AACpB,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE,GAAG,GACZ,OAAO,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC,CAAC;AAChC,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE,GAAG,GACZ,OAAO,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC,CAAC;AAkBhC;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,GAAG,GACZ,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AACtB,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,KAAK,EACX,OAAO,CAAC,EAAE,GAAG,GACZ,OAAO,CAAC,OAAO,CAAC,CAAC;AACpB,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE,GAAG,GACZ,OAAO,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../lib/commands/find.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ exports.findNativeElementOrElements = findNativeElementOrElements;
|
|
|
5
5
|
exports.doNativeFind = doNativeFind;
|
|
6
6
|
exports.getFirstVisibleChild = getFirstVisibleChild;
|
|
7
7
|
const utils_1 = require("../utils");
|
|
8
|
-
const
|
|
8
|
+
const css_1 = require("../css");
|
|
9
9
|
const driver_1 = require("appium/driver");
|
|
10
10
|
const support_1 = require("appium/support");
|
|
11
11
|
async function findElOrEls(strategy, selector, mult, context) {
|
|
@@ -25,11 +25,10 @@ async function findNativeElementOrElements(strategy, selector, mult, context) {
|
|
|
25
25
|
strategy = 'predicate string';
|
|
26
26
|
}
|
|
27
27
|
else if (strategy === '-ios class chain') {
|
|
28
|
-
strategy = WDA_CLASS_CHAIN_STRATEGY;
|
|
28
|
+
strategy = css_1.WDA_CLASS_CHAIN_STRATEGY;
|
|
29
29
|
}
|
|
30
30
|
else if (strategy === 'css selector') {
|
|
31
|
-
strategy =
|
|
32
|
-
selector = css_converter_1.CssConverter.toIosClassChainSelector(selector);
|
|
31
|
+
({ strategy, selector } = await (0, css_1.cssToNativeLocator)(selector));
|
|
33
32
|
}
|
|
34
33
|
if (strategy === 'class name') {
|
|
35
34
|
if (selector.startsWith('UIA')) {
|
|
@@ -122,7 +121,7 @@ async function getFirstVisibleChild(mult, context) {
|
|
|
122
121
|
}
|
|
123
122
|
let index = 1;
|
|
124
123
|
while (true) {
|
|
125
|
-
const strategy = WDA_CLASS_CHAIN_STRATEGY;
|
|
124
|
+
const strategy = css_1.WDA_CLASS_CHAIN_STRATEGY;
|
|
126
125
|
const selector = `*[${index}]`;
|
|
127
126
|
const nthChild = (await this.doNativeFind(strategy, selector, false, context));
|
|
128
127
|
const visible = await this.getAttribute('visible', nthChild);
|
|
@@ -135,7 +134,6 @@ async function getFirstVisibleChild(mult, context) {
|
|
|
135
134
|
}
|
|
136
135
|
const MAGIC_FIRST_VIS_CHILD_SEL = /\/\*\[@firstVisible\s*=\s*('|")true\1\]/;
|
|
137
136
|
const MAGIC_SCROLLABLE_SEL = /\/\/\*\[@scrollable\s*=\s*('|")true\1\]/;
|
|
138
|
-
const WDA_CLASS_CHAIN_STRATEGY = 'class chain';
|
|
139
137
|
function stripViewFromSelector(selector) {
|
|
140
138
|
const keepView = [
|
|
141
139
|
'XCUIElementTypeScrollView',
|
|
@@ -152,7 +150,7 @@ function rewriteMagicScrollable(mult, log = null) {
|
|
|
152
150
|
const pred = ['ScrollView', 'Table', 'CollectionView', 'WebView']
|
|
153
151
|
.map((t) => `type == "XCUIElementType${t}"`)
|
|
154
152
|
.join(' OR ');
|
|
155
|
-
const strategy = WDA_CLASS_CHAIN_STRATEGY;
|
|
153
|
+
const strategy = css_1.WDA_CLASS_CHAIN_STRATEGY;
|
|
156
154
|
let selector = '**/*[`' + pred + '`]';
|
|
157
155
|
if (!mult) {
|
|
158
156
|
selector += '[1]';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../lib/commands/find.ts"],"names":[],"mappings":";;AAuCA,kCAeC;AA0BD,
|
|
1
|
+
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../lib/commands/find.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ParsedSelector, StrategyEmitter } from '@appium/css-locator-to-native';
|
|
2
|
+
/** Converts parsed CSS selectors into class chain strings. */
|
|
3
|
+
export declare class ClassChainEmitter implements StrategyEmitter {
|
|
4
|
+
readonly strategy: string;
|
|
5
|
+
constructor(strategy: string);
|
|
6
|
+
emit(parsed: ParsedSelector): string;
|
|
7
|
+
private emitRule;
|
|
8
|
+
private formatEntity;
|
|
9
|
+
private formatIndex;
|
|
10
|
+
private formatBooleanAttr;
|
|
11
|
+
private formatStringAttr;
|
|
12
|
+
private toCamelCase;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=class-chain-emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-chain-emitter.d.ts","sourceRoot":"","sources":["../../../lib/css/class-chain-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,cAAc,EACd,eAAe,EAChB,MAAM,+BAA+B,CAAC;AAMvC,8DAA8D;AAC9D,qBAAa,iBAAkB,YAAW,eAAe;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;IAI5B,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM;IAIpC,OAAO,CAAC,QAAQ;IA8ChB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,gBAAgB;IAuBxB,OAAO,CAAC,WAAW;CAOpB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClassChainEmitter = void 0;
|
|
4
|
+
const driver_1 = require("appium/driver");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
const BOOLEAN_ATTRS = new Set(['visible', 'accessible', 'accessibility-container', 'enabled']);
|
|
7
|
+
const STRING_ATTRS = new Set(['label', 'name', 'value', 'type']);
|
|
8
|
+
/** Converts parsed CSS selectors into class chain strings. */
|
|
9
|
+
class ClassChainEmitter {
|
|
10
|
+
strategy;
|
|
11
|
+
constructor(strategy) {
|
|
12
|
+
this.strategy = strategy;
|
|
13
|
+
}
|
|
14
|
+
emit(parsed) {
|
|
15
|
+
return this.emitRule(parsed.rule);
|
|
16
|
+
}
|
|
17
|
+
emitRule(rule) {
|
|
18
|
+
if (rule.classes.length) {
|
|
19
|
+
throw new driver_1.errors.InvalidSelectorError(`'${rule.classes.join('.')}' is not a valid class. Must be a single string ` +
|
|
20
|
+
`(e.g.: XCUIElementTypeWindow) without dots separating them`);
|
|
21
|
+
}
|
|
22
|
+
let tagName = rule.tag ?? '';
|
|
23
|
+
if (tagName && tagName !== '*' && !tagName.toLowerCase().startsWith('xcuielementtype')) {
|
|
24
|
+
const capitalizedTagName = tagName.charAt(0).toUpperCase() + tagName.slice(1);
|
|
25
|
+
tagName = `XCUIElementType${capitalizedTagName}`;
|
|
26
|
+
}
|
|
27
|
+
let classChainSelector = tagName || '*';
|
|
28
|
+
const attrs = [];
|
|
29
|
+
if (rule.id) {
|
|
30
|
+
attrs.push(`name == "${rule.id}"`);
|
|
31
|
+
}
|
|
32
|
+
for (const attr of rule.attributes) {
|
|
33
|
+
attrs.push(this.formatEntity(attr));
|
|
34
|
+
}
|
|
35
|
+
for (const pseudo of rule.pseudos) {
|
|
36
|
+
attrs.push(this.formatEntity(pseudo));
|
|
37
|
+
}
|
|
38
|
+
const nonIndexAttrs = attrs.filter((attr) => typeof attr === 'string');
|
|
39
|
+
if (!(0, utils_1.isEmpty)(nonIndexAttrs)) {
|
|
40
|
+
classChainSelector += `[\`${nonIndexAttrs.join(' AND ')}\`]`;
|
|
41
|
+
}
|
|
42
|
+
const indexAttr = attrs.find((attr) => typeof attr === 'object' && attr !== null && attr.index !== undefined);
|
|
43
|
+
if (indexAttr) {
|
|
44
|
+
classChainSelector += `[${indexAttr.index}]`;
|
|
45
|
+
}
|
|
46
|
+
if (rule.nested) {
|
|
47
|
+
classChainSelector += `/${this.emitRule(rule.nested)}`;
|
|
48
|
+
}
|
|
49
|
+
return rule.combinator === 'child' ? classChainSelector : `**/${classChainSelector}`;
|
|
50
|
+
}
|
|
51
|
+
formatEntity(attr) {
|
|
52
|
+
if (attr.name === 'index') {
|
|
53
|
+
return this.formatIndex(attr.value);
|
|
54
|
+
}
|
|
55
|
+
if (BOOLEAN_ATTRS.has(attr.name)) {
|
|
56
|
+
return this.formatBooleanAttr(attr.name, attr.value);
|
|
57
|
+
}
|
|
58
|
+
if (STRING_ATTRS.has(attr.name)) {
|
|
59
|
+
return this.formatStringAttr(attr);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
formatIndex(value) {
|
|
63
|
+
return { index: value ?? '' };
|
|
64
|
+
}
|
|
65
|
+
formatBooleanAttr(name, value) {
|
|
66
|
+
return `${this.toCamelCase(name)} == ${value ?? '1'}`;
|
|
67
|
+
}
|
|
68
|
+
formatStringAttr(attr) {
|
|
69
|
+
const attrName = this.toCamelCase(attr.name);
|
|
70
|
+
const value = attr.value ?? '';
|
|
71
|
+
if (value === '') {
|
|
72
|
+
return `[${attrName} LIKE ${value}]`;
|
|
73
|
+
}
|
|
74
|
+
switch (attr.operator) {
|
|
75
|
+
case '=':
|
|
76
|
+
return `${attrName} == "${value}"`;
|
|
77
|
+
case '*=':
|
|
78
|
+
return `${attrName} MATCHES "${(0, utils_1.escapeRegExp)(value)}"`;
|
|
79
|
+
case '^=':
|
|
80
|
+
return `${attrName} BEGINSWITH "${value}"`;
|
|
81
|
+
case '$=':
|
|
82
|
+
return `${attrName} ENDSWITH "${value}"`;
|
|
83
|
+
case '~=':
|
|
84
|
+
return `${attrName} CONTAINS "${value}"`;
|
|
85
|
+
default:
|
|
86
|
+
return `${attrName} == "${value}"`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
toCamelCase(str) {
|
|
90
|
+
const tokens = str
|
|
91
|
+
.split('-')
|
|
92
|
+
.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase());
|
|
93
|
+
const out = tokens.join('');
|
|
94
|
+
return out.charAt(0).toLowerCase() + out.slice(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.ClassChainEmitter = ClassChainEmitter;
|
|
98
|
+
//# sourceMappingURL=class-chain-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-chain-emitter.js","sourceRoot":"","sources":["../../../lib/css/class-chain-emitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Locator strategy name used by WebDriverAgent for class chain queries. */
|
|
2
|
+
export declare const WDA_CLASS_CHAIN_STRATEGY = "class chain";
|
|
3
|
+
/** Registry key for the class chain CSS emitter. */
|
|
4
|
+
export declare const CLASS_CHAIN_EMITTER_KEY = "classChain";
|
|
5
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../lib/css/constants.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,eAAO,MAAM,wBAAwB,gBAAgB,CAAC;AAEtD,oDAAoD;AACpD,eAAO,MAAM,uBAAuB,eAAe,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLASS_CHAIN_EMITTER_KEY = exports.WDA_CLASS_CHAIN_STRATEGY = void 0;
|
|
4
|
+
/** Locator strategy name used by WebDriverAgent for class chain queries. */
|
|
5
|
+
exports.WDA_CLASS_CHAIN_STRATEGY = 'class chain';
|
|
6
|
+
/** Registry key for the class chain CSS emitter. */
|
|
7
|
+
exports.CLASS_CHAIN_EMITTER_KEY = 'classChain';
|
|
8
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../lib/css/constants.ts"],"names":[],"mappings":";;;AAAA,4EAA4E;AAC/D,QAAA,wBAAwB,GAAG,aAAa,CAAC;AAEtD,oDAAoD;AACvC,QAAA,uBAAuB,GAAG,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NativeLocator } from '@appium/css-locator-to-native';
|
|
2
|
+
export { WDA_CLASS_CHAIN_STRATEGY } from './constants';
|
|
3
|
+
/**
|
|
4
|
+
* Converts a CSS selector string into a native locator for the resolved strategy.
|
|
5
|
+
*
|
|
6
|
+
* @param css - CSS selector to transform
|
|
7
|
+
* @returns Native locator strategy name and selector string
|
|
8
|
+
*/
|
|
9
|
+
export declare function cssToNativeLocator(css: string): Promise<NativeLocator>;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/css/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAiB,aAAa,EAAc,MAAM,+BAA+B,CAAC;AAE9F,OAAO,EAAC,wBAAwB,EAAC,MAAM,aAAa,CAAC;AAiBrD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAO5E"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WDA_CLASS_CHAIN_STRATEGY = void 0;
|
|
4
|
+
exports.cssToNativeLocator = cssToNativeLocator;
|
|
5
|
+
const driver_1 = require("appium/driver");
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
const constants_1 = require("./constants");
|
|
8
|
+
const schema_1 = require("./schema");
|
|
9
|
+
const class_chain_emitter_1 = require("./class-chain-emitter");
|
|
10
|
+
var constants_2 = require("./constants");
|
|
11
|
+
Object.defineProperty(exports, "WDA_CLASS_CHAIN_STRATEGY", { enumerable: true, get: function () { return constants_2.WDA_CLASS_CHAIN_STRATEGY; } });
|
|
12
|
+
const emitters = {
|
|
13
|
+
[constants_1.CLASS_CHAIN_EMITTER_KEY]: new class_chain_emitter_1.ClassChainEmitter(constants_1.WDA_CLASS_CHAIN_STRATEGY),
|
|
14
|
+
};
|
|
15
|
+
const getTransformCss = (0, utils_1.memoize)(async function loadTransformCss() {
|
|
16
|
+
const mod = await import('@appium/css-locator-to-native');
|
|
17
|
+
return mod.createCssTransformer({
|
|
18
|
+
schema: schema_1.ATTRIBUTE_SCHEMA,
|
|
19
|
+
emitters,
|
|
20
|
+
resolveStrategy() {
|
|
21
|
+
return constants_1.CLASS_CHAIN_EMITTER_KEY;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Converts a CSS selector string into a native locator for the resolved strategy.
|
|
27
|
+
*
|
|
28
|
+
* @param css - CSS selector to transform
|
|
29
|
+
* @returns Native locator strategy name and selector string
|
|
30
|
+
*/
|
|
31
|
+
async function cssToNativeLocator(css) {
|
|
32
|
+
try {
|
|
33
|
+
const transformCss = await getTransformCss();
|
|
34
|
+
return transformCss(css);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
throw mapCssError(err, css);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function mapCssError(err, css) {
|
|
41
|
+
if (isPackageError(err, 'InvalidSelectorError')) {
|
|
42
|
+
return new driver_1.errors.InvalidSelectorError(`Invalid CSS selector '${css}'`, err);
|
|
43
|
+
}
|
|
44
|
+
if (isPackageError(err, 'UnsupportedSelectorError')) {
|
|
45
|
+
return new driver_1.errors.InvalidSelectorError(`Unsupported CSS selector '${css}'`, err);
|
|
46
|
+
}
|
|
47
|
+
if (err instanceof Error) {
|
|
48
|
+
return err;
|
|
49
|
+
}
|
|
50
|
+
return new Error(String(err));
|
|
51
|
+
}
|
|
52
|
+
function isPackageError(err, name) {
|
|
53
|
+
return err instanceof Error && err.name === name;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/css/index.ts"],"names":[],"mappings":";;;AA8BA,gDAOC;AArCD,0CAAqC;AACrC,oCAAiC;AACjC,2CAA8E;AAC9E,qCAA0C;AAC1C,+DAAwD;AAGxD,yCAAqD;AAA7C,qHAAA,wBAAwB,OAAA;AAEhC,MAAM,QAAQ,GAAG;IACf,CAAC,mCAAuB,CAAC,EAAE,IAAI,uCAAiB,CAAC,oCAAwB,CAAC;CAC3E,CAAC;AAEF,MAAM,eAAe,GAAG,IAAA,eAAO,EAAC,KAAK,UAAU,gBAAgB;IAC7D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;IAC1D,OAAO,GAAG,CAAC,oBAAoB,CAAC;QAC9B,MAAM,EAAE,yBAAgB;QACxB,QAAQ;QACR,eAAe;YACb,OAAO,mCAAuB,CAAC;QACjC,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH;;;;;GAKG;AACI,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAClD,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,eAAe,EAAE,CAAC;QAC7C,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAY,EAAE,GAAW;IAC5C,IAAI,cAAc,CAAC,GAAG,EAAE,sBAAsB,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,eAAM,CAAC,oBAAoB,CAAC,yBAAyB,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,cAAc,CAAC,GAAG,EAAE,0BAA0B,CAAC,EAAE,CAAC;QACpD,OAAO,IAAI,eAAM,CAAC,oBAAoB,CAAC,6BAA6B,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,cAAc,CAAC,GAAY,EAAE,IAAY;IAChD,OAAO,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../lib/css/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAEnE,eAAO,MAAM,gBAAgB,EAAE,eAa9B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ATTRIBUTE_SCHEMA = void 0;
|
|
4
|
+
exports.ATTRIBUTE_SCHEMA = {
|
|
5
|
+
attributes: {
|
|
6
|
+
visible: { type: 'boolean' },
|
|
7
|
+
accessible: { type: 'boolean' },
|
|
8
|
+
'accessibility-container': { type: 'boolean' },
|
|
9
|
+
enabled: { type: 'boolean' },
|
|
10
|
+
index: { type: 'numeric', aliases: ['nth-child'] },
|
|
11
|
+
label: { type: 'string' },
|
|
12
|
+
name: { type: 'string', aliases: ['id'] },
|
|
13
|
+
value: { type: 'string' },
|
|
14
|
+
type: { type: 'string' },
|
|
15
|
+
},
|
|
16
|
+
booleanFormat: 'zero-one',
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../lib/css/schema.ts"],"names":[],"mappings":";;;AAEa,QAAA,gBAAgB,GAAoB;IAC/C,UAAU,EAAE;QACV,OAAO,EAAE,EAAC,IAAI,EAAE,SAAS,EAAC;QAC1B,UAAU,EAAE,EAAC,IAAI,EAAE,SAAS,EAAC;QAC7B,yBAAyB,EAAE,EAAC,IAAI,EAAE,SAAS,EAAC;QAC5C,OAAO,EAAE,EAAC,IAAI,EAAE,SAAS,EAAC;QAC1B,KAAK,EAAE,EAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,WAAW,CAAC,EAAC;QAChD,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAC;QACvB,IAAI,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAC;QACvC,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAC;QACvB,IAAI,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAC;KACvB;IACD,aAAa,EAAE,UAAU;CAC1B,CAAC"}
|
package/lib/commands/find.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {isEmpty} from '../utils';
|
|
2
|
-
import {
|
|
2
|
+
import {cssToNativeLocator, WDA_CLASS_CHAIN_STRATEGY} from '../css';
|
|
3
3
|
import {errors} from 'appium/driver';
|
|
4
4
|
import {util} from 'appium/support';
|
|
5
5
|
import type {Element, AppiumLogger} from '@appium/types';
|
|
@@ -92,8 +92,7 @@ export async function findNativeElementOrElements(
|
|
|
92
92
|
} else if (strategy === '-ios class chain') {
|
|
93
93
|
strategy = WDA_CLASS_CHAIN_STRATEGY;
|
|
94
94
|
} else if (strategy === 'css selector') {
|
|
95
|
-
strategy =
|
|
96
|
-
selector = CssConverter.toIosClassChainSelector(selector);
|
|
95
|
+
({strategy, selector} = await cssToNativeLocator(selector));
|
|
97
96
|
}
|
|
98
97
|
|
|
99
98
|
if (strategy === 'class name') {
|
|
@@ -248,7 +247,6 @@ export async function getFirstVisibleChild(
|
|
|
248
247
|
|
|
249
248
|
const MAGIC_FIRST_VIS_CHILD_SEL = /\/\*\[@firstVisible\s*=\s*('|")true\1\]/;
|
|
250
249
|
const MAGIC_SCROLLABLE_SEL = /\/\/\*\[@scrollable\s*=\s*('|")true\1\]/;
|
|
251
|
-
const WDA_CLASS_CHAIN_STRATEGY = 'class chain';
|
|
252
250
|
|
|
253
251
|
function stripViewFromSelector(selector: string): string {
|
|
254
252
|
const keepView = [
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {errors} from 'appium/driver';
|
|
2
|
+
import {escapeRegExp, isEmpty} from '../utils';
|
|
3
|
+
import type {
|
|
4
|
+
ParsedAttribute,
|
|
5
|
+
ParsedRule,
|
|
6
|
+
ParsedSelector,
|
|
7
|
+
StrategyEmitter,
|
|
8
|
+
} from '@appium/css-locator-to-native';
|
|
9
|
+
|
|
10
|
+
const BOOLEAN_ATTRS = new Set(['visible', 'accessible', 'accessibility-container', 'enabled']);
|
|
11
|
+
|
|
12
|
+
const STRING_ATTRS = new Set(['label', 'name', 'value', 'type']);
|
|
13
|
+
|
|
14
|
+
/** Converts parsed CSS selectors into class chain strings. */
|
|
15
|
+
export class ClassChainEmitter implements StrategyEmitter {
|
|
16
|
+
readonly strategy: string;
|
|
17
|
+
|
|
18
|
+
constructor(strategy: string) {
|
|
19
|
+
this.strategy = strategy;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
emit(parsed: ParsedSelector): string {
|
|
23
|
+
return this.emitRule(parsed.rule);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private emitRule(rule: ParsedRule): string {
|
|
27
|
+
if (rule.classes.length) {
|
|
28
|
+
throw new errors.InvalidSelectorError(
|
|
29
|
+
`'${rule.classes.join('.')}' is not a valid class. Must be a single string ` +
|
|
30
|
+
`(e.g.: XCUIElementTypeWindow) without dots separating them`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let tagName = rule.tag ?? '';
|
|
35
|
+
if (tagName && tagName !== '*' && !tagName.toLowerCase().startsWith('xcuielementtype')) {
|
|
36
|
+
const capitalizedTagName = tagName.charAt(0).toUpperCase() + tagName.slice(1);
|
|
37
|
+
tagName = `XCUIElementType${capitalizedTagName}`;
|
|
38
|
+
}
|
|
39
|
+
let classChainSelector = tagName || '*';
|
|
40
|
+
|
|
41
|
+
const attrs: (string | {index: string} | undefined)[] = [];
|
|
42
|
+
if (rule.id) {
|
|
43
|
+
attrs.push(`name == "${rule.id}"`);
|
|
44
|
+
}
|
|
45
|
+
for (const attr of rule.attributes) {
|
|
46
|
+
attrs.push(this.formatEntity(attr));
|
|
47
|
+
}
|
|
48
|
+
for (const pseudo of rule.pseudos) {
|
|
49
|
+
attrs.push(this.formatEntity(pseudo));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const nonIndexAttrs = attrs.filter((attr) => typeof attr === 'string') as string[];
|
|
53
|
+
if (!isEmpty(nonIndexAttrs)) {
|
|
54
|
+
classChainSelector += `[\`${nonIndexAttrs.join(' AND ')}\`]`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const indexAttr = attrs.find(
|
|
58
|
+
(attr) =>
|
|
59
|
+
typeof attr === 'object' && attr !== null && (attr as {index: string}).index !== undefined,
|
|
60
|
+
) as {index: string} | undefined;
|
|
61
|
+
if (indexAttr) {
|
|
62
|
+
classChainSelector += `[${indexAttr.index}]`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (rule.nested) {
|
|
66
|
+
classChainSelector += `/${this.emitRule(rule.nested)}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return rule.combinator === 'child' ? classChainSelector : `**/${classChainSelector}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private formatEntity(attr: ParsedAttribute): string | {index: string} | undefined {
|
|
73
|
+
if (attr.name === 'index') {
|
|
74
|
+
return this.formatIndex(attr.value);
|
|
75
|
+
}
|
|
76
|
+
if (BOOLEAN_ATTRS.has(attr.name)) {
|
|
77
|
+
return this.formatBooleanAttr(attr.name, attr.value);
|
|
78
|
+
}
|
|
79
|
+
if (STRING_ATTRS.has(attr.name)) {
|
|
80
|
+
return this.formatStringAttr(attr);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private formatIndex(value: string | undefined): {index: string} {
|
|
85
|
+
return {index: value ?? ''};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private formatBooleanAttr(name: string, value: string | undefined): string {
|
|
89
|
+
return `${this.toCamelCase(name)} == ${value ?? '1'}`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private formatStringAttr(attr: ParsedAttribute): string {
|
|
93
|
+
const attrName = this.toCamelCase(attr.name);
|
|
94
|
+
const value = attr.value ?? '';
|
|
95
|
+
if (value === '') {
|
|
96
|
+
return `[${attrName} LIKE ${value}]`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
switch (attr.operator) {
|
|
100
|
+
case '=':
|
|
101
|
+
return `${attrName} == "${value}"`;
|
|
102
|
+
case '*=':
|
|
103
|
+
return `${attrName} MATCHES "${escapeRegExp(value)}"`;
|
|
104
|
+
case '^=':
|
|
105
|
+
return `${attrName} BEGINSWITH "${value}"`;
|
|
106
|
+
case '$=':
|
|
107
|
+
return `${attrName} ENDSWITH "${value}"`;
|
|
108
|
+
case '~=':
|
|
109
|
+
return `${attrName} CONTAINS "${value}"`;
|
|
110
|
+
default:
|
|
111
|
+
return `${attrName} == "${value}"`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private toCamelCase(str: string): string {
|
|
116
|
+
const tokens = str
|
|
117
|
+
.split('-')
|
|
118
|
+
.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase());
|
|
119
|
+
const out = tokens.join('');
|
|
120
|
+
return out.charAt(0).toLowerCase() + out.slice(1);
|
|
121
|
+
}
|
|
122
|
+
}
|
package/lib/css/index.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {errors} from 'appium/driver';
|
|
2
|
+
import {memoize} from '../utils';
|
|
3
|
+
import {CLASS_CHAIN_EMITTER_KEY, WDA_CLASS_CHAIN_STRATEGY} from './constants';
|
|
4
|
+
import {ATTRIBUTE_SCHEMA} from './schema';
|
|
5
|
+
import {ClassChainEmitter} from './class-chain-emitter';
|
|
6
|
+
import type {CssTransformer, NativeLocator, StrategyKey} from '@appium/css-locator-to-native';
|
|
7
|
+
|
|
8
|
+
export {WDA_CLASS_CHAIN_STRATEGY} from './constants';
|
|
9
|
+
|
|
10
|
+
const emitters = {
|
|
11
|
+
[CLASS_CHAIN_EMITTER_KEY]: new ClassChainEmitter(WDA_CLASS_CHAIN_STRATEGY),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const getTransformCss = memoize(async function loadTransformCss(): Promise<CssTransformer> {
|
|
15
|
+
const mod = await import('@appium/css-locator-to-native');
|
|
16
|
+
return mod.createCssTransformer({
|
|
17
|
+
schema: ATTRIBUTE_SCHEMA,
|
|
18
|
+
emitters,
|
|
19
|
+
resolveStrategy(): StrategyKey<typeof emitters> {
|
|
20
|
+
return CLASS_CHAIN_EMITTER_KEY;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Converts a CSS selector string into a native locator for the resolved strategy.
|
|
27
|
+
*
|
|
28
|
+
* @param css - CSS selector to transform
|
|
29
|
+
* @returns Native locator strategy name and selector string
|
|
30
|
+
*/
|
|
31
|
+
export async function cssToNativeLocator(css: string): Promise<NativeLocator> {
|
|
32
|
+
try {
|
|
33
|
+
const transformCss = await getTransformCss();
|
|
34
|
+
return transformCss(css);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
throw mapCssError(err, css);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function mapCssError(err: unknown, css: string): Error {
|
|
41
|
+
if (isPackageError(err, 'InvalidSelectorError')) {
|
|
42
|
+
return new errors.InvalidSelectorError(`Invalid CSS selector '${css}'`, err);
|
|
43
|
+
}
|
|
44
|
+
if (isPackageError(err, 'UnsupportedSelectorError')) {
|
|
45
|
+
return new errors.InvalidSelectorError(`Unsupported CSS selector '${css}'`, err);
|
|
46
|
+
}
|
|
47
|
+
if (err instanceof Error) {
|
|
48
|
+
return err;
|
|
49
|
+
}
|
|
50
|
+
return new Error(String(err));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function isPackageError(err: unknown, name: string): err is Error {
|
|
54
|
+
return err instanceof Error && err.name === name;
|
|
55
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type {AttributeSchema} from '@appium/css-locator-to-native';
|
|
2
|
+
|
|
3
|
+
export const ATTRIBUTE_SCHEMA: AttributeSchema = {
|
|
4
|
+
attributes: {
|
|
5
|
+
visible: {type: 'boolean'},
|
|
6
|
+
accessible: {type: 'boolean'},
|
|
7
|
+
'accessibility-container': {type: 'boolean'},
|
|
8
|
+
enabled: {type: 'boolean'},
|
|
9
|
+
index: {type: 'numeric', aliases: ['nth-child']},
|
|
10
|
+
label: {type: 'string'},
|
|
11
|
+
name: {type: 'string', aliases: ['id']},
|
|
12
|
+
value: {type: 'string'},
|
|
13
|
+
type: {type: 'string'},
|
|
14
|
+
},
|
|
15
|
+
booleanFormat: 'zero-one',
|
|
16
|
+
};
|