@applitools/driver 1.13.3 → 1.13.5

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 CHANGED
@@ -1,5 +1,51 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.13.5](https://github.com/applitools/eyes.sdk.javascript1/compare/js/driver@1.13.4...js/driver@1.13.5) (2023-08-18)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * optimize driver usage in close ([#1867](https://github.com/applitools/eyes.sdk.javascript1/issues/1867)) ([60dff6b](https://github.com/applitools/eyes.sdk.javascript1/commit/60dff6b160e69d3893c91a1125d668fa18b43072))
9
+
10
+
11
+ ### Code Refactoring
12
+
13
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
14
+
15
+
16
+ ### Dependencies
17
+
18
+ * @applitools/utils bumped to 1.5.1
19
+ #### Code Refactoring
20
+
21
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
22
+ * @applitools/logger bumped to 2.0.8
23
+ #### Code Refactoring
24
+
25
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
26
+
27
+
28
+
29
+ * @applitools/snippets bumped to 2.4.23
30
+ #### Code Refactoring
31
+
32
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
33
+
34
+ ## [1.13.4](https://github.com/applitools/eyes.sdk.javascript1/compare/js/driver@1.13.3...js/driver@1.13.4) (2023-08-03)
35
+
36
+
37
+ ### Bug Fixes
38
+
39
+ * extract device orientation from a browser for web executions ([d8d4e91](https://github.com/applitools/eyes.sdk.javascript1/commit/d8d4e919965fb9105915e762c397ec2cc57a8a71))
40
+
41
+
42
+ ### Dependencies
43
+
44
+ * @applitools/snippets bumped to 2.4.22
45
+ #### Bug Fixes
46
+
47
+ * improve orientation extraction for ios devices ([378d989](https://github.com/applitools/eyes.sdk.javascript1/commit/378d9894e4fbc7247087ccb8c46266dc4737e2e5))
48
+
3
49
  ## [1.13.3](https://github.com/applitools/eyes.sdk.javascript1/compare/js/driver@1.13.2...js/driver@1.13.3) (2023-07-21)
4
50
 
5
51
 
package/dist/context.js CHANGED
@@ -27,14 +27,12 @@ exports.Context = void 0;
27
27
  const selector_1 = require("./selector");
28
28
  const element_1 = require("./element");
29
29
  const utils = __importStar(require("@applitools/utils"));
30
- const specUtils = __importStar(require("./spec-utils"));
31
30
  const snippets = require('@applitools/snippets');
32
31
  class Context {
33
32
  _isReference(reference) {
34
33
  return (utils.types.isInteger(reference) ||
35
34
  utils.types.isString(reference) ||
36
- reference instanceof element_1.Element ||
37
- this._spec.isElement(reference) ||
35
+ (0, element_1.isElement)(reference, this._spec) ||
38
36
  (0, selector_1.isSelector)(reference, this._spec));
39
37
  }
40
38
  constructor(options) {
@@ -104,11 +102,11 @@ class Context {
104
102
  await this.focus();
105
103
  const { parent, all, wait } = options;
106
104
  const environment = await this.driver.getEnvironment();
107
- const transformedSelector = specUtils.transformSelector(this._spec, selector, environment);
105
+ const transformedSelector = (0, selector_1.makeSelector)({ selector, spec: this._spec, environment });
108
106
  let elements = [];
109
107
  if (wait) {
110
108
  if (this._spec.waitForSelector) {
111
- const element = await this._spec.waitForSelector(this.target, specUtils.transformSelector(this._spec, selector, environment), parent, wait);
109
+ const element = await this._spec.waitForSelector(this.target, (0, selector_1.makeSelector)({ selector, spec: this._spec, environment }), parent, wait);
112
110
  if (element)
113
111
  elements = [element];
114
112
  }
@@ -116,7 +114,7 @@ class Context {
116
114
  let waiting = true;
117
115
  const timeout = setTimeout(() => (waiting = false), wait.timeout);
118
116
  while (waiting) {
119
- const element = await this._spec.findElement(this.target, specUtils.transformSelector(this._spec, selector, environment), parent);
117
+ const element = await this._spec.findElement(this.target, (0, selector_1.makeSelector)({ selector, spec: this._spec, environment }), parent);
120
118
  if (element) {
121
119
  clearTimeout(timeout);
122
120
  elements = [element];
@@ -134,7 +132,7 @@ class Context {
134
132
  if (element)
135
133
  elements = [element];
136
134
  }
137
- if ((0, selector_1.isObjectCommonSelector)(selector, this._spec)) {
135
+ if ((0, selector_1.isComplexSelector)(selector, this._spec)) {
138
136
  if (elements.length > 0) {
139
137
  if (selector.child) {
140
138
  elements = await elements.reduce((result, element) => {
@@ -197,12 +195,13 @@ class Context {
197
195
  throw new TypeError(`Context element with name, id, or selector ${JSON.stringify(this._reference)}' is not found`);
198
196
  }
199
197
  }
200
- else if (this._spec.isElement(this._reference) || this._reference instanceof element_1.Element) {
198
+ else if ((0, element_1.isElement)(this._reference, this._spec)) {
201
199
  this.logger.log('Initialize context from reference element', this._reference);
202
- this._element =
203
- this._reference instanceof element_1.Element
204
- ? this._reference
205
- : new element_1.Element({ spec: this._spec, context: this.parent, element: this._reference });
200
+ this._element = await (0, element_1.makeElement)({
201
+ spec: this._spec,
202
+ context: this.parent,
203
+ element: this._reference,
204
+ });
206
205
  }
207
206
  else {
208
207
  throw new TypeError('Reference type does not supported');
@@ -267,38 +266,38 @@ class Context {
267
266
  }
268
267
  }
269
268
  async element(elementOrSelector) {
270
- if (this._spec.isElement(elementOrSelector)) {
271
- return new element_1.Element({ spec: this._spec, context: this, element: elementOrSelector });
269
+ if ((0, element_1.isElement)(elementOrSelector, this._spec)) {
270
+ return (0, element_1.makeElement)({ spec: this._spec, context: this, element: elementOrSelector });
272
271
  }
273
272
  else if (!(0, selector_1.isSelector)(elementOrSelector, this._spec)) {
274
273
  throw new TypeError('Cannot find element using argument of unknown type!');
275
274
  }
276
275
  if (this.isRef) {
277
- return new element_1.Element({ spec: this._spec, context: this, selector: elementOrSelector });
276
+ return (0, element_1.makeElement)({ spec: this._spec, context: this, selector: elementOrSelector });
278
277
  }
279
278
  this.logger.log('Finding element by selector: ', elementOrSelector);
280
279
  const [element] = await this._findElements(elementOrSelector, { all: false });
281
- return element ? new element_1.Element({ spec: this._spec, context: this, element, selector: elementOrSelector }) : null;
280
+ return element ? (0, element_1.makeElement)({ spec: this._spec, context: this, element, selector: elementOrSelector }) : null;
282
281
  }
283
282
  async elements(selectorOrElement) {
284
283
  if ((0, selector_1.isSelector)(selectorOrElement, this._spec)) {
285
284
  if (this.isRef) {
286
- return [new element_1.Element({ spec: this._spec, context: this, selector: selectorOrElement })];
285
+ return [await (0, element_1.makeElement)({ spec: this._spec, context: this, selector: selectorOrElement })];
287
286
  }
288
287
  this.logger.log('Finding elements by selector: ', selectorOrElement);
289
288
  const elements = await this._findElements(selectorOrElement, { all: true });
290
- return elements.map((element, index) => {
291
- return new element_1.Element({
289
+ return Promise.all(elements.map((element, index) => {
290
+ return (0, element_1.makeElement)({
292
291
  spec: this._spec,
293
292
  context: this,
294
293
  element,
295
294
  selector: selectorOrElement,
296
295
  index,
297
296
  });
298
- });
297
+ }));
299
298
  }
300
- else if (this._spec.isElement(selectorOrElement)) {
301
- return [new element_1.Element({ spec: this._spec, context: this, element: selectorOrElement })];
299
+ else if ((0, element_1.isElement)(selectorOrElement, this._spec)) {
300
+ return [await (0, element_1.makeElement)({ spec: this._spec, context: this, element: selectorOrElement })];
302
301
  }
303
302
  else {
304
303
  throw new TypeError('Cannot find elements using argument of unknown type!');
@@ -309,7 +308,7 @@ class Context {
309
308
  const [element] = await this._findElements(selector, {
310
309
  wait: { state: 'exist', timeout: 10000, interval: 500, ...options },
311
310
  });
312
- return element ? new element_1.Element({ spec: this._spec, context: this, element, selector }) : null;
311
+ return element ? (0, element_1.makeElement)({ spec: this._spec, context: this, element, selector }) : null;
313
312
  }
314
313
  async execute(script, arg) {
315
314
  await this.focus();
@@ -323,8 +322,8 @@ class Context {
323
322
  }
324
323
  function serialize(value) {
325
324
  var _a, _b;
326
- if (this._spec.isElement(value) || value instanceof element_1.Element) {
327
- return value instanceof element_1.Element ? value.toJSON() : value;
325
+ if ((0, element_1.isElement)(value, this._spec)) {
326
+ return (0, element_1.isElementInstance)(value) ? value.toJSON() : value;
328
327
  }
329
328
  else if (utils.types.isArray(value)) {
330
329
  return value.map(value => serialize.call(this, value));
@@ -390,7 +389,7 @@ class Context {
390
389
  return (_a = this._element) !== null && _a !== void 0 ? _a : null;
391
390
  }
392
391
  async getScrollingElement() {
393
- if (!(this._scrollingElement instanceof element_1.Element)) {
392
+ if (!(0, element_1.isElementInstance)(this._scrollingElement)) {
394
393
  await this.focus();
395
394
  const environment = await this.driver.getEnvironment();
396
395
  if (this._scrollingElement) {
@@ -420,8 +419,7 @@ class Context {
420
419
  else if (scrollingElement === null)
421
420
  this._scrollingElement = null;
422
421
  else {
423
- this._scrollingElement =
424
- scrollingElement instanceof element_1.Element ? scrollingElement : await this.element(scrollingElement);
422
+ this._scrollingElement = await this.element(scrollingElement);
425
423
  }
426
424
  }
427
425
  async blurElement(element) {
@@ -31,14 +31,14 @@ async function checkSpecDriver(options) {
31
31
  assert_1.strict.ok(isElements, 'script returns elements inside nested structure and could be executed with a nested structure of elements');
32
32
  },
33
33
  'find element with string selector': async () => {
34
- const selector = transformSelector('html>body>h1');
34
+ const selector = toSelector('html>body>h1');
35
35
  const element = await spec.findElement(context, selector);
36
36
  const isWantedElement = await spec.executeScript(context, `return arguments[0] === document.querySelector("${selector}")`, element);
37
37
  assert_1.strict.ok(isWantedElement, `returns element by string selector - "${selector}"`);
38
38
  },
39
39
  'find element with spec selector': async () => {
40
- const cssSelector = transformSelector({ type: 'css', selector: 'html>body>h1' });
41
- const xpathSelector = transformSelector({ type: 'xpath', selector: '//html/body/h1' });
40
+ const cssSelector = toSelector({ type: 'css', selector: 'html>body>h1' });
41
+ const xpathSelector = toSelector({ type: 'xpath', selector: '//html/body/h1' });
42
42
  const verificationScript = `return arguments[0] === document.querySelector('html>body>h1')`;
43
43
  const cssElement = await spec.findElement(context, cssSelector);
44
44
  const isCssElement = await spec.executeScript(context, verificationScript, cssElement);
@@ -48,19 +48,19 @@ async function checkSpecDriver(options) {
48
48
  assert_1.strict.ok(isXpathElement, `returns element by spec selector - ${JSON.stringify(xpathSelector)}`);
49
49
  },
50
50
  'find element with unresolvable selector': async () => {
51
- const selector = transformSelector('unresolvable_selector');
51
+ const selector = toSelector('unresolvable_selector');
52
52
  const element = await spec.findElement(context, selector);
53
53
  assert_1.strict.equal(element, null, `returns null by unresolvable selector - "${selector}"`);
54
54
  },
55
55
  'find elements with string selector': async () => {
56
- const selector = transformSelector('html p');
56
+ const selector = toSelector('html p');
57
57
  const elements = await spec.findElements(context, selector);
58
58
  const isExpectedElements = await spec.executeScript(context, `var expected = arguments[0]; return Array.prototype.every.call(document.querySelectorAll("${selector}"), function(element, index) { return element === expected[index] })`, elements);
59
59
  assert_1.strict.ok(isExpectedElements, `returns elements by string selector - "${selector}"`);
60
60
  },
61
61
  'find elements with spec selector': async () => {
62
- const cssSelector = transformSelector({ type: 'css', selector: 'html p' });
63
- const xpathSelector = transformSelector({ type: 'xpath', selector: '//html//p' });
62
+ const cssSelector = toSelector({ type: 'css', selector: 'html p' });
63
+ const xpathSelector = toSelector({ type: 'xpath', selector: '//html//p' });
64
64
  const verificationScript = `var expected = arguments[0]; return Array.prototype.every.call(document.querySelectorAll('html p'), function(element, index) { return element === expected[index] })`;
65
65
  const cssElements = await spec.findElements(context, cssSelector);
66
66
  const isCssElements = await spec.executeScript(context, verificationScript, cssElements);
@@ -70,12 +70,12 @@ async function checkSpecDriver(options) {
70
70
  assert_1.strict.ok(isXpathElements, `returns element by spec selector - ${JSON.stringify(xpathSelector)}`);
71
71
  },
72
72
  'find elements with unresolvable selector': async () => {
73
- const selector = transformSelector('unresolvable_selector');
73
+ const selector = toSelector('unresolvable_selector');
74
74
  const element = await spec.findElements(context, selector);
75
75
  assert_1.strict.deepEqual(element, [], `returns empty array by unresolvable selector - "${selector}"`);
76
76
  },
77
77
  'child context': async () => {
78
- const element = await spec.findElement(context, transformSelector('[name="frame1"]'));
78
+ const element = await spec.findElement(context, toSelector('[name="frame1"]'));
79
79
  const childContext = await spec.childContext(context, element);
80
80
  const inFrame = await spec.executeScript(childContext, 'return window.frameElement.name === "frame1"');
81
81
  assert_1.strict.ok(inFrame, 'returns or switches to a child context');
@@ -85,7 +85,7 @@ async function checkSpecDriver(options) {
85
85
  'is equal elements': async () => {
86
86
  if (!spec.isEqualElements)
87
87
  return { skipped: true };
88
- const htmlEl = await spec.findElement(context, transformSelector('html'));
88
+ const htmlEl = await spec.findElement(context, toSelector('html'));
89
89
  const htmlEl2 = await spec.executeScript(context, 'return document.documentElement');
90
90
  assert_1.strict.ok(await spec.isEqualElements(context, htmlEl, htmlEl2), 'elements should be equal');
91
91
  const bodyEl = await spec.executeScript(context, 'return document.body');
@@ -94,32 +94,34 @@ async function checkSpecDriver(options) {
94
94
  assert_1.strict.ok(!(await spec.isEqualElements(context, undefined, htmlEl)), 'isEqualElements should return false if one of the arguments is falsy');
95
95
  },
96
96
  'main context': async () => {
97
- const mainDocument1 = await spec.findElement(context, transformSelector('html'));
98
- const childContext1 = await spec.childContext(context, (await spec.findElement(context, transformSelector('[name="frame1"]'))));
99
- const childContext2 = await spec.childContext(childContext1, (await spec.findElement(childContext1, transformSelector('[name="frame1-1"]'))));
100
- const frameDocument = await spec.findElement(childContext2, transformSelector('html'));
97
+ const mainDocument1 = await spec.findElement(context, toSelector('html'));
98
+ const childContext1 = await spec.childContext(context, (await spec.findElement(context, toSelector('[name="frame1"]'))));
99
+ const childContext2 = await spec.childContext(childContext1, (await spec.findElement(childContext1, toSelector('[name="frame1-1"]'))));
100
+ const frameDocument = await spec.findElement(childContext2, toSelector('html'));
101
101
  assert_1.strict.ok(!(await isEqualElements(childContext2, mainDocument1, frameDocument)));
102
102
  const mainContext = await spec.mainContext(childContext2);
103
- const mainDocument2 = await spec.findElement(mainContext, transformSelector('html'));
103
+ const mainDocument2 = await spec.findElement(mainContext, toSelector('html'));
104
104
  assert_1.strict.ok(await isEqualElements(mainContext, mainDocument2, mainDocument1));
105
105
  },
106
106
  'parent context': async () => {
107
- const parentContext1 = await spec.childContext(context, (await spec.findElement(context, transformSelector('[name="frame1"]'))));
108
- const parentDocument1 = await spec.findElement(parentContext1, transformSelector('html'));
109
- const frameContext = await spec.childContext(parentContext1, (await spec.findElement(parentContext1, transformSelector('[name="frame1-1"]'))));
110
- const frameDocument = await spec.findElement(frameContext, transformSelector('html'));
107
+ const parentContext1 = await spec.childContext(context, (await spec.findElement(context, toSelector('[name="frame1"]'))));
108
+ const parentDocument1 = await spec.findElement(parentContext1, toSelector('html'));
109
+ const frameContext = await spec.childContext(parentContext1, (await spec.findElement(parentContext1, toSelector('[name="frame1-1"]'))));
110
+ const frameDocument = await spec.findElement(frameContext, toSelector('html'));
111
111
  assert_1.strict.ok(!(await isEqualElements(frameContext, parentDocument1, frameDocument)));
112
112
  const parentContext2 = await spec.parentContext(frameContext);
113
- const parentDocument2 = await spec.findElement(parentContext2, transformSelector('html'));
113
+ const parentDocument2 = await spec.findElement(parentContext2, toSelector('html'));
114
114
  assert_1.strict.ok(await isEqualElements(parentContext2, parentDocument2, parentDocument1));
115
115
  await spec.mainContext(context);
116
116
  },
117
117
  'get title': async () => {
118
- const title = await spec.getTitle(driver);
118
+ var _a;
119
+ const title = await ((_a = spec.getTitle) === null || _a === void 0 ? void 0 : _a.call(spec, driver));
119
120
  assert_1.strict.equal(title, 'Cross SDK test', 'returns title of the current page');
120
121
  },
121
122
  'get url': async () => {
122
- const url = await spec.getUrl(driver);
123
+ var _a;
124
+ const url = await ((_a = spec.getUrl) === null || _a === void 0 ? void 0 : _a.call(spec, driver));
123
125
  assert_1.strict.equal(url, 'https://applitools.github.io/demo/TestPages/FramesTestPage/', 'returns url of the current page');
124
126
  },
125
127
  'is driver': async () => {
@@ -129,7 +131,7 @@ async function checkSpecDriver(options) {
129
131
  assert_1.strict.ok(!(await spec.isDriver('str')), 'string should not be considered a driver');
130
132
  },
131
133
  'is element': async () => {
132
- const el = await spec.findElement(context, transformSelector('html'));
134
+ const el = await spec.findElement(context, toSelector('html'));
133
135
  assert_1.strict.ok(await spec.isElement(el), 'element should be considered an element :)');
134
136
  assert_1.strict.ok(!(await spec.isElement(undefined)), 'undefined should not be considered an element');
135
137
  assert_1.strict.ok(!(await spec.isElement(3)), 'number should not be considered an element');
@@ -151,17 +153,17 @@ async function checkSpecDriver(options) {
151
153
  }
152
154
  }
153
155
  return report;
154
- function isEqualElements(context, element1, element2) {
156
+ async function isEqualElements(context, element1, element2) {
155
157
  var _a, _b;
156
- return ((_b = (_a = spec.isEqualElements) === null || _a === void 0 ? void 0 : _a.call(spec, context, element1, element2)) !== null && _b !== void 0 ? _b : spec.executeScript(context, snippets.isEqualElements, [element1, element2]).catch(() => false));
158
+ return ((_b = (await ((_a = spec.isEqualElements) === null || _a === void 0 ? void 0 : _a.call(spec, context, element1, element2)))) !== null && _b !== void 0 ? _b : spec.executeScript(context, snippets.isEqualElements, [element1, element2]).catch(() => false));
157
159
  }
158
160
  function extractContext(driver) {
159
161
  var _a, _b;
160
162
  return (_b = (_a = spec.extractContext) === null || _a === void 0 ? void 0 : _a.call(spec, driver)) !== null && _b !== void 0 ? _b : driver;
161
163
  }
162
- function transformSelector(selector) {
164
+ function toSelector(selector) {
163
165
  var _a, _b;
164
- return (_b = (_a = spec.transformSelector) === null || _a === void 0 ? void 0 : _a.call(spec, selector)) !== null && _b !== void 0 ? _b : selector;
166
+ return (_b = (_a = spec.toSelector) === null || _a === void 0 ? void 0 : _a.call(spec, selector)) !== null && _b !== void 0 ? _b : selector;
165
167
  }
166
168
  }
167
169
  exports.checkSpecDriver = checkSpecDriver;
package/dist/driver.js CHANGED
@@ -23,19 +23,19 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.makeDriver = exports.isDriver = exports.Driver = void 0;
27
- const context_1 = require("./context");
26
+ exports.makeDriver = exports.isDriver = exports.isDriverInstance = exports.Driver = void 0;
28
27
  const logger_1 = require("@applitools/logger");
28
+ const context_1 = require("./context");
29
+ const selector_1 = require("./selector");
29
30
  const helper_ios_1 = require("./helper-ios");
30
31
  const helper_android_1 = require("./helper-android");
31
32
  const user_agent_1 = require("./user-agent");
32
33
  const capabilities_1 = require("./capabilities");
33
- const specUtils = __importStar(require("./spec-utils"));
34
34
  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;
39
39
  this._state = {};
40
40
  this._customConfig = {};
41
41
  this._original = this;
@@ -43,13 +43,13 @@ class Driver {
43
43
  this._customConfig = (_a = options.customConfig) !== null && _a !== void 0 ? _a : {};
44
44
  this._guid = utils.general.guid();
45
45
  this._spec = options.spec;
46
- 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
+ this._target = options.driver;
47
47
  if (!this._spec.isDriver(this._target)) {
48
48
  throw new TypeError('Driver constructor called with argument of unknown type!');
49
49
  }
50
50
  this._mainContext = new context_1.Context({
51
51
  spec: this._spec,
52
- 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
+ context: (_d = (_c = (_b = this._spec).extractContext) === null || _c === void 0 ? void 0 : _c.call(_b, this._target)) !== null && _d !== void 0 ? _d : this._target,
53
53
  driver: this,
54
54
  });
55
55
  this._currentContext = this._mainContext;
@@ -124,9 +124,6 @@ class Driver {
124
124
  },
125
125
  });
126
126
  }
127
- function transformSelector(selector) {
128
- return specUtils.transformSelector(spec, selector, { isWeb: true });
129
- }
130
127
  async function getContextInfo(context) {
131
128
  const [documentElement, selector, isRoot, isCORS] = await spec.executeScript(context, snippets.getContextInfo);
132
129
  return { documentElement, selector, isRoot, isCORS };
@@ -143,7 +140,7 @@ class Driver {
143
140
  }
144
141
  async function findContextReference(context, contextInfo) {
145
142
  if (contextInfo.selector) {
146
- const contextElement = await spec.findElement(context, transformSelector({ type: 'xpath', selector: contextInfo.selector }));
143
+ const contextElement = await spec.findElement(context, (0, selector_1.makeSelector)({ selector: { type: 'xpath', selector: contextInfo.selector }, spec, environment: { isWeb: true } }));
147
144
  if (contextElement)
148
145
  return contextElement;
149
146
  }
@@ -151,7 +148,7 @@ class Driver {
151
148
  if (childContextInfo.isCORS !== contextInfo.isCORS)
152
149
  continue;
153
150
  const childContext = await spec.childContext(context, childContextInfo.contextElement);
154
- const contentDocument = await spec.findElement(childContext, transformSelector('html'));
151
+ const contentDocument = await spec.findElement(childContext, (0, selector_1.makeSelector)({ selector: 'html', spec, environment: { isWeb: true } }));
155
152
  const isWantedContext = await isEqualElements(childContext, contentDocument, contextInfo.documentElement);
156
153
  await spec.parentContext(childContext);
157
154
  if (isWantedContext)
@@ -160,7 +157,7 @@ class Driver {
160
157
  return null;
161
158
  }
162
159
  async function findContextPath(context, contextInfo, contextPath = []) {
163
- const contentDocument = await spec.findElement(context, transformSelector('html'));
160
+ const contentDocument = await spec.findElement(context, (0, selector_1.makeSelector)({ selector: 'html', spec, environment: { isWeb: true } }));
164
161
  if (await isEqualElements(context, contentDocument, contextInfo.documentElement)) {
165
162
  return contextPath;
166
163
  }
@@ -458,6 +455,11 @@ class Driver {
458
455
  }
459
456
  }
460
457
  async getSessionMetadata() {
458
+ var _a;
459
+ // NOTE: not using this.getEnvironment() to not provoke environment extraction if it was not calculated yet.
460
+ // It is faster to try to execute and fail then collect all of the environment information
461
+ if (((_a = this._environment) === null || _a === void 0 ? void 0 : _a.isECClient) === false)
462
+ return undefined;
461
463
  try {
462
464
  const metadata = await this.currentContext.execute('applitools:metadata');
463
465
  this._logger.log('Extracted session metadata', metadata);
@@ -679,7 +681,7 @@ class Driver {
679
681
  const environment = await this.getEnvironment();
680
682
  if (environment.isMobile && !environment.isEmulation)
681
683
  return;
682
- if (this._spec.setViewportSize) {
684
+ if (this._spec.setViewportSize && (!this._spec.setWindowSize || environment.isChromium)) {
683
685
  this._logger.log('Setting viewport size to', size, 'using spec method');
684
686
  await this._spec.setViewportSize(this.target, size);
685
687
  return;
@@ -734,7 +736,7 @@ class Driver {
734
736
  const environment = await this.getEnvironment();
735
737
  if (!environment.isMobile)
736
738
  return undefined;
737
- if (environment.isEmulation)
739
+ if (environment.isWeb)
738
740
  return (_a = this._viewport) === null || _a === void 0 ? void 0 : _a.orientation;
739
741
  if (environment.isAndroid) {
740
742
  this._logger.log('Extracting device orientation using adb command on android');
@@ -788,18 +790,20 @@ class Driver {
788
790
  }
789
791
  }
790
792
  async getTitle() {
793
+ var _a, _b, _c;
791
794
  const environment = await this.getEnvironment();
792
795
  if (environment.isNative)
793
796
  return undefined;
794
- const title = await this._spec.getTitle(this.target);
797
+ const title = (_c = (await ((_b = (_a = this._spec).getTitle) === null || _b === void 0 ? void 0 : _b.call(_a, this.target)))) !== null && _c !== void 0 ? _c : '';
795
798
  this._logger.log('Extracted title:', title);
796
799
  return title;
797
800
  }
798
801
  async getUrl() {
802
+ var _a, _b, _c;
799
803
  const environment = await this.getEnvironment();
800
804
  if (environment.isNative)
801
805
  return undefined;
802
- const url = await this._spec.getUrl(this.target);
806
+ const url = (_c = (await ((_b = (_a = this._spec).getUrl) === null || _b === void 0 ? void 0 : _b.call(_a, this.target)))) !== null && _c !== void 0 ? _c : '';
803
807
  this._logger.log('Extracted url:', url);
804
808
  return url;
805
809
  }
@@ -821,12 +825,27 @@ class Driver {
821
825
  }
822
826
  }
823
827
  exports.Driver = Driver;
828
+ function isDriverInstance(driver) {
829
+ return driver instanceof Driver;
830
+ }
831
+ exports.isDriverInstance = isDriverInstance;
824
832
  function isDriver(driver, spec) {
825
- return driver instanceof Driver || !!(spec === null || spec === void 0 ? void 0 : spec.isDriver(driver));
833
+ var _a;
834
+ return isDriverInstance(driver) || !!(spec === null || spec === void 0 ? void 0 : spec.isDriver(driver)) || !!((_a = spec === null || spec === void 0 ? void 0 : spec.isSecondaryDriver) === null || _a === void 0 ? void 0 : _a.call(spec, driver));
826
835
  }
827
836
  exports.isDriver = isDriver;
828
837
  async function makeDriver(options) {
829
- const driver = options.driver instanceof Driver ? options.driver : new Driver(options);
838
+ var _a, _b, _c;
839
+ let driver;
840
+ if (options.driver instanceof Driver) {
841
+ driver = options.driver;
842
+ if (options.relaxed)
843
+ return driver;
844
+ }
845
+ else {
846
+ options.driver = (_c = (await ((_b = (_a = options.spec) === null || _a === void 0 ? void 0 : _a.toDriver) === null || _b === void 0 ? void 0 : _b.call(_a, options.driver)))) !== null && _c !== void 0 ? _c : options.driver;
847
+ driver = new Driver(options);
848
+ }
830
849
  if (options.logger)
831
850
  driver.updateLogger(options.logger);
832
851
  return driver.refresh({ reset: options.reset });
package/dist/element.js CHANGED
@@ -23,21 +23,21 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.isElementReference = exports.Element = void 0;
26
+ exports.makeElement = exports.isElementReference = exports.isElement = exports.isElementInstance = exports.Element = void 0;
27
27
  const selector_1 = require("./selector");
28
28
  const utils = __importStar(require("@applitools/utils"));
29
29
  const snippets = require('@applitools/snippets');
30
30
  class Element {
31
31
  constructor(options) {
32
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
32
+ var _a, _b, _c, _d, _e, _f;
33
33
  this._state = {};
34
34
  this._spec = options.spec;
35
35
  this._context = options.context;
36
36
  if (utils.types.has(options, 'element')) {
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;
37
+ this._target = options.element;
38
38
  if (this._spec.isElement(this._target)) {
39
39
  // Some frameworks contains information about the selector inside an element
40
- this._selector = (_d = options.selector) !== null && _d !== void 0 ? _d : (_f = (_e = this._spec).extractSelector) === null || _f === void 0 ? void 0 : _f.call(_e, options.element);
40
+ this._selector = (_a = options.selector) !== null && _a !== void 0 ? _a : (_c = (_b = this._spec).extractSelector) === null || _c === void 0 ? void 0 : _c.call(_b, options.element);
41
41
  this._index = options.index;
42
42
  }
43
43
  }
@@ -50,8 +50,8 @@ class Element {
50
50
  if ((0, selector_1.isSimpleCommonSelector)(this._selector) && !utils.types.isString(this._selector)) {
51
51
  this._commonSelector = this._selector;
52
52
  }
53
- else if (this._selector && this._spec.untransformSelector) {
54
- this._commonSelector = this._spec.untransformSelector((_j = (_h = (_g = this._spec).transformSelector) === null || _h === void 0 ? void 0 : _h.call(_g, this._selector)) !== null && _j !== void 0 ? _j : this._selector);
53
+ else if (this._selector && this._spec.toSimpleCommonSelector) {
54
+ this._commonSelector = this._spec.toSimpleCommonSelector((_f = (_e = (_d = this._spec).toSelector) === null || _e === void 0 ? void 0 : _e.call(_d, this._selector)) !== null && _f !== void 0 ? _f : this._selector);
55
55
  }
56
56
  else if (utils.types.isString(this._selector)) {
57
57
  this._commonSelector = { selector: this._selector };
@@ -624,6 +624,11 @@ class Element {
624
624
  return this.getScrollOffset();
625
625
  }
626
626
  }
627
+ async hover() {
628
+ var _a, _b;
629
+ this.logger.log(`Hovering on the element with selector`, this.selector);
630
+ await ((_b = (_a = this._spec).hover) === null || _b === void 0 ? void 0 : _b.call(_a, this.context.target, this.target));
631
+ }
627
632
  async click() {
628
633
  var _a, _b;
629
634
  this.logger.log(`Clicking on the element with selector`, this.selector);
@@ -722,7 +727,34 @@ class Element {
722
727
  }
723
728
  }
724
729
  exports.Element = Element;
730
+ function isElementInstance(element) {
731
+ return element instanceof Element;
732
+ }
733
+ exports.isElementInstance = isElementInstance;
734
+ function isElement(element, spec) {
735
+ var _a;
736
+ return isElementInstance(element) || !!(spec === null || spec === void 0 ? void 0 : spec.isElement(element)) || !!((_a = spec === null || spec === void 0 ? void 0 : spec.isSecondaryElement) === null || _a === void 0 ? void 0 : _a.call(spec, element));
737
+ }
738
+ exports.isElement = isElement;
725
739
  function isElementReference(reference, spec) {
726
- return !!spec && (spec.isElement(reference) || (0, selector_1.isSelector)(reference, spec));
740
+ return isElement(reference, spec) || (0, selector_1.isSelector)(reference, spec);
727
741
  }
728
742
  exports.isElementReference = isElementReference;
743
+ async function makeElement(options) {
744
+ var _a, _b, _c;
745
+ let element;
746
+ if (utils.types.has(options, 'element')) {
747
+ if (options.element instanceof Element) {
748
+ element = options.element;
749
+ }
750
+ else {
751
+ options.element = (_c = (await ((_b = (_a = options.spec) === null || _a === void 0 ? void 0 : _a.toElement) === null || _b === void 0 ? void 0 : _b.call(_a, options.element)))) !== null && _c !== void 0 ? _c : options.element;
752
+ element = new Element(options);
753
+ }
754
+ }
755
+ else {
756
+ element = new Element(options);
757
+ }
758
+ return element;
759
+ }
760
+ exports.makeElement = makeElement;
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.visit = exports.getTitle = exports.getUrl = exports.getOrientation = exports.setWindowSize = exports.getWindowSize = exports.getDriverInfo = exports.takeScreenshot = exports.childContext = exports.parentContext = exports.mainContext = exports.getElementText = exports.findElements = exports.findElement = exports.executeScript = exports.isEqualElements = exports.isStaleElementError = exports.extractSelector = exports.untransformSelector = exports.transformSelector = exports.isSelector = exports.isElement = exports.isDriver = void 0;
26
+ exports.visit = exports.getTitle = exports.getUrl = exports.getOrientation = exports.setWindowSize = exports.getWindowSize = exports.getDriverInfo = exports.takeScreenshot = exports.childContext = exports.parentContext = exports.mainContext = exports.getElementText = exports.findElements = exports.findElement = exports.executeScript = exports.isEqualElements = exports.isStaleElementError = exports.extractSelector = exports.toSimpleCommonSelector = exports.toSelector = exports.isSelector = exports.isElement = exports.isDriver = void 0;
27
27
  const utils = __importStar(require("@applitools/utils"));
28
28
  function isDriver(driver) {
29
29
  return driver && driver.constructor.name === 'MockDriver';
@@ -41,11 +41,11 @@ function isSelector(selector) {
41
41
  return (utils.types.isString(selector) || utils.types.has(selector, ['using', 'value']) || (selector === null || selector === void 0 ? void 0 : selector.forceSelector) === true);
42
42
  }
43
43
  exports.isSelector = isSelector;
44
- function transformSelector(selector) {
44
+ function toSelector(selector) {
45
45
  return utils.types.has(selector, 'selector') ? selector.selector : selector;
46
46
  }
47
- exports.transformSelector = transformSelector;
48
- function untransformSelector(selector) {
47
+ exports.toSelector = toSelector;
48
+ function toSimpleCommonSelector(selector) {
49
49
  if (utils.types.isString(selector)) {
50
50
  return { type: 'css', selector: selector };
51
51
  }
@@ -57,7 +57,7 @@ function untransformSelector(selector) {
57
57
  }
58
58
  return null;
59
59
  }
60
- exports.untransformSelector = untransformSelector;
60
+ exports.toSimpleCommonSelector = toSimpleCommonSelector;
61
61
  function extractSelector(element) {
62
62
  if (utils.types.has(element, ['selector'])) {
63
63
  return element.selector;
package/dist/index.js CHANGED
@@ -10,27 +10,13 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
10
10
  if (k2 === undefined) k2 = k;
11
11
  o[k2] = m[k];
12
12
  }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
13
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
19
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
15
  };
21
- var __importStar = (this && this.__importStar) || function (mod) {
22
- if (mod && mod.__esModule) return mod;
23
- var result = {};
24
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25
- __setModuleDefault(result, mod);
26
- return result;
27
- };
28
16
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.specUtils = void 0;
30
17
  __exportStar(require("./spec-driver"), exports);
31
18
  __exportStar(require("./driver"), exports);
32
19
  __exportStar(require("./context"), exports);
33
20
  __exportStar(require("./element"), exports);
34
21
  __exportStar(require("./selector"), exports);
35
22
  __exportStar(require("./types"), exports);
36
- exports.specUtils = __importStar(require("./spec-utils"));
package/dist/selector.js CHANGED
@@ -23,20 +23,41 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.isSimpleCommonSelector = exports.isObjectCommonSelector = exports.isSelector = void 0;
26
+ exports.makeSelector = exports.isSimpleCommonSelector = exports.isComplexSelector = exports.isSelector = void 0;
27
27
  const utils = __importStar(require("@applitools/utils"));
28
28
  function isSelector(selector, spec) {
29
- return (spec === null || spec === void 0 ? void 0 : spec.isSelector(selector)) || utils.types.isString(selector) || isObjectCommonSelector(selector, spec);
29
+ var _a;
30
+ return ((spec === null || spec === void 0 ? void 0 : spec.isSelector(selector)) ||
31
+ ((_a = spec === null || spec === void 0 ? void 0 : spec.isSecondarySelector) === null || _a === void 0 ? void 0 : _a.call(spec, selector)) ||
32
+ utils.types.isString(selector) ||
33
+ isComplexSelector(selector, spec));
30
34
  }
31
35
  exports.isSelector = isSelector;
32
- function isObjectCommonSelector(selector, spec) {
36
+ function isComplexSelector(selector, spec) {
33
37
  return (utils.types.isPlainObject(selector) &&
34
38
  utils.types.has(selector, 'selector') &&
35
39
  Object.keys(selector).every(key => ['selector', 'type', 'frame', 'shadow', 'child', 'fallback'].includes(key)) &&
36
40
  (utils.types.isString(selector.selector) || !!(spec === null || spec === void 0 ? void 0 : spec.isSelector(selector.selector))));
37
41
  }
38
- exports.isObjectCommonSelector = isObjectCommonSelector;
42
+ exports.isComplexSelector = isComplexSelector;
39
43
  function isSimpleCommonSelector(selector) {
40
- return utils.types.isString(selector) || isObjectCommonSelector(selector);
44
+ return utils.types.isString(selector) || isComplexSelector(selector);
41
45
  }
42
46
  exports.isSimpleCommonSelector = isSimpleCommonSelector;
47
+ function makeSelector(options) {
48
+ var _a, _b;
49
+ const { spec, environment } = options;
50
+ let selector = options.selector;
51
+ if ((environment === null || environment === void 0 ? void 0 : environment.isWeb) && isComplexSelector(selector, spec)) {
52
+ if (selector.type === 'id')
53
+ selector = { type: 'css', selector: `#${selector.selector}` };
54
+ else if (selector.type === 'name')
55
+ selector = { type: 'css', selector: `[name="${selector.selector}"]` };
56
+ else if (selector.type === 'class name')
57
+ selector = { type: 'css', selector: `.${selector.selector}` };
58
+ else if (selector.type === 'tag name')
59
+ selector = { type: 'css', selector: `${selector.selector}` };
60
+ }
61
+ return (_b = (_a = spec.toSelector) === null || _a === void 0 ? void 0 : _a.call(spec, selector)) !== null && _b !== void 0 ? _b : selector;
62
+ }
63
+ exports.makeSelector = makeSelector;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/driver",
3
- "version": "1.13.3",
3
+ "version": "1.13.5",
4
4
  "description": "Applitools universal framework wrapper",
5
5
  "keywords": [
6
6
  "applitools",
@@ -73,9 +73,9 @@
73
73
  "test": "run --top-level mocha './test/**/*.spec.ts'"
74
74
  },
75
75
  "dependencies": {
76
- "@applitools/logger": "2.0.7",
77
- "@applitools/snippets": "2.4.21",
78
- "@applitools/utils": "1.5.0",
76
+ "@applitools/logger": "2.0.8",
77
+ "@applitools/snippets": "2.4.23",
78
+ "@applitools/utils": "1.5.1",
79
79
  "semver": "7.5.4"
80
80
  },
81
81
  "devDependencies": {
@@ -3,7 +3,7 @@ import type { Cookie } from './types';
3
3
  import { type SpecType, type SpecDriver, type WaitOptions } from './spec-driver';
4
4
  import { type Driver } from './driver';
5
5
  import { type Selector } from './selector';
6
- import { Element, type ElementReference } from './element';
6
+ import { type ElementReference, type Element } from './element';
7
7
  export type ContextReference<T extends SpecType> = Element<T> | ElementReference<T> | string | number;
8
8
  export type NestedContextReference<T extends SpecType> = {
9
9
  reference: ContextReference<T>;
package/types/driver.d.ts CHANGED
@@ -4,8 +4,8 @@ import type { DriverInfo, Capabilities, UserAgent, Environment, Viewport, Featur
4
4
  import { type Selector } from './selector';
5
5
  import { type SpecType, type SpecDriver, type WaitOptions } from './spec-driver';
6
6
  import { type Element } from './element';
7
- import { Context, type ContextReference } from './context';
8
7
  import { type Logger } from '@applitools/logger';
8
+ import { Context, type ContextReference } from './context';
9
9
  import { HelperIOS } from './helper-ios';
10
10
  import { HelperAndroid } from './helper-android';
11
11
  type DriverOptions<T extends SpecType> = {
@@ -87,14 +87,16 @@ export declare class Driver<T extends SpecType> {
87
87
  execute(script: ((arg: any) => any) | string, arg?: any): Promise<any>;
88
88
  visit(url: string): Promise<void>;
89
89
  }
90
- export declare function isDriver<T extends SpecType>(driver: any, spec?: SpecDriver<T>): driver is Driver<T> | T['driver'];
90
+ export declare function isDriverInstance<T extends SpecType>(driver: any): driver is Driver<T>;
91
+ export declare function isDriver<T extends SpecType>(driver: any, spec?: SpecDriver<T>): driver is Driver<T> | T['driver'] | T['secondary']['driver'];
91
92
  export declare function makeDriver<T extends SpecType>(options: {
92
- driver: Driver<T> | T['driver'];
93
+ driver: Driver<T> | T['driver'] | T['secondary']['driver'];
93
94
  spec?: SpecDriver<T>;
94
95
  customConfig?: {
95
96
  useCeilForViewportSize?: boolean;
96
97
  };
97
98
  reset?: boolean;
99
+ relaxed?: boolean;
98
100
  logger?: Logger;
99
101
  }): Promise<Driver<T>>;
100
102
  export {};
@@ -2,7 +2,7 @@ import type { Location, Size, Region } from '@applitools/utils';
2
2
  import { type SpecType, type SpecDriver } from './spec-driver';
3
3
  import { type Context } from './context';
4
4
  import { type Selector, type CommonSelector } from './selector';
5
- export type ElementReference<T extends SpecType> = T['element'] | Selector<T>;
5
+ export type ElementReference<T extends SpecType> = T['element'] | T['secondary']['element'] | Selector<T>;
6
6
  type ElementState = {
7
7
  contentSize?: Size;
8
8
  scrollOffset?: Location;
@@ -74,6 +74,7 @@ export declare class Element<T extends SpecType> {
74
74
  getScrollOffset(): Promise<Location>;
75
75
  getTranslateOffset(): Promise<Location>;
76
76
  getInnerOffset(): Promise<Location>;
77
+ hover(): Promise<void>;
77
78
  click(): Promise<void>;
78
79
  type(value: string): Promise<void>;
79
80
  preserveState(): Promise<ElementState>;
@@ -84,5 +85,18 @@ export declare class Element<T extends SpecType> {
84
85
  withRefresh<TResult>(operation: (...args: any[]) => TResult): Promise<TResult>;
85
86
  toJSON(): T['element'];
86
87
  }
88
+ export declare function isElementInstance<T extends SpecType>(element: any): element is Element<T>;
89
+ export declare function isElement<T extends SpecType>(element: any, spec?: SpecDriver<T>): element is Element<T> | T['element'] | T['secondary']['element'];
87
90
  export declare function isElementReference<T extends SpecType>(reference: any, spec?: SpecDriver<T>): reference is ElementReference<T>;
91
+ export declare function makeElement<T extends SpecType>(options: {
92
+ spec: SpecDriver<T>;
93
+ context?: Context<T>;
94
+ } & ({
95
+ element: Element<T> | T['element'] | T['secondary']['element'];
96
+ selector?: Selector<T>;
97
+ index?: number;
98
+ } | {
99
+ selector: Selector<T>;
100
+ index?: number;
101
+ })): Promise<Element<T>>;
88
102
  export {};
@@ -14,10 +14,10 @@ type CommonSelector = string | {
14
14
  export declare function isDriver(driver: any): driver is Driver;
15
15
  export declare function isElement(element: any): element is Element;
16
16
  export declare function isSelector(selector: any): selector is Selector;
17
- export declare function transformSelector(selector: Selector | {
17
+ export declare function toSelector(selector: Selector | {
18
18
  selector: Selector;
19
19
  }): Selector;
20
- export declare function untransformSelector(selector: Selector): CommonSelector | null;
20
+ export declare function toSimpleCommonSelector(selector: Selector): CommonSelector | null;
21
21
  export declare function extractSelector(element: Element): any;
22
22
  export declare function isStaleElementError(): boolean;
23
23
  export declare function isEqualElements(_driver: Driver, element1: Element, element2: Element): Promise<boolean>;
package/types/index.d.ts CHANGED
@@ -4,4 +4,3 @@ export * from './context';
4
4
  export * from './element';
5
5
  export * from './selector';
6
6
  export * from './types';
7
- export * as specUtils from './spec-utils';
@@ -1,5 +1,5 @@
1
1
  import { type SpecType, type SpecDriver } from './spec-driver';
2
- export type Selector<T extends SpecType = never> = T['selector'] | CommonSelector<T['selector']>;
2
+ export type Selector<T extends SpecType = never> = T['selector'] | T['secondary']['selector'] | CommonSelector<T['selector'] | T['secondary']['selector']>;
3
3
  export type CommonSelector<TSelector = never> = string | ComplexSelector<TSelector>;
4
4
  type ComplexSelector<TSelector> = {
5
5
  selector: TSelector | string;
@@ -9,7 +9,17 @@ type ComplexSelector<TSelector> = {
9
9
  frame?: TSelector | string | CommonSelector<TSelector>;
10
10
  fallback?: TSelector | string | CommonSelector<TSelector>;
11
11
  };
12
- export declare function isSelector<T extends SpecType>(selector: any, spec?: Pick<SpecDriver<T>, 'isSelector'>): selector is Selector<T>;
13
- export declare function isObjectCommonSelector<T extends SpecType>(selector: any, spec?: Pick<SpecDriver<T>, 'isSelector'>): selector is Exclude<CommonSelector<T['selector']>, string>;
12
+ export declare function isSelector<T extends SpecType>(selector: any, spec?: Pick<SpecDriver<T>, 'isSelector' | 'isSecondarySelector'>): selector is Selector<T>;
13
+ export declare function isComplexSelector<T extends SpecType>(selector: any, spec?: Pick<SpecDriver<T>, 'isSelector'>): selector is Exclude<CommonSelector<T['selector']>, string>;
14
14
  export declare function isSimpleCommonSelector(selector: any): selector is CommonSelector;
15
+ export declare function makeSelector<T extends SpecType>(options: {
16
+ selector: Selector<T>;
17
+ spec: Pick<SpecDriver<T>, 'isSelector' | 'toSelector'>;
18
+ environment?: {
19
+ isWeb?: boolean;
20
+ isNative?: boolean;
21
+ isIOS?: boolean;
22
+ isAndroid?: boolean;
23
+ };
24
+ }): T['selector'];
15
25
  export {};
@@ -2,47 +2,105 @@
2
2
  import type { Size, Region } from '@applitools/utils';
3
3
  import type { DriverInfo, Capabilities, ScreenOrientation, Cookie } from './types';
4
4
  import { type CommonSelector } from './selector';
5
- export type SpecType<TDriver = unknown, TContext = unknown, TElement = unknown, TSelector = unknown> = {
5
+ export type SpecType<TDriver = unknown, TContext = unknown, TElement = unknown, TSelector = unknown, TSecondary extends SpecType = SpecType<unknown, unknown, unknown, unknown, never>> = {
6
6
  driver: TDriver;
7
7
  context: TContext;
8
8
  element: TElement;
9
9
  selector: TSelector;
10
+ secondary: TSecondary;
10
11
  };
11
12
  export interface SpecDriver<T extends SpecType> {
13
+ /**
14
+ * Assures that the given driver has a speced type.
15
+ */
12
16
  isDriver(driver: any): driver is T['driver'];
17
+ /**
18
+ * Assures that the given driver has a secondary type.
19
+ */
20
+ isSecondaryDriver?(driver: any): driver is T['secondary']['driver'];
21
+ /**
22
+ * Assures that the given context has a speced type.
23
+ * (applicable only to cdp-like specs.)
24
+ */
13
25
  isContext?(context: any): context is T['context'];
26
+ /**
27
+ * Assures that the given context has a secondary type.
28
+ */
29
+ isSecondaryContext?(context: any): context is T['secondary']['context'];
30
+ /**
31
+ * Assures that the given element has a speced type.
32
+ */
14
33
  isElement(element: any): element is T['element'];
34
+ /**
35
+ * Assures that the given element has a secondary type.
36
+ */
37
+ isSecondaryElement?(element: any): element is T['secondary']['element'];
38
+ /**
39
+ * Assures that the given selector has a speced context.
40
+ */
15
41
  isSelector(selector: any): selector is T['selector'];
16
- transformDriver?(driver: any): T['driver'];
17
- transformElement?(element: any): T['element'];
18
- transformSelector?(selector: CommonSelector<T['selector']> | T['selector']): T['selector'];
19
- untransformSelector?(selector: T['selector']): CommonSelector | null;
20
- extractContext?(element: T['driver'] | T['context']): T['context'];
21
- extractSelector?(element: T['element']): T['selector'];
42
+ /**
43
+ * Assures that the given selector has a secondary type.
44
+ */
45
+ isSecondarySelector?(selector: any): selector is T['secondary']['selector'];
46
+ /**
47
+ * Assures that two given elements are equal.
48
+ * (should be implemented only if there is different a different method then in-browser comparison.)
49
+ */
50
+ isEqualElements?(context: T['context'], element1: T['element'], element2: T['element']): boolean | Promise<boolean>;
51
+ /**
52
+ * Assures that the error is a stale element error.
53
+ */
22
54
  isStaleElementError(error: any, selector?: T['selector']): boolean;
23
- isEqualElements?(context: T['context'], element1: T['element'], element2: T['element']): Promise<boolean>;
24
- extractHostName?(driver: T['driver']): string | null;
25
- mainContext(context: T['context']): Promise<T['context']>;
26
- parentContext?(context: T['context']): Promise<T['context']>;
27
- childContext(context: T['context'], element: T['element']): Promise<T['context']>;
55
+ /**
56
+ * Converts the given driver to a speced driver.
57
+ * (applicable in cases when spec has certain variations or sub-types of the driver.)
58
+ */
59
+ toDriver?(driver: T['secondary']['driver']): T['driver'] | Promise<T['driver']>;
60
+ /**
61
+ * Transforms the given element to a speced element.
62
+ * (applicable in cases when spec has certain variations or sub-types of the element.)
63
+ */
64
+ toElement?(element: T['secondary']['element']): T['element'] | Promise<T['element']>;
65
+ /**
66
+ * Transforms the given common selector to a speced selector.
67
+ */
68
+ toSelector?(selector: T['secondary']['selector'] | CommonSelector<T['selector']>): T['selector'];
69
+ /**
70
+ * Transforms the given speced selector to simple common selector if possible.
71
+ */
72
+ toSimpleCommonSelector?(selector: T['selector']): CommonSelector | null;
73
+ /**
74
+ * Extracts context from the given driver.
75
+ */
76
+ extractContext?(element: T['driver']): T['context'];
77
+ /**
78
+ * Extracts selector from the given element if possible.
79
+ * (should be implemented in cases when speced type of the element contains selector in itself.)
80
+ */
81
+ extractSelector?(element: T['element']): T['selector'] | null;
82
+ /**
83
+ * Executes given script in the given contexts with given argument.
84
+ */
28
85
  executeScript(context: T['context'], script: ((arg?: any) => any) | string, arg?: any): Promise<any>;
29
86
  findElement(context: T['context'], selector: T['selector'], parent?: T['element']): Promise<T['element'] | null>;
30
87
  findElements(context: T['context'], selector: T['selector'], parent?: T['element']): Promise<T['element'][]>;
31
88
  waitForSelector?(context: T['context'], selector: T['selector'], parent?: T['element'], options?: WaitOptions): Promise<T['element'] | null>;
89
+ getElementRegion?(context: T['context'], element: T['element']): Promise<Region>;
90
+ getElementAttribute?(context: T['context'], element: T['element'], attr: string): Promise<string>;
32
91
  setElementText?(context: T['context'], element: T['element'], text: string): Promise<void>;
33
92
  getElementText?(context: T['context'], element: T['element']): Promise<string>;
93
+ hover?(context: T['context'], element: T['element']): Promise<void>;
94
+ click?(context: T['context'], element: T['element']): Promise<void>;
95
+ mainContext(context: T['context']): Promise<T['context']>;
96
+ parentContext?(context: T['context']): Promise<T['context']>;
97
+ childContext(context: T['context'], element: T['element']): Promise<T['context']>;
98
+ getDriverInfo?(driver: T['driver']): Promise<DriverInfo>;
99
+ getCapabilities?(driver: T['driver']): Promise<Capabilities>;
34
100
  setWindowSize?(driver: T['driver'], size: Size): Promise<void>;
35
101
  getWindowSize?(driver: T['driver']): Promise<Size>;
36
102
  setViewportSize?(driver: T['driver'], size: Size): Promise<void>;
37
103
  getViewportSize?(driver: T['driver']): Promise<Size>;
38
- getCookies?(driver: T['driver'] | T['context'], context?: boolean): Promise<Cookie[]>;
39
- getDriverInfo?(driver: T['driver']): Promise<DriverInfo>;
40
- getCapabilities?(driver: T['driver']): Promise<Capabilities>;
41
- getTitle(driver: T['driver']): Promise<string>;
42
- getUrl(driver: T['driver']): Promise<string>;
43
- takeScreenshot(driver: T['driver']): Promise<Buffer | string>;
44
- click?(context: T['context'], element: T['element'] | T['selector']): Promise<void>;
45
- visit?(driver: T['driver'], url: string): Promise<void>;
46
104
  getOrientation?(driver: T['driver']): Promise<ScreenOrientation>;
47
105
  setOrientation?(driver: T['driver'], orientation: ScreenOrientation): Promise<void>;
48
106
  getSystemBars?(driver: T['driver']): Promise<{
@@ -61,9 +119,12 @@ export interface SpecDriver<T extends SpecType> {
61
119
  width: number;
62
120
  };
63
121
  }>;
64
- getElementRegion?(driver: T['driver'], element: T['element']): Promise<Region>;
65
- getElementAttribute?(driver: T['driver'], element: T['element'], attr: string): Promise<string>;
122
+ getCookies?(driver: T['driver'] | T['context'], context?: boolean): Promise<Cookie[]>;
123
+ getTitle?(driver: T['driver']): Promise<string>;
124
+ getUrl?(driver: T['driver']): Promise<string>;
125
+ visit?(driver: T['driver'], url: string): Promise<void>;
66
126
  performAction?(driver: T['driver'], steps: any[]): Promise<void>;
127
+ takeScreenshot(driver: T['driver']): Promise<Buffer | string>;
67
128
  getCurrentWorld?(driver: T['driver']): Promise<string>;
68
129
  getWorlds?(driver: T['driver']): Promise<string[]>;
69
130
  switchWorld?(driver: T['driver'], id: string): Promise<void>;
@@ -0,0 +1,2 @@
1
+ import { type SpecType, type SpecDriver } from './spec-driver';
2
+ export declare function withFastCache<TSpecDriver extends SpecDriver<SpecType>>(spec: TSpecDriver): TSpecDriver;
@@ -1,76 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withFastCache = exports.splitSelector = exports.transformSelector = void 0;
4
- const selector_1 = require("./selector");
5
- function transformSelector(spec, selector, environment) {
6
- var _a, _b;
7
- if ((environment === null || environment === void 0 ? void 0 : environment.isWeb) && (0, selector_1.isObjectCommonSelector)(selector, spec)) {
8
- if (selector.type === 'id')
9
- selector = { type: 'css', selector: `#${selector.selector}` };
10
- else if (selector.type === 'name')
11
- selector = { type: 'css', selector: `[name="${selector.selector}"]` };
12
- else if (selector.type === 'class name')
13
- selector = { type: 'css', selector: `.${selector.selector}` };
14
- else if (selector.type === 'tag name')
15
- selector = { type: 'css', selector: `${selector.selector}` };
16
- }
17
- selector;
18
- return (_b = (_a = spec.transformSelector) === null || _a === void 0 ? void 0 : _a.call(spec, selector)) !== null && _b !== void 0 ? _b : selector;
19
- }
20
- exports.transformSelector = transformSelector;
21
- function splitSelector(spec, selector) {
22
- let targetSelector = selector;
23
- let activeSelector = {};
24
- let elementSelector = activeSelector;
25
- const contextSelectors = [];
26
- while (targetSelector) {
27
- if ((0, selector_1.isObjectCommonSelector)(targetSelector, spec)) {
28
- activeSelector.selector = targetSelector.selector;
29
- if (targetSelector.type)
30
- activeSelector.type = targetSelector.type;
31
- if (targetSelector.child) {
32
- activeSelector = activeSelector.child = {};
33
- targetSelector = targetSelector.child;
34
- }
35
- else if (targetSelector.shadow) {
36
- activeSelector = activeSelector.shadow = {};
37
- targetSelector = targetSelector.shadow;
38
- }
39
- else if (targetSelector.frame) {
40
- contextSelectors.push(elementSelector);
41
- elementSelector = activeSelector = {};
42
- targetSelector = targetSelector.frame;
43
- }
44
- else {
45
- targetSelector = null;
46
- }
47
- }
48
- else {
49
- activeSelector.selector = targetSelector;
50
- targetSelector = null;
51
- }
52
- }
53
- return { contextSelectors, elementSelector };
54
- }
55
- exports.splitSelector = splitSelector;
56
- function withFastCache(spec) {
57
- const cache = new Map();
58
- return Object.entries(spec).reduce((spec, [name, command]) => {
59
- spec[name] = (...args) => {
60
- const value = cache.get(command);
61
- if ((value === null || value === void 0 ? void 0 : value.args.length) === args.length && value.args.every((arg, index) => arg === args[index])) {
62
- return value.result;
63
- }
64
- else {
65
- cache.delete(command);
66
- }
67
- const result = command(...args);
68
- if (!(result instanceof Promise))
69
- return result;
70
- cache.set(command, { args, result });
71
- return result.finally(() => setImmediate(() => cache.delete(command)));
72
- };
73
- return spec;
74
- }, {});
75
- }
76
- exports.withFastCache = withFastCache;