@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 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, _c, _d, _e;
100
- var _f;
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
- let contentRegion = await ((_b = this.driver.helper) === null || _b === void 0 ? void 0 : _b.getContentRegion(this));
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
- (_e = (_f = this._state).containedElements) !== null && _e !== void 0 ? _e : (_f.containedElements = new Map());
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 getContentSizeFromAttribute() {
182
- try {
183
- const data = await this.getAttribute('contentSize');
184
- const contentSize = JSON.parse(data);
185
- return {
186
- x: contentSize.left,
187
- y: contentSize.top,
188
- width: contentSize.width,
189
- height: this.driver.isIOS
190
- ? Math.max(contentSize.height, contentSize.scrollableOffset)
191
- : contentSize.height + contentSize.scrollableOffset,
192
- };
193
- }
194
- catch (err) {
195
- this._logger.warn(`Unable to get the attribute 'contentSize' due to the following error: '${err.message}'`);
196
- }
197
- if (this.driver.isIOS) {
198
- const type = await this.getAttribute('type');
199
- if (type === 'XCUIElementTypeScrollView') {
200
- const elementRegion = await this._spec.getElementRegion(this.driver.target, this.target);
201
- const [childElement] = await this.driver.elements({
202
- type: 'xpath',
203
- selector: '//XCUIElementTypeScrollView[1]/*', // We cannot be sure that our element is the first one
204
- });
205
- const childElementRegion = await this._spec.getElementRegion(this.driver.target, childElement.target);
206
- return {
207
- ...elementRegion,
208
- height: childElementRegion.y + childElementRegion.height - elementRegion.y,
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
- let contentRegion = await ((_a = this.driver.helper) === null || _a === void 0 ? void 0 : _a.getContentRegion(this, options));
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.driver.target, this.target);
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.05), touchPadding + 3);
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, [].concat(...actions));
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.type(this.context.target, this.target, value);
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 = await this.context.execute(snippets.getElementStyleProperties, [
606
- this,
607
- ['transform', '-webkit-transform'],
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)
@@ -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.8",
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.8",
91
+ "@applitools/snippets": "2.4.9",
92
92
  "@applitools/utils": "1.3.16",
93
93
  "semver": "7.3.7"
94
94
  },
@@ -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
- getContentSizeFromAttribute(): Promise<{
45
- x: any;
46
- y: any;
47
- width: any;
48
- height: any;
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;
@@ -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[]>;