appium-uiautomator2-driver 7.2.3 → 7.4.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/CHANGELOG.md +12 -0
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +1 -5
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +2 -6
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/gestures.d.ts.map +1 -1
- package/build/lib/commands/gestures.js +2 -6
- package/build/lib/commands/gestures.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +0 -8
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/screenshot.js +7 -8
- package/build/lib/commands/screenshot.js.map +1 -1
- package/build/lib/commands/types.d.ts +1 -1
- package/build/lib/commands/types.d.ts.map +1 -1
- package/build/lib/css-converter.js +9 -12
- package/build/lib/css-converter.js.map +1 -1
- package/build/lib/driver.d.ts +31 -30
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +72 -43
- package/build/lib/driver.js.map +1 -1
- package/build/lib/uiautomator2.d.ts.map +1 -1
- package/build/lib/uiautomator2.js +1 -2
- package/build/lib/uiautomator2.js.map +1 -1
- package/build/lib/{helpers.d.ts → utils/app.d.ts} +1 -1
- package/build/lib/utils/app.d.ts.map +1 -0
- package/build/lib/{helpers.js → utils/app.js} +1 -1
- package/build/lib/utils/app.js.map +1 -0
- package/build/lib/utils/index.d.ts +5 -0
- package/build/lib/utils/index.d.ts.map +1 -0
- package/build/lib/utils/index.js +21 -0
- package/build/lib/utils/index.js.map +1 -0
- package/build/lib/utils/lang.d.ts +15 -0
- package/build/lib/utils/lang.d.ts.map +1 -0
- package/build/lib/utils/lang.js +37 -0
- package/build/lib/utils/lang.js.map +1 -0
- package/build/lib/utils/memoize.d.ts +11 -0
- package/build/lib/utils/memoize.d.ts.map +1 -0
- package/build/lib/utils/memoize.js +26 -0
- package/build/lib/utils/memoize.js.map +1 -0
- package/build/lib/utils/object.d.ts +6 -0
- package/build/lib/utils/object.d.ts.map +1 -0
- package/build/lib/utils/object.js +15 -0
- package/build/lib/utils/object.js.map +1 -0
- package/lib/commands/app-management.ts +1 -2
- package/lib/commands/element.ts +2 -3
- package/lib/commands/gestures.ts +2 -3
- package/lib/commands/keyboard.ts +0 -5
- package/lib/commands/screenshot.ts +7 -7
- package/lib/commands/types.ts +1 -1
- package/lib/constraints.ts +1 -1
- package/lib/css-converter.ts +9 -9
- package/lib/driver.ts +124 -91
- package/lib/execute-method-map.ts +1 -1
- package/lib/uiautomator2.ts +5 -6
- package/lib/utils/index.ts +4 -0
- package/lib/utils/lang.ts +34 -0
- package/lib/utils/memoize.ts +26 -0
- package/lib/utils/object.ts +14 -0
- package/npm-shrinkwrap.json +95 -29
- package/package.json +7 -5
- package/build/lib/helpers.d.ts.map +0 -1
- package/build/lib/helpers.js.map +0 -1
- /package/lib/{helpers.ts → utils/app.ts} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// TODO(appium server 3.4.1+): Replace local `isEmpty` / `escapeRegExp` with imports from `appium/support`
|
|
3
|
+
// once this driver declares that minimum server version.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.isEmpty = isEmpty;
|
|
6
|
+
exports.escapeRegExp = escapeRegExp;
|
|
7
|
+
/**
|
|
8
|
+
* Returns true when the value has no elements/properties.
|
|
9
|
+
*
|
|
10
|
+
* @param value - Value to check
|
|
11
|
+
* @returns `true` if the value is empty
|
|
12
|
+
*/
|
|
13
|
+
function isEmpty(value) {
|
|
14
|
+
if (value == null) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (typeof value === 'string' || Array.isArray(value) || Buffer.isBuffer(value)) {
|
|
18
|
+
return value.length === 0;
|
|
19
|
+
}
|
|
20
|
+
if (value instanceof Map || value instanceof Set) {
|
|
21
|
+
return value.size === 0;
|
|
22
|
+
}
|
|
23
|
+
if (typeof value === 'object' || typeof value === 'function') {
|
|
24
|
+
return Object.keys(value).length === 0;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Escapes RegExp special characters in a string.
|
|
30
|
+
*
|
|
31
|
+
* @param value - Input string
|
|
32
|
+
* @returns Escaped string safe for RegExp source
|
|
33
|
+
*/
|
|
34
|
+
function escapeRegExp(value) {
|
|
35
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lang.js","sourceRoot":"","sources":["../../../lib/utils/lang.ts"],"names":[],"mappings":";AAAA,0GAA0G;AAC1G,yDAAyD;;AAQzD,0BAcC;AAQD,oCAEC;AA9BD;;;;;GAKG;AACH,SAAgB,OAAO,CAAC,KAAc;IACpC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAChF,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,KAAK,YAAY,GAAG,IAAI,KAAK,YAAY,GAAG,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAC7D,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a memoized version of a function.
|
|
3
|
+
*
|
|
4
|
+
* @param fn - Function to memoize
|
|
5
|
+
* @param resolver - Optional cache key resolver. If omitted, the first argument is used as the cache key.
|
|
6
|
+
* @returns Memoized function with a mutable `.cache` map (compatible with lodash-style cache resets in tests).
|
|
7
|
+
*/
|
|
8
|
+
export declare function memoize<Fn extends (...args: any[]) => any>(fn: Fn, resolver?: (...args: Parameters<Fn>) => unknown): Fn & {
|
|
9
|
+
cache: Map<unknown, ReturnType<Fn>>;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=memoize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoize.d.ts","sourceRoot":"","sources":["../../../lib/utils/memoize.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,EAAE,EAAE,EAAE,EACN,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,OAAO,GAC9C,EAAE,GAAG;IAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;CAAC,CAY5C"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// TODO(appium server 3.4.1+): Replace local `memoize` with imports from `appium/support`
|
|
3
|
+
// once this driver declares that minimum server version.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.memoize = memoize;
|
|
6
|
+
/**
|
|
7
|
+
* Creates a memoized version of a function.
|
|
8
|
+
*
|
|
9
|
+
* @param fn - Function to memoize
|
|
10
|
+
* @param resolver - Optional cache key resolver. If omitted, the first argument is used as the cache key.
|
|
11
|
+
* @returns Memoized function with a mutable `.cache` map (compatible with lodash-style cache resets in tests).
|
|
12
|
+
*/
|
|
13
|
+
function memoize(fn, resolver) {
|
|
14
|
+
const memoizedFn = function (...args) {
|
|
15
|
+
const key = resolver ? resolver.apply(this, args) : args[0];
|
|
16
|
+
if (memoizedFn.cache.has(key)) {
|
|
17
|
+
return memoizedFn.cache.get(key);
|
|
18
|
+
}
|
|
19
|
+
const result = fn.apply(this, args);
|
|
20
|
+
memoizedFn.cache.set(key, result);
|
|
21
|
+
return result;
|
|
22
|
+
};
|
|
23
|
+
memoizedFn.cache = new Map();
|
|
24
|
+
return memoizedFn;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=memoize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoize.js","sourceRoot":"","sources":["../../../lib/utils/memoize.ts"],"names":[],"mappings":";AAAA,yFAAyF;AACzF,yDAAyD;;AASzD,0BAeC;AAtBD;;;;;;GAMG;AACH,SAAgB,OAAO,CACrB,EAAM,EACN,QAA+C;IAE/C,MAAM,UAAU,GAAG,UAAyB,GAAG,IAAoB;QACjE,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAmB,CAAC;QACrD,CAAC;QACD,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACpC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAClC,OAAO,MAAM,CAAC;IAChB,CAA0D,CAAC;IAC3D,UAAU,CAAC,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IACtD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assigns own enumerable properties of `source` onto `target` only where `target[key] === undefined`
|
|
3
|
+
* (lodash `defaults` semantics).
|
|
4
|
+
*/
|
|
5
|
+
export declare function assignDefaults<T extends Record<string, unknown>>(target: T, source: Record<string, unknown>): void;
|
|
6
|
+
//# sourceMappingURL=object.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../../../lib/utils/object.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9D,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,IAAI,CAMN"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assignDefaults = assignDefaults;
|
|
4
|
+
/**
|
|
5
|
+
* Assigns own enumerable properties of `source` onto `target` only where `target[key] === undefined`
|
|
6
|
+
* (lodash `defaults` semantics).
|
|
7
|
+
*/
|
|
8
|
+
function assignDefaults(target, source) {
|
|
9
|
+
for (const key of Object.keys(source)) {
|
|
10
|
+
if (target[key] === undefined) {
|
|
11
|
+
target[key] = source[key];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object.js","sourceRoot":"","sources":["../../../lib/utils/object.ts"],"names":[],"mappings":";;AAIA,wCASC;AAbD;;;GAGG;AACH,SAAgB,cAAc,CAC5B,MAAS,EACT,MAA+B;IAE/B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAkC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
1
|
import {errors} from 'appium/driver';
|
|
3
2
|
import {APK_EXTENSION} from '../extensions';
|
|
4
3
|
import type {AndroidUiautomator2Driver} from '../driver';
|
|
@@ -15,7 +14,7 @@ export async function mobileInstallMultipleApks(
|
|
|
15
14
|
apks: string[],
|
|
16
15
|
options?: InstallOptions,
|
|
17
16
|
): Promise<void> {
|
|
18
|
-
if (!
|
|
17
|
+
if (!Array.isArray(apks) || apks.length === 0) {
|
|
19
18
|
throw new errors.InvalidArgumentError('No apks are given to install');
|
|
20
19
|
}
|
|
21
20
|
const configuredApks = await Promise.all(
|
package/lib/commands/element.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {PROTOCOLS} from 'appium/driver';
|
|
2
|
-
import _ from 'lodash';
|
|
3
2
|
import type {DoSetElementValueOpts} from 'appium-android-driver';
|
|
4
3
|
import type {Element as AppiumElement, Position, Rect, Size} from '@appium/types';
|
|
5
4
|
import type {AndroidUiautomator2Driver} from '../driver';
|
|
@@ -130,7 +129,7 @@ export async function setValueImmediate(
|
|
|
130
129
|
): Promise<void> {
|
|
131
130
|
await this.uiautomator2.jwproxy.command(`/element/${elementId}/value`, 'POST', {
|
|
132
131
|
elementId,
|
|
133
|
-
text:
|
|
132
|
+
text: Array.isArray(keys) ? keys.join('') : keys,
|
|
134
133
|
replace: false,
|
|
135
134
|
});
|
|
136
135
|
}
|
|
@@ -215,5 +214,5 @@ export async function mobileReplaceElementValue(
|
|
|
215
214
|
}
|
|
216
215
|
|
|
217
216
|
function toBool(value: any): boolean {
|
|
218
|
-
return
|
|
217
|
+
return typeof value === 'string' ? value.toLowerCase() === 'true' : !!value;
|
|
219
218
|
}
|
package/lib/commands/gestures.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {errors} from 'appium/driver';
|
|
2
2
|
import {util} from 'appium/support';
|
|
3
|
-
import _ from 'lodash';
|
|
4
3
|
import type {Element as AppiumElement, Position} from '@appium/types';
|
|
5
4
|
import type {RelativeRect} from './types';
|
|
6
5
|
import type {AndroidUiautomator2Driver} from '../driver';
|
|
@@ -288,7 +287,7 @@ function toOrigin(element?: AppiumElement | string): AppiumElement | undefined {
|
|
|
288
287
|
}
|
|
289
288
|
|
|
290
289
|
function toPoint(x?: number, y?: number): Partial<Position> | undefined {
|
|
291
|
-
return
|
|
290
|
+
return Number.isFinite(x) && Number.isFinite(y) ? {x, y} : undefined;
|
|
292
291
|
}
|
|
293
292
|
|
|
294
293
|
function toRect(
|
|
@@ -297,7 +296,7 @@ function toRect(
|
|
|
297
296
|
width?: number,
|
|
298
297
|
height?: number,
|
|
299
298
|
): RelativeRect | undefined {
|
|
300
|
-
return [left, top, width, height].some((v) => !
|
|
299
|
+
return [left, top, width, height].some((v) => !Number.isFinite(v))
|
|
301
300
|
? undefined
|
|
302
301
|
: ({left, top, width, height} as RelativeRect);
|
|
303
302
|
}
|
package/lib/commands/keyboard.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import {errors} from 'appium/driver';
|
|
2
|
-
import _ from 'lodash';
|
|
3
1
|
import type {AndroidUiautomator2Driver} from '../driver';
|
|
4
2
|
import type {SendKeysOpts} from 'appium-android-driver';
|
|
5
3
|
|
|
@@ -81,9 +79,6 @@ export async function mobileType(
|
|
|
81
79
|
this: AndroidUiautomator2Driver,
|
|
82
80
|
text: string | number | boolean,
|
|
83
81
|
): Promise<boolean> {
|
|
84
|
-
if (_.isUndefined(text)) {
|
|
85
|
-
throw new errors.InvalidArgumentError(`The 'text' argument is mandatory`);
|
|
86
|
-
}
|
|
87
82
|
return await this.settingsApp.typeUnicode(String(text));
|
|
88
83
|
}
|
|
89
84
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
1
|
import {imageUtil} from 'appium/support';
|
|
2
|
+
import {isEmpty} from '../utils';
|
|
3
3
|
import type {AndroidUiautomator2Driver} from '../driver';
|
|
4
4
|
import type {Screenshot} from './types';
|
|
5
5
|
import type {StringRecord} from '@appium/types';
|
|
@@ -94,7 +94,7 @@ export async function mobileScreenshots(
|
|
|
94
94
|
): Promise<StringRecord<Screenshot>> {
|
|
95
95
|
const displaysInfo = await this.adb.shell(['dumpsys', 'SurfaceFlinger', '--display-id']);
|
|
96
96
|
const infos = parseSurfaceFlingerDisplays(displaysInfo);
|
|
97
|
-
if (
|
|
97
|
+
if (isEmpty(infos)) {
|
|
98
98
|
this.log.debug(displaysInfo);
|
|
99
99
|
throw new Error('Cannot determine the information about connected Android displays');
|
|
100
100
|
}
|
|
@@ -104,7 +104,7 @@ export async function mobileScreenshots(
|
|
|
104
104
|
(await this.adb.takeScreenshot(dispId)).toString('base64');
|
|
105
105
|
|
|
106
106
|
const displayIdStr: string | null =
|
|
107
|
-
|
|
107
|
+
displayId == null || displayId === '' ? null : String(displayId);
|
|
108
108
|
|
|
109
109
|
if (displayIdStr) {
|
|
110
110
|
if (!infos[displayIdStr]) {
|
|
@@ -121,13 +121,13 @@ export async function mobileScreenshots(
|
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
const allInfos =
|
|
124
|
+
const allInfos = Object.values(infos).filter(
|
|
125
125
|
(info): info is Partial<Screenshot> & {id: string} => !!info?.id,
|
|
126
126
|
);
|
|
127
127
|
const screenshots = await Promise.all(allInfos.map((info) => toB64Screenshot(info.id)));
|
|
128
|
-
for (
|
|
129
|
-
[
|
|
130
|
-
|
|
128
|
+
for (let i = 0; i < allInfos.length; i++) {
|
|
129
|
+
const info = allInfos[i];
|
|
130
|
+
const payload = screenshots[i];
|
|
131
131
|
if (info && payload) {
|
|
132
132
|
info.payload = payload;
|
|
133
133
|
}
|
package/lib/commands/types.ts
CHANGED
package/lib/constraints.ts
CHANGED
package/lib/css-converter.ts
CHANGED
|
@@ -8,9 +8,9 @@ import type {
|
|
|
8
8
|
AstSelector,
|
|
9
9
|
AstTagName,
|
|
10
10
|
} from 'css-selector-parser';
|
|
11
|
-
import _ from 'lodash';
|
|
12
11
|
import {errors} from 'appium/driver';
|
|
13
12
|
import {log} from './logger';
|
|
13
|
+
import {escapeRegExp, isEmpty} from './utils';
|
|
14
14
|
|
|
15
15
|
const parseCssSelector = createParser({
|
|
16
16
|
syntax: {
|
|
@@ -100,7 +100,7 @@ export class CssConverter {
|
|
|
100
100
|
private parseAttr(cssAttr: AstAttribute): string {
|
|
101
101
|
const attrValueNode = cssAttr.value as {value?: string} | undefined;
|
|
102
102
|
const attrValue = attrValueNode?.value;
|
|
103
|
-
if (
|
|
103
|
+
if (typeof attrValue !== 'string' && !isEmpty(attrValue)) {
|
|
104
104
|
throw new Error(
|
|
105
105
|
`'${cssAttr.name}=${attrValue}' is an invalid attribute. Only 'string' and empty attribute types are supported. Found '${attrValue}'`,
|
|
106
106
|
);
|
|
@@ -136,14 +136,14 @@ export class CssConverter {
|
|
|
136
136
|
if (['description', 'text'].includes(attrName)) {
|
|
137
137
|
return `.${methodName}Contains("${value}")`;
|
|
138
138
|
}
|
|
139
|
-
return `.${methodName}Matches("${
|
|
139
|
+
return `.${methodName}Matches("${escapeRegExp(value)}")`;
|
|
140
140
|
case '^=':
|
|
141
141
|
if (['description', 'text'].includes(attrName)) {
|
|
142
142
|
return `.${methodName}StartsWith("${value}")`;
|
|
143
143
|
}
|
|
144
|
-
return `.${methodName}Matches("^${
|
|
144
|
+
return `.${methodName}Matches("^${escapeRegExp(value)}")`;
|
|
145
145
|
case '$=':
|
|
146
|
-
return `.${methodName}Matches("${
|
|
146
|
+
return `.${methodName}Matches("${escapeRegExp(value)}$")`;
|
|
147
147
|
case '~=':
|
|
148
148
|
return `.${methodName}Matches("${getWordMatcherRegex(value)}")`;
|
|
149
149
|
default:
|
|
@@ -155,7 +155,7 @@ export class CssConverter {
|
|
|
155
155
|
|
|
156
156
|
private parsePseudo(cssPseudo: AstPseudoClass): string | undefined {
|
|
157
157
|
const argValue = (cssPseudo.argument as {value?: string} | undefined)?.value;
|
|
158
|
-
if (
|
|
158
|
+
if (typeof argValue !== 'string' && !isEmpty(argValue)) {
|
|
159
159
|
throw new Error(
|
|
160
160
|
`'${cssPseudo.name}=${argValue}'. Unsupported css pseudo class value: '${argValue}'. Only 'string' type or empty is supported.`,
|
|
161
161
|
);
|
|
@@ -226,7 +226,7 @@ export class CssConverter {
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
private parseCssObject(css: AstSelector): string {
|
|
229
|
-
if (!
|
|
229
|
+
if (!isEmpty(css.rules)) {
|
|
230
230
|
return this.parseCssRule(css.rules[0] as AstRule);
|
|
231
231
|
}
|
|
232
232
|
|
|
@@ -247,7 +247,7 @@ function toSnakeCase(str?: string | null): string {
|
|
|
247
247
|
|
|
248
248
|
function requireBoolean(css: AstAttribute | AstPseudoClass): 'true' | 'false' {
|
|
249
249
|
const rawValue = (css as any).value?.value ?? (css as any).argument?.value;
|
|
250
|
-
const value =
|
|
250
|
+
const value = String(rawValue ?? 'true').toLowerCase();
|
|
251
251
|
if (value === 'true') {
|
|
252
252
|
return 'true';
|
|
253
253
|
}
|
|
@@ -275,5 +275,5 @@ function requireEntityName(cssEntity: AstAttribute | AstPseudoClass): string {
|
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
function getWordMatcherRegex(word: string): string {
|
|
278
|
-
return `\\b(\\w*${
|
|
278
|
+
return `\\b(\\w*${escapeRegExp(word)}\\w*)\\b`;
|
|
279
279
|
}
|