webdriverio 5.11.11 → 5.11.12
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/build/commands/browser/$$.js +0 -42
- package/build/commands/browser/$.js +0 -42
- package/build/commands/browser/call.js +0 -38
- package/build/commands/browser/debug.js +1 -21
- package/build/commands/browser/deleteCookies.js +0 -43
- package/build/commands/browser/execute.js +0 -43
- package/build/commands/browser/executeAsync.js +0 -51
- package/build/commands/browser/getCookies.js +0 -32
- package/build/commands/browser/getWindowSize.js +0 -20
- package/build/commands/browser/keys.js +0 -36
- package/build/commands/browser/newWindow.js +0 -37
- package/build/commands/browser/pause.js +0 -21
- package/build/commands/browser/react$$.js +0 -24
- package/build/commands/browser/react$.js +0 -28
- package/build/commands/browser/reloadSession.js +1 -28
- package/build/commands/browser/saveRecordingScreen.js +0 -23
- package/build/commands/browser/saveScreenshot.js +0 -22
- package/build/commands/browser/setCookies.js +0 -46
- package/build/commands/browser/setTimeout.js +1 -38
- package/build/commands/browser/setWindowSize.js +0 -25
- package/build/commands/browser/switchWindow.js +0 -38
- package/build/commands/browser/touchAction.js +0 -60
- package/build/commands/browser/uploadFile.js +0 -32
- package/build/commands/browser/url.js +0 -33
- package/build/commands/browser/waitUntil.js +0 -40
- package/build/commands/constant.js +0 -18
- package/build/commands/element/$$.js +0 -39
- package/build/commands/element/$.js +0 -43
- package/build/commands/element/addValue.js +1 -28
- package/build/commands/element/clearValue.js +0 -26
- package/build/commands/element/click.js +0 -43
- package/build/commands/element/doubleClick.js +0 -30
- package/build/commands/element/dragAndDrop.js +1 -21
- package/build/commands/element/getAttribute.js +0 -26
- package/build/commands/element/getCSSProperty.js +0 -66
- package/build/commands/element/getHTML.js +1 -33
- package/build/commands/element/getLocation.js +0 -27
- package/build/commands/element/getProperty.js +0 -16
- package/build/commands/element/getSize.js +0 -27
- package/build/commands/element/getTagName.js +0 -23
- package/build/commands/element/getText.js +0 -40
- package/build/commands/element/getValue.js +0 -24
- package/build/commands/element/isDisplayed.js +1 -62
- package/build/commands/element/isDisplayedInViewport.js +1 -39
- package/build/commands/element/isEnabled.js +0 -32
- package/build/commands/element/isExisting.js +0 -40
- package/build/commands/element/isFocused.js +1 -29
- package/build/commands/element/isSelected.js +0 -29
- package/build/commands/element/moveTo.js +0 -21
- package/build/commands/element/react$$.js +0 -25
- package/build/commands/element/react$.js +0 -29
- package/build/commands/element/saveScreenshot.js +0 -21
- package/build/commands/element/scrollIntoView.js +2 -26
- package/build/commands/element/selectByAttribute.js +0 -46
- package/build/commands/element/selectByIndex.js +0 -40
- package/build/commands/element/selectByVisibleText.js +1 -43
- package/build/commands/element/setValue.js +0 -25
- package/build/commands/element/shadow$$.js +0 -18
- package/build/commands/element/shadow$.js +0 -18
- package/build/commands/element/touchAction.js +0 -53
- package/build/commands/element/waitForDisplayed.js +0 -37
- package/build/commands/element/waitForEnabled.js +0 -35
- package/build/commands/element/waitForExist.js +0 -38
- package/build/commands/element/waitUntil.js +0 -6
- package/build/constants.js +0 -128
- package/build/index.js +0 -25
- package/build/middlewares.js +0 -14
- package/build/multiremote.js +0 -46
- package/build/scripts/getHTML.js +0 -7
- package/build/scripts/getProperty.js +0 -6
- package/build/scripts/isDisplayedInViewport.js +0 -5
- package/build/scripts/isElementDisplayed.js +10 -71
- package/build/scripts/isFocused.js +0 -5
- package/build/scripts/newWindow.js +0 -8
- package/build/scripts/resq.js +2 -7
- package/build/scripts/shadowFnFactory.js +0 -1
- package/build/utils/Timer.js +4 -23
- package/build/utils/findStrategy.js +16 -48
- package/build/utils/getElementObject.js +0 -25
- package/build/utils/implicitWait.js +0 -12
- package/build/utils/refetchElement.js +2 -15
- package/build/utils.js +3 -119
- package/package.json +3 -3
- package/webdriverio-core.d.ts +0 -8
|
@@ -5,11 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = isDisplayedInViewport;
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* check if element is visible and within the viewport
|
|
10
|
-
* @param {HTMLElement} elem element to check
|
|
11
|
-
* @return {Boolean} true if element is within viewport
|
|
12
|
-
*/
|
|
13
8
|
function isDisplayedInViewport(elem) {
|
|
14
9
|
const dde = document.documentElement;
|
|
15
10
|
let isWithinViewport = true;
|
|
@@ -5,36 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = isElementDisplayed;
|
|
7
7
|
|
|
8
|
-
/*
|
|
9
|
-
* Copyright (C) 2017 Apple Inc. All rights reserved.
|
|
10
|
-
*
|
|
11
|
-
* Redistribution and use in source and binary forms, with or without
|
|
12
|
-
* modification, are permitted provided that the following conditions
|
|
13
|
-
* are met:
|
|
14
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
15
|
-
* notice, this list of conditions and the following disclaimer.
|
|
16
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
17
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
18
|
-
* documentation and/or other materials provided with the distribution.
|
|
19
|
-
*
|
|
20
|
-
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
|
|
21
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
22
|
-
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
23
|
-
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
|
|
24
|
-
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
-
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
-
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
-
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
-
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
-
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
30
|
-
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* check if element is visible
|
|
35
|
-
* @param {HTMLElement} elem element to check
|
|
36
|
-
* @return {Boolean} true if element is within viewport
|
|
37
|
-
*/
|
|
38
8
|
function isElementDisplayed(element) {
|
|
39
9
|
function nodeIsElement(node) {
|
|
40
10
|
if (!node) {
|
|
@@ -79,10 +49,7 @@ function isElementDisplayed(element) {
|
|
|
79
49
|
function cascadedStylePropertyForElement(element, property) {
|
|
80
50
|
if (!element || !property) {
|
|
81
51
|
return null;
|
|
82
|
-
}
|
|
83
|
-
// when the element is inside a shadow root.
|
|
84
|
-
// window.getComputedStyle errors on document-fragment.
|
|
85
|
-
|
|
52
|
+
}
|
|
86
53
|
|
|
87
54
|
if (element instanceof DocumentFragment) {
|
|
88
55
|
element = element.host;
|
|
@@ -93,15 +60,7 @@ function isElementDisplayed(element) {
|
|
|
93
60
|
|
|
94
61
|
if (computedStyleProperty && computedStyleProperty !== 'inherit') {
|
|
95
62
|
return computedStyleProperty;
|
|
96
|
-
}
|
|
97
|
-
// it doesn't for legacy reasons. So we need to do our own poor man's cascade.
|
|
98
|
-
// Fall back to the first non-'inherit' value found in an ancestor.
|
|
99
|
-
// In any case, getPropertyValue will not return 'initial'.
|
|
100
|
-
// FIXME: will this incorrectly inherit non-inheritable CSS properties?
|
|
101
|
-
// I think all important non-inheritable properties (width, height, etc.)
|
|
102
|
-
// for our purposes here are specially resolved, so this may not be an issue.
|
|
103
|
-
// Specification is here: https://drafts.csswg.org/cssom/#resolved-values
|
|
104
|
-
|
|
63
|
+
}
|
|
105
64
|
|
|
106
65
|
let parentElement = parentElementForElement(element);
|
|
107
66
|
return cascadedStylePropertyForElement(parentElement, property);
|
|
@@ -112,8 +71,7 @@ function isElementDisplayed(element) {
|
|
|
112
71
|
|
|
113
72
|
if (boundingBox.width > 0 && boundingBox.height > 0) {
|
|
114
73
|
return true;
|
|
115
|
-
}
|
|
116
|
-
|
|
74
|
+
}
|
|
117
75
|
|
|
118
76
|
if (element.tagName.toUpperCase() === 'PATH' && boundingBox.width + boundingBox.height > 0) {
|
|
119
77
|
let strokeWidth = cascadedStylePropertyForElement(element, 'stroke-width');
|
|
@@ -124,9 +82,7 @@ function isElementDisplayed(element) {
|
|
|
124
82
|
|
|
125
83
|
if (cascadedOverflow === 'hidden') {
|
|
126
84
|
return false;
|
|
127
|
-
}
|
|
128
|
-
// container to have non-zero dimensions if a child node has non-zero dimensions.
|
|
129
|
-
|
|
85
|
+
}
|
|
130
86
|
|
|
131
87
|
return Array.from(element.childNodes).some(childNode => {
|
|
132
88
|
if (childNode.nodeType === Node.TEXT_NODE) {
|
|
@@ -146,10 +102,7 @@ function isElementDisplayed(element) {
|
|
|
146
102
|
|
|
147
103
|
if (cascadedOverflow !== 'hidden') {
|
|
148
104
|
return false;
|
|
149
|
-
}
|
|
150
|
-
// the display modes of it and its ancestors, and the container it overflows.
|
|
151
|
-
// See Selenium's bot.dom.getOverflowState atom for an exhaustive list of edge cases.
|
|
152
|
-
|
|
105
|
+
}
|
|
153
106
|
|
|
154
107
|
return true;
|
|
155
108
|
}
|
|
@@ -165,13 +118,9 @@ function isElementDisplayed(element) {
|
|
|
165
118
|
|
|
166
119
|
if (!element.childNodes.length) {
|
|
167
120
|
return false;
|
|
168
|
-
}
|
|
169
|
-
|
|
121
|
+
}
|
|
170
122
|
|
|
171
123
|
return Array.from(element.childNodes).every(childNode => {
|
|
172
|
-
// Returns true if the child node is overflowed or otherwise hidden.
|
|
173
|
-
// Base case: not an element, has zero size, scrolled out, or doesn't overflow container.
|
|
174
|
-
// Visibility of text nodes is controlled by parent
|
|
175
124
|
if (childNode.nodeType === Node.TEXT_NODE) {
|
|
176
125
|
return false;
|
|
177
126
|
}
|
|
@@ -182,13 +131,11 @@ function isElementDisplayed(element) {
|
|
|
182
131
|
|
|
183
132
|
if (!elementSubtreeHasNonZeroDimensions(childNode)) {
|
|
184
133
|
return true;
|
|
185
|
-
}
|
|
186
|
-
|
|
134
|
+
}
|
|
187
135
|
|
|
188
136
|
return isElementSubtreeHiddenByOverflow(childNode);
|
|
189
137
|
});
|
|
190
|
-
}
|
|
191
|
-
|
|
138
|
+
}
|
|
192
139
|
|
|
193
140
|
function isElementInsideShadowRoot(element) {
|
|
194
141
|
if (!element) {
|
|
@@ -200,15 +147,11 @@ function isElementDisplayed(element) {
|
|
|
200
147
|
}
|
|
201
148
|
|
|
202
149
|
return isElementInsideShadowRoot(element.parentNode);
|
|
203
|
-
}
|
|
204
|
-
// When the W3C specification's algorithm stabilizes, we should implement that.
|
|
205
|
-
// If this command is misdirected to the wrong document (and is NOT inside a shadow root), treat it as not shown.
|
|
206
|
-
|
|
150
|
+
}
|
|
207
151
|
|
|
208
152
|
if (!isElementInsideShadowRoot(element) && !document.contains(element)) {
|
|
209
153
|
return false;
|
|
210
|
-
}
|
|
211
|
-
|
|
154
|
+
}
|
|
212
155
|
|
|
213
156
|
switch (element.tagName.toUpperCase()) {
|
|
214
157
|
case 'BODY':
|
|
@@ -221,20 +164,16 @@ function isElementDisplayed(element) {
|
|
|
221
164
|
case 'OPTGROUP':
|
|
222
165
|
case 'OPTION':
|
|
223
166
|
{
|
|
224
|
-
// Option/optgroup are considered shown if the containing <select> is shown.
|
|
225
167
|
let enclosingSelectElement = enclosingNodeOrSelfMatchingPredicate(element, e => e.tagName.toUpperCase() === 'SELECT');
|
|
226
168
|
return isElementDisplayed(enclosingSelectElement);
|
|
227
169
|
}
|
|
228
170
|
|
|
229
171
|
case 'INPUT':
|
|
230
|
-
// <input type="hidden"> is considered not shown.
|
|
231
172
|
if (element.type === 'hidden') {
|
|
232
173
|
return false;
|
|
233
174
|
}
|
|
234
175
|
|
|
235
176
|
break;
|
|
236
|
-
// case 'MAP':
|
|
237
|
-
// FIXME: Selenium has special handling for <map> elements. We don't do anything now.
|
|
238
177
|
|
|
239
178
|
default:
|
|
240
179
|
break;
|
|
@@ -5,11 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = _default;
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* checks if given element is focused
|
|
10
|
-
* @param {HTMLElement} elem element to check
|
|
11
|
-
* @return {Boolean} true if element is focused
|
|
12
|
-
*/
|
|
13
8
|
function _default(elem) {
|
|
14
9
|
return elem === document.activeElement;
|
|
15
10
|
}
|
|
@@ -5,14 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = newWindow;
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* opens new window via window.open
|
|
10
|
-
* @param {String} url The URL to be loaded in the newly opened window.
|
|
11
|
-
* @param {String} windowName A string name for the new window.
|
|
12
|
-
* @param {String} windowFeatures An optional parameter listing the features (size, position, scrollbars, etc.) of the new window as a string.
|
|
13
|
-
*
|
|
14
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window.open
|
|
15
|
-
*/
|
|
16
8
|
function newWindow(url, windowName = 'new window', windowFeatures = '') {
|
|
17
9
|
window.open(url, windowName, windowFeatures);
|
|
18
10
|
}
|
package/build/scripts/resq.js
CHANGED
|
@@ -26,9 +26,7 @@ const react$ = function react$(selector, props = {}, state = {}, reactElement) {
|
|
|
26
26
|
return {
|
|
27
27
|
message: `React element with selector "${selector}" wasn't found`
|
|
28
28
|
};
|
|
29
|
-
}
|
|
30
|
-
// if the element is a fragment, we return the first child to be passed into the driver
|
|
31
|
-
|
|
29
|
+
}
|
|
32
30
|
|
|
33
31
|
return element.isFragment ? element.node[0] : element.node;
|
|
34
32
|
};
|
|
@@ -48,10 +46,7 @@ const react$$ = function react$$(selector, props, state, reactElement) {
|
|
|
48
46
|
|
|
49
47
|
if (!elements.length) {
|
|
50
48
|
return [];
|
|
51
|
-
}
|
|
52
|
-
// this avoids having nested arrays of nodes which the driver does not understand
|
|
53
|
-
// [[div, div], [div, div]] => [div, div, div, div]
|
|
54
|
-
|
|
49
|
+
}
|
|
55
50
|
|
|
56
51
|
let nodes = [];
|
|
57
52
|
elements.forEach(element => {
|
package/build/utils/Timer.js
CHANGED
|
@@ -8,15 +8,6 @@ exports.default = void 0;
|
|
|
8
8
|
var _config = require("@wdio/config");
|
|
9
9
|
|
|
10
10
|
const TIMEOUT_ERROR = 'timeout';
|
|
11
|
-
/**
|
|
12
|
-
* Promise-based Timer. Execute fn every tick.
|
|
13
|
-
* When fn is resolved — timer will stop
|
|
14
|
-
* @param {Number} delay - delay between ticks
|
|
15
|
-
* @param {Number} timeout - after that time timer will stop
|
|
16
|
-
* @param {Function} fn - function that returns promise. will execute every tick
|
|
17
|
-
* @param {Boolean} leading - should be function invoked on start
|
|
18
|
-
* @return {promise} Promise-based Timer.
|
|
19
|
-
*/
|
|
20
11
|
|
|
21
12
|
class Timer {
|
|
22
13
|
constructor(delay, timeout, fn, leading) {
|
|
@@ -25,11 +16,6 @@ class Timer {
|
|
|
25
16
|
this._fn = fn;
|
|
26
17
|
this._leading = leading;
|
|
27
18
|
this._conditionExecutedCnt = 0;
|
|
28
|
-
/**
|
|
29
|
-
* only wrap waitUntil condition if:
|
|
30
|
-
* - wdio-sync is installed
|
|
31
|
-
* - function name is not async
|
|
32
|
-
*/
|
|
33
19
|
|
|
34
20
|
if (_config.hasWdioSyncSupport && !fn.name.includes('async')) {
|
|
35
21
|
this._fn = () => (0, _config.runFnInFiberContext)(fn)();
|
|
@@ -54,9 +40,6 @@ class Timer {
|
|
|
54
40
|
}
|
|
55
41
|
|
|
56
42
|
this._mainTimeoutId = setTimeout(() => {
|
|
57
|
-
/**
|
|
58
|
-
* make sure that condition was executed at least once
|
|
59
|
-
*/
|
|
60
43
|
if (!this.wasConditionExecuted()) {
|
|
61
44
|
return;
|
|
62
45
|
}
|
|
@@ -97,7 +80,7 @@ class Timer {
|
|
|
97
80
|
|
|
98
81
|
checkCondition(err, res) {
|
|
99
82
|
++this._conditionExecutedCnt;
|
|
100
|
-
this.lastError = err;
|
|
83
|
+
this.lastError = err;
|
|
101
84
|
|
|
102
85
|
if (res) {
|
|
103
86
|
this._resolve(res);
|
|
@@ -105,14 +88,12 @@ class Timer {
|
|
|
105
88
|
this.stop();
|
|
106
89
|
this.stopMain();
|
|
107
90
|
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
91
|
+
}
|
|
110
92
|
|
|
111
93
|
let diff = Date.now() - this._start - this._ticks++ * this._delay;
|
|
112
94
|
|
|
113
|
-
let delay = Math.max(0, this._delay - diff);
|
|
114
|
-
|
|
115
|
-
this.stop(); // check if we have time to one more tick
|
|
95
|
+
let delay = Math.max(0, this._delay - diff);
|
|
96
|
+
this.stop();
|
|
116
97
|
|
|
117
98
|
if (this.hasTime(delay)) {
|
|
118
99
|
this._timeoutId = setTimeout(this.tick.bind(this), delay);
|
|
@@ -15,87 +15,60 @@ const DEFAULT_STRATEGY = 'css selector';
|
|
|
15
15
|
const DIRECT_SELECTOR_REGEXP = /^(id|css selector|xpath|link text|partial link text|name|tag name|class name|-android uiautomator|-android datamatcher|-ios uiautomation|-ios predicate string|-ios class chain|accessibility id):(.+)/;
|
|
16
16
|
const XPATH_SELECTORS_START = ['/', '(', '../', './', '*/'];
|
|
17
17
|
const NAME_MOBILE_SELECTORS_START = ['uia', 'xcuielementtype', 'android.widget', 'cyi'];
|
|
18
|
-
const XPATH_SELECTOR_REGEXP = [
|
|
19
|
-
/^([a-z0-9|-]*)/, // optional . or # + class or id
|
|
20
|
-
/(?:(\.|#)(-?[_a-zA-Z]+[_a-zA-Z0-9-]*))?/, // optional [attribute-name="attribute-selector"]
|
|
21
|
-
/(?:\[(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)(?:=(?:"|')([a-zA-z0-9\-_. ]+)(?:"|'))?\])?/, // *=query or =query
|
|
22
|
-
/(\*)?=(.+)$/];
|
|
18
|
+
const XPATH_SELECTOR_REGEXP = [/^([a-z0-9|-]*)/, /(?:(\.|#)(-?[_a-zA-Z]+[_a-zA-Z0-9-]*))?/, /(?:\[(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)(?:=(?:"|')([a-zA-z0-9\-_. ]+)(?:"|'))?\])?/, /(\*)?=(.+)$/];
|
|
23
19
|
|
|
24
20
|
const defineStrategy = function (selector) {
|
|
25
|
-
// Condition with checking isPlainObject(selector) should be first because
|
|
26
|
-
// in case of "selector" argument is a plain object then .match() will cause
|
|
27
|
-
// an error like "selector.match is not a function"
|
|
28
|
-
// Use '-android datamatcher' strategy if selector is a plain object (Android only)
|
|
29
21
|
if ((0, _lodash.default)(selector)) {
|
|
30
22
|
return '-android datamatcher';
|
|
31
|
-
}
|
|
32
|
-
|
|
23
|
+
}
|
|
33
24
|
|
|
34
25
|
if (selector.match(DIRECT_SELECTOR_REGEXP)) {
|
|
35
26
|
return 'directly';
|
|
36
|
-
}
|
|
37
|
-
|
|
27
|
+
}
|
|
38
28
|
|
|
39
29
|
if (XPATH_SELECTORS_START.some(option => selector.startsWith(option))) {
|
|
40
30
|
return 'xpath';
|
|
41
|
-
}
|
|
42
|
-
|
|
31
|
+
}
|
|
43
32
|
|
|
44
33
|
if (selector.startsWith('=')) {
|
|
45
34
|
return 'link text';
|
|
46
|
-
}
|
|
47
|
-
|
|
35
|
+
}
|
|
48
36
|
|
|
49
37
|
if (selector.startsWith('*=')) {
|
|
50
38
|
return 'partial link text';
|
|
51
|
-
}
|
|
52
|
-
|
|
39
|
+
}
|
|
53
40
|
|
|
54
41
|
if (selector.startsWith('id=')) {
|
|
55
42
|
return 'id';
|
|
56
|
-
}
|
|
57
|
-
|
|
43
|
+
}
|
|
58
44
|
|
|
59
45
|
if (selector.startsWith('android=')) {
|
|
60
46
|
return '-android uiautomator';
|
|
61
|
-
}
|
|
62
|
-
|
|
47
|
+
}
|
|
63
48
|
|
|
64
49
|
if (selector.startsWith('ios=')) {
|
|
65
50
|
return '-ios uiautomation';
|
|
66
|
-
}
|
|
67
|
-
|
|
51
|
+
}
|
|
68
52
|
|
|
69
53
|
if (selector.startsWith('~')) {
|
|
70
54
|
return 'accessibility id';
|
|
71
|
-
}
|
|
72
|
-
// for iOS = UIA...
|
|
73
|
-
// for Android = android.widget
|
|
74
|
-
|
|
55
|
+
}
|
|
75
56
|
|
|
76
57
|
if (NAME_MOBILE_SELECTORS_START.some(option => selector.toLowerCase().startsWith(option))) {
|
|
77
58
|
return 'class name';
|
|
78
|
-
}
|
|
79
|
-
// e.g. "<div>" or "<div />"
|
|
80
|
-
|
|
59
|
+
}
|
|
81
60
|
|
|
82
61
|
if (selector.search(/<[a-zA-Z-]+( \/)*>/g) >= 0) {
|
|
83
62
|
return 'tag name';
|
|
84
|
-
}
|
|
85
|
-
// or if isMobile is used even when w3c is used
|
|
86
|
-
// e.g. "[name='myName']" or '[name="myName"]'
|
|
87
|
-
|
|
63
|
+
}
|
|
88
64
|
|
|
89
65
|
if (selector.search(/^\[name=("|')([a-zA-z0-9\-_.@=[\] ']+)("|')]$/) >= 0) {
|
|
90
66
|
return 'name';
|
|
91
|
-
}
|
|
92
|
-
|
|
67
|
+
}
|
|
93
68
|
|
|
94
69
|
if (selector === '..' || selector === '.') {
|
|
95
70
|
return 'xpath';
|
|
96
|
-
}
|
|
97
|
-
// e.g. h1.header=Welcome or [data-name=table-row]=Item or #content*=Intro
|
|
98
|
-
|
|
71
|
+
}
|
|
99
72
|
|
|
100
73
|
if (selector.match(new RegExp(XPATH_SELECTOR_REGEXP.map(rx => rx.source).join('')))) {
|
|
101
74
|
return 'xpath extended';
|
|
@@ -107,13 +80,12 @@ const findStrategy = function (selector, isW3C, isMobile) {
|
|
|
107
80
|
let value = selector;
|
|
108
81
|
|
|
109
82
|
switch (defineStrategy(selector)) {
|
|
110
|
-
// user has specified locator strategy directly
|
|
111
83
|
case 'directly':
|
|
112
84
|
{
|
|
113
85
|
const match = selector.match(DIRECT_SELECTOR_REGEXP);
|
|
114
86
|
|
|
115
87
|
if (!isMobile && isW3C && !_constants.W3C_SELECTOR_STRATEGIES.includes(match[1])) {
|
|
116
|
-
throw new Error('InvalidSelectorStrategy');
|
|
88
|
+
throw new Error('InvalidSelectorStrategy');
|
|
117
89
|
}
|
|
118
90
|
|
|
119
91
|
using = match[1];
|
|
@@ -223,13 +195,9 @@ const findStrategy = function (selector, isW3C, isMobile) {
|
|
|
223
195
|
break;
|
|
224
196
|
}
|
|
225
197
|
}
|
|
226
|
-
/**
|
|
227
|
-
* ensure selector strategy is supported
|
|
228
|
-
*/
|
|
229
|
-
|
|
230
198
|
|
|
231
199
|
if (!isMobile && isW3C && !_constants.W3C_SELECTOR_STRATEGIES.includes(using)) {
|
|
232
|
-
throw new Error('InvalidSelectorStrategy');
|
|
200
|
+
throw new Error('InvalidSelectorStrategy');
|
|
233
201
|
}
|
|
234
202
|
|
|
235
203
|
return {
|
|
@@ -25,12 +25,6 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
25
25
|
|
|
26
26
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* transforms and findElement response into a WDIO element
|
|
30
|
-
* @param {String} selector selector that was used to query the element
|
|
31
|
-
* @param {Object} res findElement response
|
|
32
|
-
* @return {Object} WDIO element object
|
|
33
|
-
*/
|
|
34
28
|
const getElement = function findElement(selector, res) {
|
|
35
29
|
const browser = (0, _utils.getBrowserObject)(this);
|
|
36
30
|
|
|
@@ -42,13 +36,7 @@ const getElement = function findElement(selector, res) {
|
|
|
42
36
|
const elementId = (0, _utils.getElementFromResponse)(res);
|
|
43
37
|
|
|
44
38
|
if (elementId) {
|
|
45
|
-
/**
|
|
46
|
-
* set elementId for easy access
|
|
47
|
-
*/
|
|
48
39
|
client.elementId = elementId;
|
|
49
|
-
/**
|
|
50
|
-
* set element id with proper key so element can be passed into execute commands
|
|
51
|
-
*/
|
|
52
40
|
|
|
53
41
|
if (this.isW3C) {
|
|
54
42
|
client[_constants.ELEMENT_KEY] = elementId;
|
|
@@ -76,13 +64,6 @@ const getElement = function findElement(selector, res) {
|
|
|
76
64
|
|
|
77
65
|
return elementInstance;
|
|
78
66
|
};
|
|
79
|
-
/**
|
|
80
|
-
* transforms and findElement response into a WDIO element
|
|
81
|
-
* @param {String} selector selector that was used to query the element
|
|
82
|
-
* @param {Object} res findElement response
|
|
83
|
-
* @return {Object} WDIO element object
|
|
84
|
-
*/
|
|
85
|
-
|
|
86
67
|
|
|
87
68
|
exports.getElement = getElement;
|
|
88
69
|
|
|
@@ -93,13 +74,7 @@ const getElements = function getElements(selector, res) {
|
|
|
93
74
|
const elementId = (0, _utils.getElementFromResponse)(res);
|
|
94
75
|
|
|
95
76
|
if (elementId) {
|
|
96
|
-
/**
|
|
97
|
-
* set elementId for easy access
|
|
98
|
-
*/
|
|
99
77
|
client.elementId = elementId;
|
|
100
|
-
/**
|
|
101
|
-
* set element id with proper key so element can be passed into execute commands
|
|
102
|
-
*/
|
|
103
78
|
|
|
104
79
|
if (this.isW3C) {
|
|
105
80
|
client[_constants.ELEMENT_KEY] = elementId;
|
|
@@ -10,14 +10,6 @@ var _logger = _interopRequireDefault(require("@wdio/logger"));
|
|
|
10
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
11
|
|
|
12
12
|
const log = (0, _logger.default)('webdriverio');
|
|
13
|
-
/**
|
|
14
|
-
* wait on element if:
|
|
15
|
-
* - elementId couldn't be fetched in the first place
|
|
16
|
-
* - command is not explicit wait command for existance or displayedness
|
|
17
|
-
* @param {Object} currentElement element to wait on if necessary
|
|
18
|
-
* @param {string} commandName name of the command that called this
|
|
19
|
-
* @return {Promise} resolves with element after any necessary waiting
|
|
20
|
-
*/
|
|
21
13
|
|
|
22
14
|
async function implicitWait(currentElement, commandName) {
|
|
23
15
|
if (!currentElement.elementId && !commandName.match(/(waitUntil|waitFor|isExisting|is?\w+Displayed)/)) {
|
|
@@ -25,10 +17,6 @@ async function implicitWait(currentElement, commandName) {
|
|
|
25
17
|
|
|
26
18
|
try {
|
|
27
19
|
await currentElement.waitForExist();
|
|
28
|
-
/**
|
|
29
|
-
* if waitForExist was successful requery element and assign elementId to the scope
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
20
|
return await currentElement.parent.$(currentElement.selector);
|
|
33
21
|
} catch (_unused) {
|
|
34
22
|
throw new Error(`Can't call ${commandName} on element with selector "${currentElement.selector}" because element wasn't found`);
|
|
@@ -9,15 +9,8 @@ var _implicitWait = _interopRequireDefault(require("./implicitWait"));
|
|
|
9
9
|
|
|
10
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
* helper utility to refetch an element and all its parent elements when running
|
|
14
|
-
* into stale element exception errors
|
|
15
|
-
* @param {Object} currentElement element to refetch
|
|
16
|
-
* @param {string} commandName name of the command that called this
|
|
17
|
-
* @return {Promise} resolves with element after all its parent were refetched
|
|
18
|
-
*/
|
|
19
12
|
async function refetchElement(currentElement, commandName) {
|
|
20
|
-
let selectors = [];
|
|
13
|
+
let selectors = [];
|
|
21
14
|
|
|
22
15
|
while (currentElement.elementId && currentElement.parent) {
|
|
23
16
|
selectors.push({
|
|
@@ -28,8 +21,7 @@ async function refetchElement(currentElement, commandName) {
|
|
|
28
21
|
}
|
|
29
22
|
|
|
30
23
|
selectors.reverse();
|
|
31
|
-
const length = selectors.length;
|
|
32
|
-
|
|
24
|
+
const length = selectors.length;
|
|
33
25
|
return selectors.reduce(async (elementPromise, {
|
|
34
26
|
selector,
|
|
35
27
|
index
|
|
@@ -37,11 +29,6 @@ async function refetchElement(currentElement, commandName) {
|
|
|
37
29
|
const resolvedElement = await elementPromise;
|
|
38
30
|
let nextElement = index > 0 ? (await resolvedElement.$$(selector))[index] : null;
|
|
39
31
|
nextElement = nextElement || (await resolvedElement.$(selector));
|
|
40
|
-
/**
|
|
41
|
-
* For error purposes, changing command name to '$' if we aren't
|
|
42
|
-
* on the last element of the array
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
32
|
return await (0, _implicitWait.default)(nextElement, currentIndex + 1 < length ? '$' : commandName);
|
|
46
33
|
}, Promise.resolve(currentElement));
|
|
47
34
|
}
|