-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlazy-element.js
105 lines (96 loc) · 3.2 KB
/
lazy-element.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
const functionNames = require("./element-function-names");
/**
* This class will replace the element returned by the wdio $.
* This will be usefull to allow us to avoid async/awaits when creating new
* Page Objects and will allow us to use getters and chain promises.
*/
class LazyElement {
/**
*
* @param {string} selector Element selector
* @param {LazyElement} parent Element parent if it exists
* @param {number} index Index of the pretended element. Used when retrieving an LazyElement
* from the LazyElementGroup class
*/
constructor({ selector, parent, index }) {
if (parent && Number.isInteger(index)) {
this.getElement = () => parent.getElement().then(parentElement => parentElement[index]);
return;
}
if (parent) {
this.getElement = () => parent.getElement().then(parentElement => parentElement.$(selector));
return;
}
// eslint-disable-next-line no-undef
this.getElement = () => browser.$(selector);
}
}
/**
* This class will replace the Array of elements returned by the wdio $$.
* This will be usefull to allow us to avoid async/awaits when creating new
* Page Objects and will allow us to use getters and chain promises.
*/
class LazyElementGroup {
/**
* LazyElementGroup constructor.
*
* @param {string} selector Elements selector
* @param {LazyElement} parent parent element
*/
constructor({ selector, parent }) {
if (parent) {
this.getElement = () => parent.getElement().then(parentElement => parentElement.$$(selector));
return;
}
// eslint-disable-next-line no-undef
this.getElement = () => browser.$$(selector);
}
/**
* Get a LazyElement at a specific index of this LazyElementGroup
* @param {number} index Index of the pretended element
* @returns {LazyElement}
*/
get(index) {
return new LazyElement({ parent: this, index });
}
/**
* Gives us the number of Elements on the LazyElementGroup
*/
get length() {
return this.getElement().then(element => element.length);
}
}
/**
* Function to find an element and return an LazyElement
* instead of the wdio Promise<WebdriverIOAsync.Element>.
* @param {string} selector The element selector
* @returns {LazyElement} A Lazy Element
*/
function findElement(selector) {
return new LazyElement({ parent: this, selector });
}
/**
* Function to find an elements and return an LazyElementGroup
* instead of the wdio Array.<Promise<WebdriverIOAsync.Element>>.
* @param {string} selector The element selector
* @returns {LazyElementGroup} A Lazy Element Group
*/
function findElements(selector) {
return new LazyElementGroup({ parent: this, selector });
}
/**
* Override the prototype selector functions with ours
*/
LazyElement.prototype.$ = findElement;
LazyElement.prototype.$$ = findElements;
LazyElementGroup.prototype.$ = findElement;
LazyElementGroup.prototype.$$ = findElements;
/**
* Override all the Element functions so we are able to chain Promises
*/
functionNames.forEach(functionName => {
LazyElement.prototype[functionName] = function getLazyElementAndCall(...args) {
return this.getElement().then(element => element[functionName](...args));
};
});
module.exports = { LazyElement, LazyElementGroup };