@applitools/driver 1.11.50 → 1.11.52
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/capabilities.js +3 -1
- package/dist/context.js +32 -34
- package/dist/driver.js +20 -9
- package/dist/element.js +39 -38
- package/dist/helper-android.js +7 -4
- package/dist/helper-ios.js +5 -3
- package/package.json +4 -4
- package/types/context.d.ts +1 -3
- package/types/driver.d.ts +3 -0
- package/types/element.d.ts +1 -3
- package/types/helper-android.d.ts +3 -4
- package/types/helper-ios.d.ts +2 -5
package/dist/capabilities.js
CHANGED
|
@@ -28,7 +28,9 @@ function extractCapabilitiesEnvironment(capabilities) {
|
|
|
28
28
|
if (!environment.browserName) {
|
|
29
29
|
environment.isNative = true;
|
|
30
30
|
}
|
|
31
|
-
else if (environment.isIOS &&
|
|
31
|
+
else if (environment.isIOS &&
|
|
32
|
+
capabilities.CFBundleIdentifier &&
|
|
33
|
+
!/mobilesafari/i.test(capabilities.CFBundleIdentifier)) {
|
|
32
34
|
environment.browserName = undefined;
|
|
33
35
|
environment.isNative = true;
|
|
34
36
|
}
|
package/dist/context.js
CHANGED
|
@@ -41,7 +41,6 @@ class Context {
|
|
|
41
41
|
var _a, _b, _c, _d;
|
|
42
42
|
this._state = {};
|
|
43
43
|
this._spec = options.spec;
|
|
44
|
-
this._logger = options.logger;
|
|
45
44
|
if (options.context) {
|
|
46
45
|
if ((_c = (_b = (_a = this._spec).isContext) === null || _b === void 0 ? void 0 : _b.call(_a, options.context)) !== null && _c !== void 0 ? _c : this._spec.isDriver(options.context)) {
|
|
47
46
|
this._target = options.context;
|
|
@@ -67,6 +66,9 @@ class Context {
|
|
|
67
66
|
throw new TypeError('Context constructor called with context reference of unknown type!');
|
|
68
67
|
}
|
|
69
68
|
}
|
|
69
|
+
get logger() {
|
|
70
|
+
return this._driver.logger;
|
|
71
|
+
}
|
|
70
72
|
get target() {
|
|
71
73
|
return this._target;
|
|
72
74
|
}
|
|
@@ -171,9 +173,9 @@ class Context {
|
|
|
171
173
|
throw new TypeError('Cannot initialize context without a reference to the context element');
|
|
172
174
|
}
|
|
173
175
|
await this.parent.focus();
|
|
174
|
-
this.
|
|
176
|
+
this.logger.log('Context initialization');
|
|
175
177
|
if (utils.types.isInteger(this._reference)) {
|
|
176
|
-
this.
|
|
178
|
+
this.logger.log('Getting context element using index:', this._reference);
|
|
177
179
|
const elements = await this.parent.elements('frame, iframe');
|
|
178
180
|
if (this._reference > elements.length) {
|
|
179
181
|
throw new TypeError(`Context element with index ${this._reference} is not found`);
|
|
@@ -182,13 +184,13 @@ class Context {
|
|
|
182
184
|
}
|
|
183
185
|
else if (utils.types.isString(this._reference) || (0, selector_1.isSelector)(this._reference, this._spec)) {
|
|
184
186
|
if (utils.types.isString(this._reference)) {
|
|
185
|
-
this.
|
|
187
|
+
this.logger.log('Getting context element by name or id', this._reference);
|
|
186
188
|
this._element = await this.parent
|
|
187
189
|
.element(`iframe[name="${this._reference}"], iframe#${this._reference}`)
|
|
188
190
|
.catch(() => null);
|
|
189
191
|
}
|
|
190
192
|
if (!this._element && (0, selector_1.isSelector)(this._reference, this._spec)) {
|
|
191
|
-
this.
|
|
193
|
+
this.logger.log('Getting context element by selector', this._reference);
|
|
192
194
|
this._element = await this.parent.element(this._reference);
|
|
193
195
|
}
|
|
194
196
|
if (!this._element) {
|
|
@@ -196,11 +198,11 @@ class Context {
|
|
|
196
198
|
}
|
|
197
199
|
}
|
|
198
200
|
else if (this._spec.isElement(this._reference) || this._reference instanceof element_1.Element) {
|
|
199
|
-
this.
|
|
201
|
+
this.logger.log('Initialize context from reference element', this._reference);
|
|
200
202
|
this._element =
|
|
201
203
|
this._reference instanceof element_1.Element
|
|
202
204
|
? this._reference
|
|
203
|
-
: new element_1.Element({ spec: this._spec, context: this.parent, element: this._reference
|
|
205
|
+
: new element_1.Element({ spec: this._spec, context: this.parent, element: this._reference });
|
|
204
206
|
}
|
|
205
207
|
else {
|
|
206
208
|
throw new TypeError('Reference type does not supported');
|
|
@@ -246,7 +248,7 @@ class Context {
|
|
|
246
248
|
return reference;
|
|
247
249
|
}
|
|
248
250
|
else if (this._isReference(reference)) {
|
|
249
|
-
return new Context({ spec: this._spec, parent: this, driver: this.driver, reference
|
|
251
|
+
return new Context({ spec: this._spec, parent: this, driver: this.driver, reference });
|
|
250
252
|
}
|
|
251
253
|
else if (utils.types.has(reference, 'reference')) {
|
|
252
254
|
if (reference.reference instanceof Context)
|
|
@@ -258,7 +260,6 @@ class Context {
|
|
|
258
260
|
driver: this.driver,
|
|
259
261
|
reference: reference.reference,
|
|
260
262
|
scrollingElement: reference === null || reference === void 0 ? void 0 : reference.scrollingElement,
|
|
261
|
-
logger: this._logger,
|
|
262
263
|
});
|
|
263
264
|
}
|
|
264
265
|
else {
|
|
@@ -267,26 +268,24 @@ class Context {
|
|
|
267
268
|
}
|
|
268
269
|
async element(elementOrSelector) {
|
|
269
270
|
if (this._spec.isElement(elementOrSelector)) {
|
|
270
|
-
return new element_1.Element({ spec: this._spec, context: this, element: elementOrSelector
|
|
271
|
+
return new element_1.Element({ spec: this._spec, context: this, element: elementOrSelector });
|
|
271
272
|
}
|
|
272
273
|
else if (!(0, selector_1.isSelector)(elementOrSelector, this._spec)) {
|
|
273
274
|
throw new TypeError('Cannot find element using argument of unknown type!');
|
|
274
275
|
}
|
|
275
276
|
if (this.isRef) {
|
|
276
|
-
return new element_1.Element({ spec: this._spec, context: this, selector: elementOrSelector
|
|
277
|
+
return new element_1.Element({ spec: this._spec, context: this, selector: elementOrSelector });
|
|
277
278
|
}
|
|
278
|
-
this.
|
|
279
|
+
this.logger.log('Finding element by selector: ', elementOrSelector);
|
|
279
280
|
const [element] = await this._findElements(elementOrSelector, { all: false });
|
|
280
|
-
return element
|
|
281
|
-
? new element_1.Element({ spec: this._spec, context: this, element, selector: elementOrSelector, logger: this._logger })
|
|
282
|
-
: null;
|
|
281
|
+
return element ? new element_1.Element({ spec: this._spec, context: this, element, selector: elementOrSelector }) : null;
|
|
283
282
|
}
|
|
284
283
|
async elements(selectorOrElement) {
|
|
285
284
|
if ((0, selector_1.isSelector)(selectorOrElement, this._spec)) {
|
|
286
285
|
if (this.isRef) {
|
|
287
|
-
return [new element_1.Element({ spec: this._spec, context: this, selector: selectorOrElement
|
|
286
|
+
return [new element_1.Element({ spec: this._spec, context: this, selector: selectorOrElement })];
|
|
288
287
|
}
|
|
289
|
-
this.
|
|
288
|
+
this.logger.log('Finding elements by selector: ', selectorOrElement);
|
|
290
289
|
const elements = await this._findElements(selectorOrElement, { all: true });
|
|
291
290
|
return elements.map((element, index) => {
|
|
292
291
|
return new element_1.Element({
|
|
@@ -295,23 +294,22 @@ class Context {
|
|
|
295
294
|
element,
|
|
296
295
|
selector: selectorOrElement,
|
|
297
296
|
index,
|
|
298
|
-
logger: this._logger,
|
|
299
297
|
});
|
|
300
298
|
});
|
|
301
299
|
}
|
|
302
300
|
else if (this._spec.isElement(selectorOrElement)) {
|
|
303
|
-
return [new element_1.Element({ spec: this._spec, context: this, element: selectorOrElement
|
|
301
|
+
return [new element_1.Element({ spec: this._spec, context: this, element: selectorOrElement })];
|
|
304
302
|
}
|
|
305
303
|
else {
|
|
306
304
|
throw new TypeError('Cannot find elements using argument of unknown type!');
|
|
307
305
|
}
|
|
308
306
|
}
|
|
309
307
|
async waitFor(selector, options) {
|
|
310
|
-
this.
|
|
308
|
+
this.logger.log('Waiting for element by selector: ', selector, 'and options', options);
|
|
311
309
|
const [element] = await this._findElements(selector, {
|
|
312
310
|
wait: { state: 'exist', timeout: 10000, interval: 500, ...options },
|
|
313
311
|
});
|
|
314
|
-
return element ? new element_1.Element({ spec: this._spec, context: this, element, selector
|
|
312
|
+
return element ? new element_1.Element({ spec: this._spec, context: this, element, selector }) : null;
|
|
315
313
|
}
|
|
316
314
|
async execute(script, arg) {
|
|
317
315
|
await this.focus();
|
|
@@ -319,8 +317,8 @@ class Context {
|
|
|
319
317
|
return await this._spec.executeScript(this.target, script, serialize.call(this, arg));
|
|
320
318
|
}
|
|
321
319
|
catch (err) {
|
|
322
|
-
this.
|
|
323
|
-
this.
|
|
320
|
+
this.logger.warn('Error during script execution with argument', arg);
|
|
321
|
+
this.logger.error(err);
|
|
324
322
|
throw err;
|
|
325
323
|
}
|
|
326
324
|
function serialize(value) {
|
|
@@ -342,7 +340,7 @@ class Context {
|
|
|
342
340
|
}
|
|
343
341
|
}
|
|
344
342
|
async executePoll(script, arg) {
|
|
345
|
-
this.
|
|
343
|
+
this.logger.log('Executing poll script');
|
|
346
344
|
const { main: mainScript, poll: pollScript } = utils.types.isString(script) || utils.types.isFunction(script) ? { main: script, poll: script } : script;
|
|
347
345
|
const { main: mainArg, poll: pollArg, executionTimeout = 60000, pollTimeout = 1000, } = !utils.types.has(arg, ['main', 'poll']) ? { main: arg, poll: arg } : arg;
|
|
348
346
|
let isExecutionTimedOut = false;
|
|
@@ -365,7 +363,7 @@ class Context {
|
|
|
365
363
|
else if (response.status === 'WIP') {
|
|
366
364
|
await utils.general.sleep(pollTimeout);
|
|
367
365
|
}
|
|
368
|
-
this.
|
|
366
|
+
this.logger.log('Polling...');
|
|
369
367
|
response = deserialize(await this.execute(pollScript, pollArg));
|
|
370
368
|
}
|
|
371
369
|
throw new Error('Poll script execution is timed out');
|
|
@@ -402,11 +400,11 @@ class Context {
|
|
|
402
400
|
let selector;
|
|
403
401
|
if (environment.isIOS && !environment.isEmulation) {
|
|
404
402
|
selector = 'html';
|
|
405
|
-
this.
|
|
403
|
+
this.logger.log(`Using hardcoded default scrolling element for Safari on iOS - "${selector}"`);
|
|
406
404
|
}
|
|
407
405
|
else {
|
|
408
406
|
selector = await this.execute(snippets.getDocumentScrollingElement);
|
|
409
|
-
this.
|
|
407
|
+
this.logger.log(`Using dynamic default scrolling element - "${selector}"`);
|
|
410
408
|
}
|
|
411
409
|
this._scrollingElement = await this.element({ type: 'css', selector });
|
|
412
410
|
}
|
|
@@ -431,8 +429,8 @@ class Context {
|
|
|
431
429
|
return await this.execute(snippets.blurElement, [element]);
|
|
432
430
|
}
|
|
433
431
|
catch (err) {
|
|
434
|
-
this.
|
|
435
|
-
this.
|
|
432
|
+
this.logger.warn('Cannot blur element', element);
|
|
433
|
+
this.logger.error(err);
|
|
436
434
|
return null;
|
|
437
435
|
}
|
|
438
436
|
}
|
|
@@ -441,8 +439,8 @@ class Context {
|
|
|
441
439
|
return await this.execute(snippets.focusElement, [element]);
|
|
442
440
|
}
|
|
443
441
|
catch (err) {
|
|
444
|
-
this.
|
|
445
|
-
this.
|
|
442
|
+
this.logger.warn('Cannot focus element', element);
|
|
443
|
+
this.logger.error(err);
|
|
446
444
|
return null;
|
|
447
445
|
}
|
|
448
446
|
}
|
|
@@ -514,7 +512,7 @@ class Context {
|
|
|
514
512
|
}
|
|
515
513
|
async getRegionInViewport(region) {
|
|
516
514
|
var _a, _b;
|
|
517
|
-
this.
|
|
515
|
+
this.logger.log('Converting context region to viewport region', region);
|
|
518
516
|
if (region)
|
|
519
517
|
region = utils.geometry.offsetNegative(region, await this.getInnerOffset());
|
|
520
518
|
else
|
|
@@ -528,7 +526,7 @@ class Context {
|
|
|
528
526
|
// TODO revisit
|
|
529
527
|
if (environment.isWeb ||
|
|
530
528
|
(!utils.geometry.equals(contextRegion, region) && utils.geometry.contains(contextRegion, region))) {
|
|
531
|
-
this.
|
|
529
|
+
this.logger.log('Intersecting context region', contextRegion, 'with context region', region);
|
|
532
530
|
region = utils.geometry.intersect(contextRegion, utils.geometry.offset(region, contextRegion));
|
|
533
531
|
// region = utils.geometry.intersect(contextScrollingRegion, region)
|
|
534
532
|
region = utils.geometry.offsetNegative(region, parentContextInnerOffset);
|
|
@@ -544,7 +542,7 @@ class Context {
|
|
|
544
542
|
return [];
|
|
545
543
|
await this.focus();
|
|
546
544
|
const cookies = await ((_b = (_a = this._spec).getCookies) === null || _b === void 0 ? void 0 : _b.call(_a, this.target, true));
|
|
547
|
-
this.
|
|
545
|
+
this.logger.log('Extracted context cookies', cookies);
|
|
548
546
|
return cookies !== null && cookies !== void 0 ? cookies : [];
|
|
549
547
|
}
|
|
550
548
|
async preserveInnerOffset() {
|
package/dist/driver.js
CHANGED
|
@@ -35,25 +35,27 @@ const utils = __importStar(require("@applitools/utils"));
|
|
|
35
35
|
const snippets = require('@applitools/snippets');
|
|
36
36
|
class Driver {
|
|
37
37
|
constructor(options) {
|
|
38
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
38
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
39
39
|
this._state = {};
|
|
40
40
|
this._customConfig = {};
|
|
41
|
+
this._logger = (0, logger_1.makeLogger)({ logger: options.logger, format: { label: 'driver' } });
|
|
41
42
|
this._customConfig = (_a = options.customConfig) !== null && _a !== void 0 ? _a : {};
|
|
42
43
|
this._guid = utils.general.guid();
|
|
43
44
|
this._spec = options.spec;
|
|
44
|
-
this.
|
|
45
|
-
this._target = (_f = (_e = (_d = this._spec).transformDriver) === null || _e === void 0 ? void 0 : _e.call(_d, options.driver)) !== null && _f !== void 0 ? _f : options.driver;
|
|
45
|
+
this._target = (_d = (_c = (_b = this._spec).transformDriver) === null || _c === void 0 ? void 0 : _c.call(_b, options.driver)) !== null && _d !== void 0 ? _d : options.driver;
|
|
46
46
|
if (!this._spec.isDriver(this._target)) {
|
|
47
47
|
throw new TypeError('Driver constructor called with argument of unknown type!');
|
|
48
48
|
}
|
|
49
49
|
this._mainContext = new context_1.Context({
|
|
50
50
|
spec: this._spec,
|
|
51
|
-
context: (
|
|
51
|
+
context: (_g = (_f = (_e = this._spec).extractContext) === null || _f === void 0 ? void 0 : _f.call(_e, this._target)) !== null && _g !== void 0 ? _g : this._target,
|
|
52
52
|
driver: this,
|
|
53
|
-
logger: this._logger,
|
|
54
53
|
});
|
|
55
54
|
this._currentContext = this._mainContext;
|
|
56
55
|
}
|
|
56
|
+
get logger() {
|
|
57
|
+
return this._logger;
|
|
58
|
+
}
|
|
57
59
|
get target() {
|
|
58
60
|
return this._target;
|
|
59
61
|
}
|
|
@@ -66,9 +68,16 @@ class Driver {
|
|
|
66
68
|
get mainContext() {
|
|
67
69
|
return this._mainContext;
|
|
68
70
|
}
|
|
71
|
+
updateLogger(logger) {
|
|
72
|
+
this._logger = logger.extend({ label: 'driver' });
|
|
73
|
+
}
|
|
69
74
|
updateCurrentContext(context) {
|
|
70
75
|
this._currentContext = context;
|
|
71
76
|
}
|
|
77
|
+
async reloadPage() {
|
|
78
|
+
await this.mainContext.execute(snippets.reloadPage).catch(() => null);
|
|
79
|
+
return this.refresh();
|
|
80
|
+
}
|
|
72
81
|
async refresh() {
|
|
73
82
|
this._driverInfo = undefined;
|
|
74
83
|
this._environment = undefined;
|
|
@@ -393,8 +402,8 @@ class Driver {
|
|
|
393
402
|
const environment = await this.getEnvironment();
|
|
394
403
|
this._logger.log(`Extracting helper for ${environment.isIOS ? 'ios' : 'android'}`);
|
|
395
404
|
this._helper = environment.isIOS
|
|
396
|
-
? await helper_ios_1.HelperIOS.make({ spec: this._spec, driver: this
|
|
397
|
-
: await helper_android_1.HelperAndroid.make({ spec: this._spec, driver: this
|
|
405
|
+
? await helper_ios_1.HelperIOS.make({ spec: this._spec, driver: this })
|
|
406
|
+
: await helper_android_1.HelperAndroid.make({ spec: this._spec, driver: this });
|
|
398
407
|
this._logger.log(`Extracted helper of type ${(_a = this._helper) === null || _a === void 0 ? void 0 : _a.name}`);
|
|
399
408
|
}
|
|
400
409
|
this._logger.log(`Returning helper for of type ${(_c = (_b = this._helper) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : null}`);
|
|
@@ -668,8 +677,8 @@ class Driver {
|
|
|
668
677
|
let attempt = 0;
|
|
669
678
|
while (attempt++ < 3) {
|
|
670
679
|
const requiredWindowSize = {
|
|
671
|
-
width: currentWindowSize.width + (requiredViewportSize.width - currentViewportSize.width),
|
|
672
|
-
height: currentWindowSize.height + (requiredViewportSize.height - currentViewportSize.height),
|
|
680
|
+
width: Math.max(0, currentWindowSize.width + (requiredViewportSize.width - currentViewportSize.width)),
|
|
681
|
+
height: Math.max(0, currentWindowSize.height + (requiredViewportSize.height - currentViewportSize.height)),
|
|
673
682
|
};
|
|
674
683
|
this._logger.log(`Attempt #${attempt} to set viewport size by setting window size to`, requiredWindowSize);
|
|
675
684
|
await this._spec.setWindowSize(this.target, requiredWindowSize);
|
|
@@ -801,6 +810,8 @@ function isDriver(driver, spec) {
|
|
|
801
810
|
exports.isDriver = isDriver;
|
|
802
811
|
async function makeDriver(options) {
|
|
803
812
|
const driver = options.driver instanceof Driver ? options.driver : new Driver(options);
|
|
813
|
+
if (options.logger)
|
|
814
|
+
driver.updateLogger(options.logger);
|
|
804
815
|
return driver.refresh();
|
|
805
816
|
}
|
|
806
817
|
exports.makeDriver = makeDriver;
|
package/dist/element.js
CHANGED
|
@@ -33,7 +33,6 @@ class Element {
|
|
|
33
33
|
this._state = {};
|
|
34
34
|
this._spec = options.spec;
|
|
35
35
|
this._context = options.context;
|
|
36
|
-
this._logger = options.logger;
|
|
37
36
|
if (utils.types.has(options, 'element')) {
|
|
38
37
|
this._target = (_c = (_b = (_a = this._spec).transformElement) === null || _b === void 0 ? void 0 : _b.call(_a, options.element)) !== null && _c !== void 0 ? _c : options.element;
|
|
39
38
|
if (this._spec.isElement(this._target)) {
|
|
@@ -61,6 +60,9 @@ class Element {
|
|
|
61
60
|
this._commonSelector = null;
|
|
62
61
|
}
|
|
63
62
|
}
|
|
63
|
+
get logger() {
|
|
64
|
+
return this._context.logger;
|
|
65
|
+
}
|
|
64
66
|
get target() {
|
|
65
67
|
return this._target;
|
|
66
68
|
}
|
|
@@ -105,13 +107,13 @@ class Element {
|
|
|
105
107
|
innerElement = innerElement instanceof Element ? innerElement.target : innerElement;
|
|
106
108
|
const environment = await this.driver.getEnvironment();
|
|
107
109
|
if (environment.isWeb) {
|
|
108
|
-
this.
|
|
110
|
+
this.logger.log('Checking if web element with selector', this.selector, 'contains element', innerElement);
|
|
109
111
|
return false; // TODO implement a snipped for web
|
|
110
112
|
}
|
|
111
113
|
else {
|
|
112
114
|
if ((_a = this._state.containedElements) === null || _a === void 0 ? void 0 : _a.has(innerElement))
|
|
113
115
|
return this._state.containedElements.get(innerElement);
|
|
114
|
-
this.
|
|
116
|
+
this.logger.log('Checking if native element with selector', this.selector, 'contains element', innerElement);
|
|
115
117
|
// appium doesn't have a way to check if an element is contained in another element, so juristic applied
|
|
116
118
|
if (await this.equals(innerElement))
|
|
117
119
|
return false;
|
|
@@ -124,12 +126,11 @@ class Element {
|
|
|
124
126
|
return contains;
|
|
125
127
|
}
|
|
126
128
|
});
|
|
127
|
-
this.
|
|
129
|
+
this.logger.log('Element with selector', this.selector, contains ? 'contains' : `doesn't contain`, innerElement);
|
|
128
130
|
return contains;
|
|
129
131
|
}
|
|
130
132
|
async init(context) {
|
|
131
133
|
this._context = context;
|
|
132
|
-
this._logger = context._logger;
|
|
133
134
|
if (this._target)
|
|
134
135
|
return this;
|
|
135
136
|
if (this._selector) {
|
|
@@ -144,13 +145,13 @@ class Element {
|
|
|
144
145
|
const region = await this.withRefresh(async () => {
|
|
145
146
|
const environment = await this.driver.getEnvironment();
|
|
146
147
|
if (environment.isWeb) {
|
|
147
|
-
this.
|
|
148
|
+
this.logger.log('Extracting region of web element with selector', this.selector);
|
|
148
149
|
return this.context.execute(snippets.getElementRect, [this, false]);
|
|
149
150
|
}
|
|
150
151
|
else {
|
|
151
|
-
this.
|
|
152
|
+
this.logger.log('Extracting region of native element with selector', this.selector);
|
|
152
153
|
const region = await this._spec.getElementRegion(this.driver.target, this.target);
|
|
153
|
-
this.
|
|
154
|
+
this.logger.log('Extracted native region', region);
|
|
154
155
|
const normalizedRegion = await this.driver.normalizeRegion(region);
|
|
155
156
|
// if element is a child of scrolling element, then region location should be adjusted
|
|
156
157
|
const scrollingElement = await this.context.getScrollingElement();
|
|
@@ -159,21 +160,21 @@ class Element {
|
|
|
159
160
|
: normalizedRegion;
|
|
160
161
|
}
|
|
161
162
|
});
|
|
162
|
-
this.
|
|
163
|
+
this.logger.log('Extracted region', region);
|
|
163
164
|
return region;
|
|
164
165
|
}
|
|
165
166
|
async getClientRegion() {
|
|
166
167
|
const region = await this.withRefresh(async () => {
|
|
167
168
|
const environment = await this.driver.getEnvironment();
|
|
168
169
|
if (environment.isWeb) {
|
|
169
|
-
this.
|
|
170
|
+
this.logger.log('Extracting region of web element with selector', this.selector);
|
|
170
171
|
return this.context.execute(snippets.getElementRect, [this, true]);
|
|
171
172
|
}
|
|
172
173
|
else {
|
|
173
174
|
return this.getRegion();
|
|
174
175
|
}
|
|
175
176
|
});
|
|
176
|
-
this.
|
|
177
|
+
this.logger.log('Extracted client region', region);
|
|
177
178
|
return region;
|
|
178
179
|
}
|
|
179
180
|
async getContentRegion(options = {}) {
|
|
@@ -181,10 +182,10 @@ class Element {
|
|
|
181
182
|
const environment = await this.driver.getEnvironment();
|
|
182
183
|
if (!environment.isNative)
|
|
183
184
|
return null;
|
|
184
|
-
this.
|
|
185
|
+
this.logger.log('Extracting content region of native element with selector', this.selector);
|
|
185
186
|
const helper = await this.driver.getHelper();
|
|
186
187
|
let contentRegion = await (helper === null || helper === void 0 ? void 0 : helper.getContentRegion(this, options));
|
|
187
|
-
this.
|
|
188
|
+
this.logger.log('Extracted content region using helper library', contentRegion);
|
|
188
189
|
if (!contentRegion || !environment.isAndroid) {
|
|
189
190
|
let attrContentRegion = null;
|
|
190
191
|
try {
|
|
@@ -199,9 +200,9 @@ class Element {
|
|
|
199
200
|
};
|
|
200
201
|
}
|
|
201
202
|
catch (err) {
|
|
202
|
-
this.
|
|
203
|
+
this.logger.warn(`Unable to get the attribute 'contentSize' due to the following error: '${err.message}'`);
|
|
203
204
|
}
|
|
204
|
-
this.
|
|
205
|
+
this.logger.log('Extracted content region using attribute', attrContentRegion);
|
|
205
206
|
// ios workaround
|
|
206
207
|
if (!attrContentRegion && environment.isIOS) {
|
|
207
208
|
try {
|
|
@@ -222,9 +223,9 @@ class Element {
|
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
225
|
catch (err) {
|
|
225
|
-
this.
|
|
226
|
+
this.logger.warn(`Unable to calculate content region using iOS workaround due to the following error: '${err.message}'`);
|
|
226
227
|
}
|
|
227
|
-
this.
|
|
228
|
+
this.logger.log('Extracted content region using iOS workaround', attrContentRegion);
|
|
228
229
|
}
|
|
229
230
|
if (attrContentRegion) {
|
|
230
231
|
contentRegion = {
|
|
@@ -243,11 +244,11 @@ class Element {
|
|
|
243
244
|
const size = await this.withRefresh(async () => {
|
|
244
245
|
const environment = await this.driver.getEnvironment();
|
|
245
246
|
if (environment.isWeb) {
|
|
246
|
-
this.
|
|
247
|
+
this.logger.log('Extracting content size of web element with selector', this.selector);
|
|
247
248
|
return this.context.execute(snippets.getElementContentSize, [this]);
|
|
248
249
|
}
|
|
249
250
|
else {
|
|
250
|
-
this.
|
|
251
|
+
this.logger.log('Extracting content size of native element with selector', this.selector);
|
|
251
252
|
try {
|
|
252
253
|
const contentRegion = await this.getContentRegion(options);
|
|
253
254
|
this._state.contentSize = utils.geometry.size(contentRegion);
|
|
@@ -261,17 +262,17 @@ class Element {
|
|
|
261
262
|
return this._state.contentSize;
|
|
262
263
|
}
|
|
263
264
|
catch (err) {
|
|
264
|
-
this.
|
|
265
|
-
this.
|
|
265
|
+
this.logger.warn('Failed to extract content size, extracting client size instead');
|
|
266
|
+
this.logger.error(err);
|
|
266
267
|
return utils.geometry.size(await this.getClientRegion());
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
270
|
});
|
|
270
|
-
this.
|
|
271
|
+
this.logger.log('Extracted content size', size);
|
|
271
272
|
return size;
|
|
272
273
|
}
|
|
273
274
|
async isPager() {
|
|
274
|
-
this.
|
|
275
|
+
this.logger.log('Check if element with selector', this.selector, 'is scrollable by pages');
|
|
275
276
|
const isPager = await this.withRefresh(async () => {
|
|
276
277
|
const environment = await this.driver.getEnvironment();
|
|
277
278
|
if (environment.isAndroid) {
|
|
@@ -282,11 +283,11 @@ class Element {
|
|
|
282
283
|
return false;
|
|
283
284
|
}
|
|
284
285
|
});
|
|
285
|
-
this.
|
|
286
|
+
this.logger.log('Element scrollable by pages', isPager);
|
|
286
287
|
return isPager;
|
|
287
288
|
}
|
|
288
289
|
async isScrollable() {
|
|
289
|
-
this.
|
|
290
|
+
this.logger.log('Check if element with selector', this.selector, 'is scrollable');
|
|
290
291
|
const isScrollable = await this.withRefresh(async () => {
|
|
291
292
|
const environment = await this.driver.getEnvironment();
|
|
292
293
|
if (environment.isWeb) {
|
|
@@ -301,7 +302,7 @@ class Element {
|
|
|
301
302
|
return ['XCUIElementTypeScrollView', 'XCUIElementTypeTable', 'XCUIElementTypeCollectionView'].includes(type);
|
|
302
303
|
}
|
|
303
304
|
});
|
|
304
|
-
this.
|
|
305
|
+
this.logger.log('Element is scrollable', isScrollable);
|
|
305
306
|
return isScrollable;
|
|
306
307
|
}
|
|
307
308
|
async isRoot() {
|
|
@@ -336,18 +337,18 @@ class Element {
|
|
|
336
337
|
const helper = await this.driver.getHelper();
|
|
337
338
|
if ((helper === null || helper === void 0 ? void 0 : helper.name) === 'android') {
|
|
338
339
|
this._state.touchPadding = await helper.getTouchPadding();
|
|
339
|
-
this.
|
|
340
|
+
this.logger.log('Touch padding extracted using helper library', this._state.touchPadding);
|
|
340
341
|
}
|
|
341
342
|
if (!this._state.touchPadding) {
|
|
342
343
|
this._state.touchPadding = await this.getAttribute('contentSize')
|
|
343
344
|
.then(data => JSON.parse(data).touchPadding)
|
|
344
345
|
.catch(err => {
|
|
345
|
-
this.
|
|
346
|
+
this.logger.warn(`Unable to get the attribute 'contentSize' when looking up 'touchPadding' due to the following error: '${err.message}'`);
|
|
346
347
|
});
|
|
347
|
-
this.
|
|
348
|
+
this.logger.log('Touch padding extracted using attribute', this._state.touchPadding);
|
|
348
349
|
}
|
|
349
350
|
(_a = (_b = this._state).touchPadding) !== null && _a !== void 0 ? _a : (_b.touchPadding = 20);
|
|
350
|
-
this.
|
|
351
|
+
this.logger.log('Touch padding set:', this._state.touchPadding);
|
|
351
352
|
}
|
|
352
353
|
}
|
|
353
354
|
return this._state.touchPadding;
|
|
@@ -359,11 +360,11 @@ class Element {
|
|
|
359
360
|
return '';
|
|
360
361
|
}
|
|
361
362
|
else {
|
|
362
|
-
this.
|
|
363
|
+
this.logger.log('Extracting text of native element with selector', this.selector);
|
|
363
364
|
return this._spec.getElementText(this.context.target, this.target);
|
|
364
365
|
}
|
|
365
366
|
});
|
|
366
|
-
this.
|
|
367
|
+
this.logger.log('Extracted element text', text);
|
|
367
368
|
return text;
|
|
368
369
|
}
|
|
369
370
|
async getAttribute(name) {
|
|
@@ -383,7 +384,7 @@ class Element {
|
|
|
383
384
|
return properties[name];
|
|
384
385
|
}
|
|
385
386
|
else {
|
|
386
|
-
this.
|
|
387
|
+
this.logger.log(`Extracting "${name}" attribute of native element with selector`, this.selector);
|
|
387
388
|
(_a = (_b = this._state).attributes) !== null && _a !== void 0 ? _a : (_b.attributes = {});
|
|
388
389
|
try {
|
|
389
390
|
this._state.attributes[name] = await this._spec.getElementAttribute(this.driver.target, this.target, name);
|
|
@@ -396,7 +397,7 @@ class Element {
|
|
|
396
397
|
finally {
|
|
397
398
|
if (environment.isAndroid && name === 'contentSize') {
|
|
398
399
|
// android has a bug when after extracting 'contentSize' attribute the element is being scrolled by undetermined number of pixels
|
|
399
|
-
this.
|
|
400
|
+
this.logger.log('Stabilizing android scroll offset');
|
|
400
401
|
const originalScrollOffset = await this.getScrollOffset();
|
|
401
402
|
await this.scrollTo({ x: 0, y: 0 }, { force: true });
|
|
402
403
|
await this.scrollTo(originalScrollOffset);
|
|
@@ -404,7 +405,7 @@ class Element {
|
|
|
404
405
|
}
|
|
405
406
|
}
|
|
406
407
|
});
|
|
407
|
-
this.
|
|
408
|
+
this.logger.log(`Extracted element "${name}" attribute:`, value);
|
|
408
409
|
return value;
|
|
409
410
|
}
|
|
410
411
|
async setAttribute(name, value) {
|
|
@@ -415,7 +416,7 @@ class Element {
|
|
|
415
416
|
}
|
|
416
417
|
async scrollTo(offset, options) {
|
|
417
418
|
return this.withRefresh(async () => {
|
|
418
|
-
this.
|
|
419
|
+
this.logger.log(`Scrolling to offset (${offset.x}, ${offset.y}) element with selector`, this.selector);
|
|
419
420
|
offset = utils.geometry.round({ x: Math.max(offset.x, 0), y: Math.max(offset.y, 0) });
|
|
420
421
|
const environment = await this.driver.getEnvironment();
|
|
421
422
|
if (environment.isWeb) {
|
|
@@ -625,12 +626,12 @@ class Element {
|
|
|
625
626
|
}
|
|
626
627
|
async click() {
|
|
627
628
|
var _a, _b;
|
|
628
|
-
this.
|
|
629
|
+
this.logger.log(`Clicking on the element with selector`, this.selector);
|
|
629
630
|
await ((_b = (_a = this._spec).click) === null || _b === void 0 ? void 0 : _b.call(_a, this.context.target, this.target));
|
|
630
631
|
}
|
|
631
632
|
async type(value) {
|
|
632
633
|
var _a, _b;
|
|
633
|
-
this.
|
|
634
|
+
this.logger.log(`Typing text "${value}" in the element with selector`, this.selector);
|
|
634
635
|
await ((_b = (_a = this._spec).setElementText) === null || _b === void 0 ? void 0 : _b.call(_a, this.context.target, this.target, value));
|
|
635
636
|
}
|
|
636
637
|
async preserveState() {
|
package/dist/helper-android.js
CHANGED
|
@@ -32,7 +32,7 @@ const gte_1 = __importDefault(require("semver/functions/gte"));
|
|
|
32
32
|
class HelperAndroid {
|
|
33
33
|
static async make(options) {
|
|
34
34
|
var _a;
|
|
35
|
-
const { spec, driver
|
|
35
|
+
const { spec, driver } = options;
|
|
36
36
|
let legacy = false;
|
|
37
37
|
let input = await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelperEDT"]' });
|
|
38
38
|
if (!input) {
|
|
@@ -50,10 +50,10 @@ class HelperAndroid {
|
|
|
50
50
|
return input
|
|
51
51
|
? new HelperAndroid({
|
|
52
52
|
spec,
|
|
53
|
+
driver,
|
|
53
54
|
input,
|
|
54
55
|
action,
|
|
55
56
|
legacy,
|
|
56
|
-
logger,
|
|
57
57
|
supportAsync: (0, gte_1.default)(version, '1.8.0'),
|
|
58
58
|
})
|
|
59
59
|
: null;
|
|
@@ -61,13 +61,16 @@ class HelperAndroid {
|
|
|
61
61
|
constructor(options) {
|
|
62
62
|
this._supportAsync = false;
|
|
63
63
|
this._spec = options.spec;
|
|
64
|
+
this._driver = options.driver;
|
|
64
65
|
this._input = options.input;
|
|
65
66
|
this._action = options.action;
|
|
66
67
|
this._legacy = options.legacy;
|
|
67
|
-
this._logger = options.logger;
|
|
68
68
|
this.name = this._legacy ? 'android-legacy' : 'android';
|
|
69
69
|
this._supportAsync = options.supportAsync === true;
|
|
70
70
|
}
|
|
71
|
+
get logger() {
|
|
72
|
+
return this._driver.logger;
|
|
73
|
+
}
|
|
71
74
|
async _getElementId(element) {
|
|
72
75
|
const resourceId = await element.getAttribute('resource-id');
|
|
73
76
|
if (!resourceId)
|
|
@@ -90,7 +93,7 @@ class HelperAndroid {
|
|
|
90
93
|
text = await this._input.getText();
|
|
91
94
|
}
|
|
92
95
|
if (text === 'WAIT') {
|
|
93
|
-
this.
|
|
96
|
+
this.logger.warn(`Helper library didn't provide a response for async command (${command}) during ${timeout}ms`);
|
|
94
97
|
text = '';
|
|
95
98
|
}
|
|
96
99
|
return text;
|
package/dist/helper-ios.js
CHANGED
|
@@ -3,17 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.HelperIOS = void 0;
|
|
4
4
|
class HelperIOS {
|
|
5
5
|
static async make(options) {
|
|
6
|
-
const { spec, driver
|
|
6
|
+
const { spec, driver } = options;
|
|
7
7
|
const element = await driver.element({ type: 'name', selector: 'applitools_grab_scrollable_data_button' });
|
|
8
|
-
return element ? new HelperIOS({ driver, element, spec
|
|
8
|
+
return element ? new HelperIOS({ driver, element, spec }) : null;
|
|
9
9
|
}
|
|
10
10
|
constructor(options) {
|
|
11
11
|
this._driver = options.driver;
|
|
12
12
|
this._element = options.element;
|
|
13
13
|
this._spec = options.spec;
|
|
14
|
-
this._logger = options.logger;
|
|
15
14
|
this.name = 'ios';
|
|
16
15
|
}
|
|
16
|
+
get logger() {
|
|
17
|
+
return this._driver.logger;
|
|
18
|
+
}
|
|
17
19
|
async getContentRegion(element) {
|
|
18
20
|
var _a, _b;
|
|
19
21
|
await this._element.click();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/driver",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.52",
|
|
4
4
|
"description": "Applitools universal framework wrapper",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"applitools",
|
|
@@ -81,9 +81,9 @@
|
|
|
81
81
|
"postversion": "bongo postversion"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@applitools/logger": "
|
|
85
|
-
"@applitools/snippets": "2.4.
|
|
86
|
-
"@applitools/utils": "1.3.
|
|
84
|
+
"@applitools/logger": "2.0.0",
|
|
85
|
+
"@applitools/snippets": "2.4.20",
|
|
86
|
+
"@applitools/utils": "1.3.36",
|
|
87
87
|
"semver": "7.3.7"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
package/types/context.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Location, Size, Region } from '@applitools/utils';
|
|
2
2
|
import type { Cookie } from './types';
|
|
3
|
-
import { type Logger } from '@applitools/logger';
|
|
4
3
|
import { type SpecType, type SpecDriver, type WaitOptions } from './spec-driver';
|
|
5
4
|
import { type Driver } from './driver';
|
|
6
5
|
import { type Selector } from './selector';
|
|
@@ -19,7 +18,6 @@ type ContextOptions<T extends SpecType> = {
|
|
|
19
18
|
reference?: ContextReference<T>;
|
|
20
19
|
element?: Element<T>;
|
|
21
20
|
scrollingElement?: Element<T>;
|
|
22
|
-
logger: Logger;
|
|
23
21
|
};
|
|
24
22
|
export declare class Context<T extends SpecType> {
|
|
25
23
|
private _target?;
|
|
@@ -29,10 +27,10 @@ export declare class Context<T extends SpecType> {
|
|
|
29
27
|
private _reference?;
|
|
30
28
|
private _scrollingElement?;
|
|
31
29
|
private _state;
|
|
32
|
-
private _logger;
|
|
33
30
|
private _isReference;
|
|
34
31
|
protected readonly _spec: SpecDriver<T>;
|
|
35
32
|
constructor(options: ContextOptions<T>);
|
|
33
|
+
get logger(): import("@applitools/logger").Logger;
|
|
36
34
|
get target(): T['driver'];
|
|
37
35
|
get driver(): Driver<T>;
|
|
38
36
|
get parent(): Context<T> | null;
|
package/types/driver.d.ts
CHANGED
|
@@ -31,11 +31,14 @@ export declare class Driver<T extends SpecType> {
|
|
|
31
31
|
private _logger;
|
|
32
32
|
protected readonly _spec: SpecDriver<T>;
|
|
33
33
|
constructor(options: DriverOptions<T>);
|
|
34
|
+
get logger(): Logger;
|
|
34
35
|
get target(): T['driver'];
|
|
35
36
|
get guid(): string;
|
|
36
37
|
get currentContext(): Context<T>;
|
|
37
38
|
get mainContext(): Context<T>;
|
|
39
|
+
updateLogger(logger: Logger): void;
|
|
38
40
|
updateCurrentContext(context: Context<T>): void;
|
|
41
|
+
reloadPage(): Promise<this>;
|
|
39
42
|
refresh(): Promise<this>;
|
|
40
43
|
getDriverInfo({ force }?: {
|
|
41
44
|
force?: boolean;
|
package/types/element.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Location, Size, Region } from '@applitools/utils';
|
|
2
|
-
import { type Logger } from '@applitools/logger';
|
|
3
2
|
import { type SpecType, type SpecDriver } from './spec-driver';
|
|
4
3
|
import { type Context } from './context';
|
|
5
4
|
import { type Selector, type CommonSelector } from './selector';
|
|
@@ -15,7 +14,6 @@ type ElementState = {
|
|
|
15
14
|
type ElementOptions<T extends SpecType> = {
|
|
16
15
|
spec: SpecDriver<T>;
|
|
17
16
|
context?: Context<T>;
|
|
18
|
-
logger: Logger;
|
|
19
17
|
} & ({
|
|
20
18
|
element: T['element'];
|
|
21
19
|
selector?: Selector<T>;
|
|
@@ -32,9 +30,9 @@ export declare class Element<T extends SpecType> {
|
|
|
32
30
|
private _index?;
|
|
33
31
|
private _state;
|
|
34
32
|
private _originalOverflow;
|
|
35
|
-
private _logger;
|
|
36
33
|
protected readonly _spec: SpecDriver<T>;
|
|
37
34
|
constructor(options: ElementOptions<T>);
|
|
35
|
+
get logger(): import("@applitools/logger").Logger;
|
|
38
36
|
get target(): NonNullable<T["element"]>;
|
|
39
37
|
get selector(): Selector<T> | undefined;
|
|
40
38
|
get commonSelector(): CommonSelector | null;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Location, Region } from '@applitools/utils';
|
|
2
|
-
import { type Logger } from '@applitools/logger';
|
|
3
2
|
import { type SpecType, type SpecDriver } from './spec-driver';
|
|
4
3
|
import { type Driver } from './driver';
|
|
5
4
|
import { type Element } from './element';
|
|
@@ -7,23 +6,23 @@ export declare class HelperAndroid<T extends SpecType> {
|
|
|
7
6
|
static make<T extends SpecType>(options: {
|
|
8
7
|
spec: SpecDriver<T>;
|
|
9
8
|
driver: Driver<T>;
|
|
10
|
-
logger: Logger;
|
|
11
9
|
}): Promise<HelperAndroid<T> | null>;
|
|
12
10
|
private readonly _spec;
|
|
11
|
+
private readonly _driver;
|
|
13
12
|
private readonly _input;
|
|
14
13
|
private readonly _action;
|
|
15
14
|
private readonly _legacy;
|
|
16
15
|
private readonly _supportAsync;
|
|
17
|
-
private _logger;
|
|
18
16
|
readonly name: 'android' | 'android-legacy';
|
|
19
17
|
constructor(options: {
|
|
20
18
|
spec: SpecDriver<T>;
|
|
19
|
+
driver: Driver<T>;
|
|
21
20
|
input: Element<T>;
|
|
22
21
|
action: Element<T> | null;
|
|
23
22
|
legacy: boolean;
|
|
24
23
|
supportAsync: boolean;
|
|
25
|
-
logger: Logger;
|
|
26
24
|
});
|
|
25
|
+
get logger(): import("@applitools/logger").Logger;
|
|
27
26
|
private _getElementId;
|
|
28
27
|
private _command;
|
|
29
28
|
getContentRegion(element: Element<T>, options?: {
|
package/types/helper-ios.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Region } from '@applitools/utils';
|
|
2
|
-
import { type Logger } from '@applitools/logger';
|
|
3
2
|
import { type SpecType, type SpecDriver } from './spec-driver';
|
|
4
3
|
import { type Driver } from './driver';
|
|
5
4
|
import { type Element } from './element';
|
|
@@ -7,18 +6,16 @@ export declare class HelperIOS<T extends SpecType> {
|
|
|
7
6
|
static make<T extends SpecType>(options: {
|
|
8
7
|
spec: SpecDriver<T>;
|
|
9
8
|
driver: Driver<T>;
|
|
10
|
-
logger: Logger;
|
|
11
9
|
}): Promise<HelperIOS<T> | null>;
|
|
12
|
-
private readonly _driver;
|
|
13
10
|
private readonly _element;
|
|
11
|
+
private readonly _driver;
|
|
14
12
|
private readonly _spec;
|
|
15
|
-
private _logger;
|
|
16
13
|
readonly name: 'ios';
|
|
17
14
|
constructor(options: {
|
|
18
15
|
driver: Driver<T>;
|
|
19
16
|
element: Element<T>;
|
|
20
17
|
spec: SpecDriver<T>;
|
|
21
|
-
logger: Logger;
|
|
22
18
|
});
|
|
19
|
+
get logger(): import("@applitools/logger").Logger;
|
|
23
20
|
getContentRegion(element: Element<T>): Promise<Region | null>;
|
|
24
21
|
}
|