@applitools/driver 1.11.8 → 1.11.10
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/dist/element.js +70 -68
- package/dist/helper-android.js +0 -4
- package/package.json +2 -2
- package/types/element.d.ts +8 -6
- package/types/spec-driver.d.ts +2 -2
package/dist/element.js
CHANGED
|
@@ -96,8 +96,8 @@ class Element {
|
|
|
96
96
|
}
|
|
97
97
|
async contains(innerElement) {
|
|
98
98
|
const contains = await this.withRefresh(async () => {
|
|
99
|
-
var _a, _b
|
|
100
|
-
var
|
|
99
|
+
var _a, _b;
|
|
100
|
+
var _c;
|
|
101
101
|
innerElement = innerElement instanceof Element ? innerElement.target : innerElement;
|
|
102
102
|
if (this.driver.isWeb) {
|
|
103
103
|
this._logger.log('Checking if web element with selector', this.selector, 'contains element', innerElement);
|
|
@@ -111,19 +111,10 @@ class Element {
|
|
|
111
111
|
if (await this.equals(innerElement))
|
|
112
112
|
return false;
|
|
113
113
|
// if the inner element region is contained in this element region, then it then could be assumed that the inner element is contained in this element
|
|
114
|
-
|
|
115
|
-
if (!contentRegion || !this.driver.isAndroid) {
|
|
116
|
-
const nativeContentRegion = await this.getContentSizeFromAttribute();
|
|
117
|
-
contentRegion = {
|
|
118
|
-
x: nativeContentRegion.x,
|
|
119
|
-
y: nativeContentRegion.y,
|
|
120
|
-
width: Math.max((_c = contentRegion === null || contentRegion === void 0 ? void 0 : contentRegion.width) !== null && _c !== void 0 ? _c : 0, nativeContentRegion.width),
|
|
121
|
-
height: Math.max((_d = contentRegion === null || contentRegion === void 0 ? void 0 : contentRegion.height) !== null && _d !== void 0 ? _d : 0, nativeContentRegion.height),
|
|
122
|
-
};
|
|
123
|
-
}
|
|
114
|
+
const contentRegion = await this.getContentRegion();
|
|
124
115
|
const innerRegion = await this._spec.getElementRegion(this.driver.target, innerElement);
|
|
125
116
|
const contains = utils.geometry.contains(contentRegion, innerRegion);
|
|
126
|
-
(
|
|
117
|
+
(_b = (_c = this._state).containedElements) !== null && _b !== void 0 ? _b : (_c.containedElements = new Map());
|
|
127
118
|
this._state.containedElements.set(innerElement, contains);
|
|
128
119
|
return contains;
|
|
129
120
|
}
|
|
@@ -178,44 +169,72 @@ class Element {
|
|
|
178
169
|
this._logger.log('Extracted client region', region);
|
|
179
170
|
return region;
|
|
180
171
|
}
|
|
181
|
-
async
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
172
|
+
async getContentRegion(options = {}) {
|
|
173
|
+
var _a, _b, _c;
|
|
174
|
+
if (!this.driver.isNative)
|
|
175
|
+
return;
|
|
176
|
+
this._logger.log('Extracting content region of native element with selector', this.selector);
|
|
177
|
+
let contentRegion = await ((_a = this.driver.helper) === null || _a === void 0 ? void 0 : _a.getContentRegion(this, options));
|
|
178
|
+
this._logger.log('Extracted content region using helper library', contentRegion);
|
|
179
|
+
if (!contentRegion || !this.driver.isAndroid) {
|
|
180
|
+
let attrContentRegion;
|
|
181
|
+
try {
|
|
182
|
+
const size = JSON.parse(await this.getAttribute('contentSize'));
|
|
183
|
+
attrContentRegion = {
|
|
184
|
+
x: size.left,
|
|
185
|
+
y: size.top,
|
|
186
|
+
width: size.width,
|
|
187
|
+
height: this.driver.isIOS
|
|
188
|
+
? Math.max(size.height, size.scrollableOffset)
|
|
189
|
+
: size.height + size.scrollableOffset,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
this._logger.warn(`Unable to get the attribute 'contentSize' due to the following error: '${err.message}'`);
|
|
194
|
+
}
|
|
195
|
+
this._logger.log('Extracted content region using attribute', attrContentRegion);
|
|
196
|
+
// ios workaround
|
|
197
|
+
if (!attrContentRegion && this.driver.isIOS) {
|
|
198
|
+
try {
|
|
199
|
+
const type = await this.getAttribute('type');
|
|
200
|
+
if (type !== 'XCUIElementTypeScrollView') {
|
|
201
|
+
const [child] = await this.driver.elements({
|
|
202
|
+
type: 'xpath',
|
|
203
|
+
selector: '//XCUIElementTypeScrollView[1]/*', // We cannot be sure that our element is the first one
|
|
204
|
+
});
|
|
205
|
+
if (child) {
|
|
206
|
+
const region = await this._spec.getElementRegion(this.driver.target, this.target);
|
|
207
|
+
const childRegion = await this._spec.getElementRegion(this.driver.target, child.target);
|
|
208
|
+
attrContentRegion = {
|
|
209
|
+
...region,
|
|
210
|
+
height: childRegion.y + childRegion.height - region.y,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
this._logger.warn(`Unable to calculate content region using iOS workaround due to the following error: '${err.message}'`);
|
|
217
|
+
}
|
|
218
|
+
this._logger.log('Extracted content region using iOS workaround', attrContentRegion);
|
|
219
|
+
}
|
|
220
|
+
if (attrContentRegion) {
|
|
221
|
+
contentRegion = {
|
|
222
|
+
x: attrContentRegion.x,
|
|
223
|
+
y: attrContentRegion.y,
|
|
224
|
+
width: Math.max((_b = contentRegion === null || contentRegion === void 0 ? void 0 : contentRegion.width) !== null && _b !== void 0 ? _b : 0, attrContentRegion.width),
|
|
225
|
+
height: Math.max((_c = contentRegion === null || contentRegion === void 0 ? void 0 : contentRegion.height) !== null && _c !== void 0 ? _c : 0, attrContentRegion.height),
|
|
209
226
|
};
|
|
210
227
|
}
|
|
211
228
|
}
|
|
229
|
+
return contentRegion !== null && contentRegion !== void 0 ? contentRegion : (await this._spec.getElementRegion(this.driver.target, this.target));
|
|
230
|
+
}
|
|
231
|
+
async getContentSizeIOS() {
|
|
212
232
|
return this._spec.getElementRegion(this.driver.target, this.target);
|
|
213
233
|
}
|
|
214
234
|
async getContentSize(options = {}) {
|
|
215
235
|
if (this._state.contentSize)
|
|
216
236
|
return this._state.contentSize;
|
|
217
237
|
const size = await this.withRefresh(async () => {
|
|
218
|
-
var _a, _b, _c;
|
|
219
238
|
if (this.driver.isWeb) {
|
|
220
239
|
this._logger.log('Extracting content size of web element with selector', this.selector);
|
|
221
240
|
return this.context.execute(snippets.getElementContentSize, [this]);
|
|
@@ -223,19 +242,7 @@ class Element {
|
|
|
223
242
|
else {
|
|
224
243
|
this._logger.log('Extracting content size of native element with selector', this.selector);
|
|
225
244
|
try {
|
|
226
|
-
|
|
227
|
-
this._logger.log('Extracted native content region using helper library', contentRegion);
|
|
228
|
-
// on android extraction of this argument will perform non-deterministic touch action, so it is better to avoid it
|
|
229
|
-
if (!contentRegion || !this.driver.isAndroid) {
|
|
230
|
-
const attrContentRegion = await this.getContentSizeFromAttribute();
|
|
231
|
-
this._logger.log('Extracted native content region using attribute', attrContentRegion);
|
|
232
|
-
contentRegion = {
|
|
233
|
-
x: attrContentRegion.x,
|
|
234
|
-
y: attrContentRegion.y,
|
|
235
|
-
width: Math.max((_b = contentRegion === null || contentRegion === void 0 ? void 0 : contentRegion.width) !== null && _b !== void 0 ? _b : 0, attrContentRegion.width),
|
|
236
|
-
height: Math.max((_c = contentRegion === null || contentRegion === void 0 ? void 0 : contentRegion.height) !== null && _c !== void 0 ? _c : 0, attrContentRegion.height),
|
|
237
|
-
};
|
|
238
|
-
}
|
|
245
|
+
const contentRegion = await this.getContentRegion(options);
|
|
239
246
|
this._state.contentSize = utils.geometry.size(contentRegion);
|
|
240
247
|
if (this.driver.isAndroid) {
|
|
241
248
|
this._state.contentSize = utils.geometry.scale(this._state.contentSize, 1 / this.driver.pixelRatio);
|
|
@@ -338,7 +345,7 @@ class Element {
|
|
|
338
345
|
}
|
|
339
346
|
else {
|
|
340
347
|
this._logger.log('Extracting text of native element with selector', this.selector);
|
|
341
|
-
return this._spec.getElementText(this.
|
|
348
|
+
return this._spec.getElementText(this.context.target, this.target);
|
|
342
349
|
}
|
|
343
350
|
});
|
|
344
351
|
this._logger.log('Extracted element text', text);
|
|
@@ -392,6 +399,7 @@ class Element {
|
|
|
392
399
|
async scrollTo(offset, options) {
|
|
393
400
|
return this.withRefresh(async () => {
|
|
394
401
|
var _a;
|
|
402
|
+
this._logger.log(`Scrolling to offset (${offset.x}, ${offset.y}) element with selector`, this.selector);
|
|
395
403
|
offset = utils.geometry.round({ x: Math.max(offset.x, 0), y: Math.max(offset.y, 0) });
|
|
396
404
|
if (this.driver.isWeb) {
|
|
397
405
|
let actualOffset = await this.context.execute(snippets.scrollTo, [this, offset]);
|
|
@@ -483,7 +491,7 @@ class Element {
|
|
|
483
491
|
xRemaining -= xRight - xLeft;
|
|
484
492
|
}
|
|
485
493
|
// vertical scrolling
|
|
486
|
-
const yPadding = Math.max(Math.floor(effectiveRegion.height * 0.
|
|
494
|
+
const yPadding = Math.max(Math.floor(effectiveRegion.height * 0.08), touchPadding + 3);
|
|
487
495
|
const xTrack = Math.floor(effectiveRegion.x + 5); // a little bit off left border
|
|
488
496
|
const yBottom = effectiveRegion.y + effectiveRegion.height - yPadding;
|
|
489
497
|
const yDirection = remainingOffset.y > 0 ? 'down' : 'up';
|
|
@@ -545,7 +553,7 @@ class Element {
|
|
|
545
553
|
}
|
|
546
554
|
}
|
|
547
555
|
else if (actions.length > 0) {
|
|
548
|
-
await this._spec.performAction(this.driver.target,
|
|
556
|
+
await this._spec.performAction(this.driver.target, actions.flat());
|
|
549
557
|
}
|
|
550
558
|
const actualScrollableRegion = await this.getClientRegion();
|
|
551
559
|
this._state.scrollOffset = utils.geometry.offsetNegative(requiredOffset, {
|
|
@@ -595,17 +603,13 @@ class Element {
|
|
|
595
603
|
}
|
|
596
604
|
async type(value) {
|
|
597
605
|
this._logger.log(`Typing text "${value}" in element with selector`, this.selector);
|
|
598
|
-
await this._spec.
|
|
606
|
+
await this._spec.setElementText(this.context.target, this.target, value);
|
|
599
607
|
}
|
|
600
608
|
async preserveState() {
|
|
601
|
-
if (this.driver.isNative)
|
|
602
|
-
return;
|
|
603
|
-
// TODO create single js snippet
|
|
604
609
|
const scrollOffset = await this.getScrollOffset();
|
|
605
|
-
const transforms =
|
|
606
|
-
this,
|
|
607
|
-
|
|
608
|
-
]);
|
|
610
|
+
const transforms = this.driver.isWeb
|
|
611
|
+
? await this.context.execute(snippets.getElementStyleProperties, [this, ['transform', '-webkit-transform']])
|
|
612
|
+
: null;
|
|
609
613
|
if (!utils.types.has(this._state, ['scrollOffset', 'transforms'])) {
|
|
610
614
|
this._state.scrollOffset = scrollOffset;
|
|
611
615
|
this._state.transforms = transforms;
|
|
@@ -613,8 +617,6 @@ class Element {
|
|
|
613
617
|
return { scrollOffset, transforms };
|
|
614
618
|
}
|
|
615
619
|
async restoreState(state = this._state) {
|
|
616
|
-
if (this.driver.isNative)
|
|
617
|
-
return;
|
|
618
620
|
if (state.scrollOffset)
|
|
619
621
|
await this.scrollTo(state.scrollOffset);
|
|
620
622
|
if (state.transforms)
|
package/dist/helper-android.js
CHANGED
|
@@ -75,9 +75,6 @@ class HelperAndroid {
|
|
|
75
75
|
return resourceId.split('/')[1];
|
|
76
76
|
}
|
|
77
77
|
async _command(command) {
|
|
78
|
-
// clean the input before passing value there could
|
|
79
|
-
// be a left over from previous async calls
|
|
80
|
-
await this._input.type('');
|
|
81
78
|
await this._input.type(command);
|
|
82
79
|
await this._input.click();
|
|
83
80
|
let text = await this._input.getText();
|
|
@@ -96,7 +93,6 @@ class HelperAndroid {
|
|
|
96
93
|
this._logger.warn(`Helper library didn't provide a response for async command (${command}) during ${timeout}ms`);
|
|
97
94
|
text = null;
|
|
98
95
|
}
|
|
99
|
-
await this._input.type('');
|
|
100
96
|
return text;
|
|
101
97
|
}
|
|
102
98
|
async getContentRegion(element, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/driver",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.10",
|
|
4
4
|
"description": "Applitools universal framework wrapper",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"applitools",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"@applitools/logger": "1.1.30",
|
|
91
|
-
"@applitools/snippets": "2.4.
|
|
91
|
+
"@applitools/snippets": "2.4.9",
|
|
92
92
|
"@applitools/utils": "1.3.16",
|
|
93
93
|
"semver": "7.3.7"
|
|
94
94
|
},
|
package/types/element.d.ts
CHANGED
|
@@ -41,12 +41,14 @@ export declare class Element<TDriver, TContext, TElement, TSelector> {
|
|
|
41
41
|
init(context: Context<TDriver, TContext, TElement, TSelector>): Promise<this>;
|
|
42
42
|
getRegion(): Promise<Region>;
|
|
43
43
|
getClientRegion(): Promise<Region>;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
getContentRegion(options?: {
|
|
45
|
+
lazyLoad?: {
|
|
46
|
+
scrollLength?: number;
|
|
47
|
+
waitingTime?: number;
|
|
48
|
+
maxAmountToScroll?: number;
|
|
49
|
+
};
|
|
50
|
+
}): Promise<Region>;
|
|
51
|
+
getContentSizeIOS(): Promise<Region>;
|
|
50
52
|
getContentSize(options?: {
|
|
51
53
|
lazyLoad?: {
|
|
52
54
|
scrollLength?: number;
|
package/types/spec-driver.d.ts
CHANGED
|
@@ -61,6 +61,8 @@ export interface SpecDriver<TDriver, TContext, TElement, TSelector> {
|
|
|
61
61
|
findElement(context: TContext, selector: TSelector, parent?: TElement): Promise<TElement | null>;
|
|
62
62
|
findElements(context: TContext, selector: TSelector, parent?: TElement): Promise<TElement[]>;
|
|
63
63
|
waitForSelector?(context: TContext, selector: TSelector, parent?: TElement, options?: WaitOptions): Promise<TElement | null>;
|
|
64
|
+
setElementText?(context: TContext, element: TElement, text: string): Promise<void>;
|
|
65
|
+
getElementText?(context: TContext, element: TElement): Promise<string>;
|
|
64
66
|
setWindowSize?(driver: TDriver, size: Size): Promise<void>;
|
|
65
67
|
getWindowSize?(driver: TDriver): Promise<Size>;
|
|
66
68
|
setViewportSize?(driver: TDriver, size: Size): Promise<void>;
|
|
@@ -72,7 +74,6 @@ export interface SpecDriver<TDriver, TContext, TElement, TSelector> {
|
|
|
72
74
|
getUrl(driver: TDriver): Promise<string>;
|
|
73
75
|
takeScreenshot(driver: TDriver): Promise<Buffer | string>;
|
|
74
76
|
click?(context: TContext, element: TElement | TSelector): Promise<void>;
|
|
75
|
-
type?(context: TContext, element: TElement, value: string): Promise<void>;
|
|
76
77
|
visit?(driver: TDriver, url: string): Promise<void>;
|
|
77
78
|
getOrientation?(driver: TDriver): Promise<ScreenOrientation>;
|
|
78
79
|
setOrientation?(driver: TDriver, orientation: ScreenOrientation): Promise<void>;
|
|
@@ -94,7 +95,6 @@ export interface SpecDriver<TDriver, TContext, TElement, TSelector> {
|
|
|
94
95
|
}>;
|
|
95
96
|
getElementRegion?(driver: TDriver, element: TElement): Promise<Region>;
|
|
96
97
|
getElementAttribute?(driver: TDriver, element: TElement, attr: string): Promise<string>;
|
|
97
|
-
getElementText?(driver: TDriver, element: TElement): Promise<string>;
|
|
98
98
|
performAction?(driver: TDriver, steps: any[]): Promise<void>;
|
|
99
99
|
getCurrentWorld?(driver: TDriver): Promise<string>;
|
|
100
100
|
getWorlds?(driver: TDriver): Promise<string[]>;
|