topological-nodered-wdio 1.1.1 → 1.1.3
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/package.json +1 -1
- package/src/dropdown-action.html +49 -19
- package/src/dropdown-action.js +45 -12
- package/src/element-action.js +2 -2
- package/src/element-check.html +49 -17
- package/src/element-check.js +51 -22
- package/src/execute-script.html +49 -16
- package/src/execute-script.js +41 -12
- package/src/explicit-wait.html +7 -10
- package/src/explicit-wait.js +1 -2
package/package.json
CHANGED
package/src/dropdown-action.html
CHANGED
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
color: '#a6bbcf',
|
|
23
23
|
defaults: {
|
|
24
24
|
name: { value: '' },
|
|
25
|
+
locateType: { value: false },
|
|
25
26
|
locateUsing: { value: 'xpath' },
|
|
26
27
|
locateValue: { value: '' },
|
|
28
|
+
locateValues: { value: [] },
|
|
27
29
|
action: { value: 'selectByAttr' },
|
|
28
30
|
text: { value: '' },
|
|
29
31
|
attribute: { value: '' },
|
|
@@ -37,30 +39,37 @@
|
|
|
37
39
|
return this.name || 'dropdown action'
|
|
38
40
|
},
|
|
39
41
|
oneditprepare: function () {
|
|
42
|
+
var that = this
|
|
40
43
|
setDropdownAction()
|
|
41
|
-
|
|
44
|
+
showSelectors()
|
|
45
|
+
multiSelectorsUI(that)
|
|
46
|
+
},
|
|
47
|
+
oneditsave: function () {
|
|
48
|
+
var node = this
|
|
49
|
+
var locateType = $('#node-input-locateType').prop('checked')
|
|
50
|
+
node.locateType = locateType
|
|
51
|
+
if (locateType) {
|
|
52
|
+
var locateValues = $('#node-input-locateValues-container').editableList('items')
|
|
53
|
+
node.locateValues = []
|
|
54
|
+
locateValues.each(function () {
|
|
55
|
+
var using = $(this).find('.node-input-locateValues-using').val()
|
|
56
|
+
var value = $(this).find('.node-input-locateValues-value').val()
|
|
57
|
+
node.locateValues.push({ using, value })
|
|
58
|
+
})
|
|
59
|
+
} else {
|
|
60
|
+
node.locateValues = []
|
|
61
|
+
node.locateValue = $('#node-input-locateValue').val()
|
|
62
|
+
node.locateUsing = $('#node-input-locateUsing').val()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
42
65
|
})
|
|
43
66
|
</script>
|
|
44
67
|
|
|
45
68
|
<script type="text/x-red" data-template-name="dropdown-action">
|
|
46
69
|
<div class="form-row">
|
|
47
|
-
<label for="node-input-
|
|
48
|
-
<
|
|
49
|
-
<option value="id">id</option>
|
|
50
|
-
<option value="name">name</option>
|
|
51
|
-
<option value="className">Class Name</option>
|
|
52
|
-
<option value="css selector">CSS selector</option>
|
|
53
|
-
<option value="link text">Link text</option>
|
|
54
|
-
<option value="partial link text">Partial link text</option>
|
|
55
|
-
<option value="tag name">Tag name</option>
|
|
56
|
-
<option value="xpath" selected>XPath</option>
|
|
57
|
-
</select>
|
|
58
|
-
</div>
|
|
59
|
-
<div class="form-row">
|
|
60
|
-
<label for="node-input-locateValue"><i class="fa fa-tasks"></i> Selector</label>
|
|
61
|
-
<input id="node-input-locateValue" type="text">
|
|
70
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
71
|
+
<input id="node-input-name" type="text">
|
|
62
72
|
</div>
|
|
63
|
-
|
|
64
73
|
<div class="form-row">
|
|
65
74
|
<label for="node-input-action"><i class="fa fa-tasks"></i> Action</label>
|
|
66
75
|
<select type="text" id="node-input-action" style="width:70%;" onchange="setDropdownAction()">
|
|
@@ -87,8 +96,29 @@
|
|
|
87
96
|
<input id="node-input-index" type="text">
|
|
88
97
|
</div>
|
|
89
98
|
<div class="form-row">
|
|
90
|
-
<label for="node-input-
|
|
91
|
-
<input id="node-input-
|
|
99
|
+
<label for="node-input-locateType"><i class="fa fa-tasks"></i> Multiple Selector?</label>
|
|
100
|
+
<input id="node-input-locateType" type="checkbox" style="width:30px;" onchange="showSelectors()">
|
|
101
|
+
</div>
|
|
102
|
+
<div class="form-row">
|
|
103
|
+
<label for="node-input-locateUsing"><i class="fa fa-tasks"></i> Locate Method</label>
|
|
104
|
+
<select type="text" id="node-input-locateUsing" style="width:70%;">
|
|
105
|
+
<option value="id">id</option>
|
|
106
|
+
<option value="name">name</option>
|
|
107
|
+
<option value="className">Class Name</option>
|
|
108
|
+
<option value="css selector">CSS selector</option>
|
|
109
|
+
<option value="link text">Link text</option>
|
|
110
|
+
<option value="partial link text">Partial link text</option>
|
|
111
|
+
<option value="tag name">Tag name</option>
|
|
112
|
+
<option value="xpath" selected>XPath</option>
|
|
113
|
+
</select>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="form-row">
|
|
116
|
+
<label for="node-input-locateValue"><i class="fa fa-tasks"></i> Selector</label>
|
|
117
|
+
<input id="node-input-locateValue" type="text">
|
|
118
|
+
</div>
|
|
119
|
+
<div class="form-row node-input-locateValues-container-row" style="position:relative">
|
|
120
|
+
<h4 style="margin-bottom: 3px;">Selectors :</h4>
|
|
121
|
+
<ol id="node-input-locateValues-container"></ol>
|
|
92
122
|
</div>
|
|
93
123
|
</script>
|
|
94
124
|
|
package/src/dropdown-action.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const common = require('./wdio-common')
|
|
2
2
|
|
|
3
|
-
module.exports = function(RED) {
|
|
3
|
+
module.exports = function (RED) {
|
|
4
4
|
function dropdownAction(config) {
|
|
5
5
|
RED.nodes.createNode(this, config)
|
|
6
6
|
const node = this
|
|
@@ -8,15 +8,48 @@ module.exports = function(RED) {
|
|
|
8
8
|
|
|
9
9
|
node.on('input', async (msg) => {
|
|
10
10
|
try {
|
|
11
|
-
|
|
12
|
-
let
|
|
11
|
+
common.clearStatus(node);
|
|
12
|
+
let multiple = config.locateType || msg.locateType;
|
|
13
|
+
let locateValues = config.locateValues || msg.locateValues;
|
|
14
|
+
let locateUsing = config.locateUsing || msg.locateUsing;
|
|
15
|
+
let locateValue = config.locateValue || msg.locateValue;
|
|
16
|
+
let element = null;
|
|
17
|
+
node.log = "";
|
|
13
18
|
|
|
14
19
|
let browser = await common.getBrowser(node.context())
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
if(!multiple){
|
|
21
|
+
let locator = await common.getLocator(
|
|
22
|
+
locateUsing,
|
|
23
|
+
locateValue
|
|
24
|
+
)
|
|
25
|
+
element = await browser.$(locator)
|
|
26
|
+
if (!element) {
|
|
27
|
+
throw new Error(`Element not found using ${locateUsing}: ${locateValue}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else{
|
|
31
|
+
for(let i = 0; i <locateValues.length; i++){
|
|
32
|
+
const { using, value } = locateValues[i];
|
|
33
|
+
let locator = await common.getLocator(
|
|
34
|
+
locateUsing,
|
|
35
|
+
locateValue
|
|
36
|
+
)
|
|
37
|
+
element = await browser.$(locator)
|
|
38
|
+
if (element) {
|
|
39
|
+
node.log += `Attempt ${i + 1}: Element found using ${using}: ${value}\n`;
|
|
40
|
+
locateUsing = using
|
|
41
|
+
locateValue = value
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
node.log += `Attempt ${i + 1}: Element not found using ${using}: ${value}\n`;
|
|
46
|
+
node.warn(`Element not found using ${using}: ${value}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (!element) {
|
|
50
|
+
throw new Error(`Element not found using all selector values`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
20
53
|
|
|
21
54
|
let text = config.text || msg.text
|
|
22
55
|
let attribute = config.attribute || msg.attribute
|
|
@@ -24,16 +57,16 @@ module.exports = function(RED) {
|
|
|
24
57
|
let value = config.value || msg.value
|
|
25
58
|
|
|
26
59
|
if (config.action === 'selectByAttr') {
|
|
27
|
-
node.log
|
|
60
|
+
node.log += `Select the dropdown value using Attribute: ${attribute} with Value: ${value}.`
|
|
28
61
|
await element.selectByAttribute(attribute, value)
|
|
29
62
|
} else if (config.action === 'selectByIndex') {
|
|
30
|
-
node.log
|
|
63
|
+
node.log += `Select the dropdown value using Index: ${index}.`
|
|
31
64
|
await element.selectByIndex(parseInt(index))
|
|
32
65
|
} else if (config.action === 'selectByText') {
|
|
33
|
-
node.log
|
|
66
|
+
node.log += `Select the dropdown value using Visible text: ${text}.`
|
|
34
67
|
await element.selectByVisibleText(text)
|
|
35
68
|
} else if (config.action === 'getValue') {
|
|
36
|
-
node.log
|
|
69
|
+
node.log += 'Get selected drop down value.'
|
|
37
70
|
msg.payload = await element.getValue()
|
|
38
71
|
}
|
|
39
72
|
await common.log(node)
|
package/src/element-action.js
CHANGED
|
@@ -5,7 +5,6 @@ module.exports = function (RED) {
|
|
|
5
5
|
RED.nodes.createNode(this, config);
|
|
6
6
|
const node = this;
|
|
7
7
|
const context = node.context();
|
|
8
|
-
common.clearStatus(node);
|
|
9
8
|
|
|
10
9
|
var getTypeInputValue = async (msg, type, value) => {
|
|
11
10
|
var r = "";
|
|
@@ -40,7 +39,8 @@ module.exports = function (RED) {
|
|
|
40
39
|
};
|
|
41
40
|
|
|
42
41
|
node.on("input", async (msg) => {
|
|
43
|
-
try {
|
|
42
|
+
try {
|
|
43
|
+
common.clearStatus(node);
|
|
44
44
|
let multiple = config.locateType || msg.locateType;
|
|
45
45
|
let locateValues = config.locateValues || msg.locateValues;
|
|
46
46
|
let locateUsing = config.locateUsing || msg.locateUsing;
|
package/src/element-check.html
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
color: '#a6bbcf',
|
|
5
5
|
defaults: {
|
|
6
6
|
name: { value: '' },
|
|
7
|
+
locateType: { value: false },
|
|
7
8
|
locateUsing: { value: 'xpath' },
|
|
8
9
|
locateValue: { value: '' },
|
|
10
|
+
locateValues: { value: [] },
|
|
9
11
|
check: { value: 'selected' }
|
|
10
12
|
},
|
|
11
13
|
inputs: 1,
|
|
@@ -13,11 +15,54 @@
|
|
|
13
15
|
icon: 'white-globe.png',
|
|
14
16
|
label: function() {
|
|
15
17
|
return this.name || 'element check'
|
|
16
|
-
}
|
|
18
|
+
},
|
|
19
|
+
oneditprepare: function () {
|
|
20
|
+
var that = this
|
|
21
|
+
showSelectors()
|
|
22
|
+
multiSelectorsUI(that)
|
|
23
|
+
},
|
|
24
|
+
oneditsave: function () {
|
|
25
|
+
var node = this
|
|
26
|
+
var locateType = $('#node-input-locateType').prop('checked')
|
|
27
|
+
node.locateType = locateType
|
|
28
|
+
if (locateType) {
|
|
29
|
+
var locateValues = $('#node-input-locateValues-container').editableList('items')
|
|
30
|
+
node.locateValues = []
|
|
31
|
+
locateValues.each(function () {
|
|
32
|
+
var using = $(this).find('.node-input-locateValues-using').val()
|
|
33
|
+
var value = $(this).find('.node-input-locateValues-value').val()
|
|
34
|
+
node.locateValues.push({ using, value })
|
|
35
|
+
})
|
|
36
|
+
} else {
|
|
37
|
+
node.locateValues = []
|
|
38
|
+
node.locateValue = $('#node-input-locateValue').val()
|
|
39
|
+
node.locateUsing = $('#node-input-locateUsing').val()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
17
42
|
})
|
|
18
43
|
</script>
|
|
19
44
|
|
|
20
45
|
<script type="text/x-red" data-template-name="element-check">
|
|
46
|
+
<div class="form-row">
|
|
47
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
48
|
+
<input id="node-input-name" type="text">
|
|
49
|
+
</div>
|
|
50
|
+
<div class="form-row">
|
|
51
|
+
<label for="node-input-check"><i class="fa fa-tasks"></i> Check</label>
|
|
52
|
+
<select type="text" id="node-input-check" style="width:70%;">
|
|
53
|
+
<option value="clickable">Is Clickable</option>
|
|
54
|
+
<option value="displayed">Is Displayed</option>
|
|
55
|
+
<option value="displayedInView">Is Displayed in Viewport</option>
|
|
56
|
+
<option value="enabled">Is Enabled</option>
|
|
57
|
+
<option value="existing">Is Existing</option>
|
|
58
|
+
<option value="focused">Is Focused</option>
|
|
59
|
+
<option value="selected">Is Selected</option>
|
|
60
|
+
</select>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="form-row">
|
|
63
|
+
<label for="node-input-locateType"><i class="fa fa-tasks"></i> Multiple Selector?</label>
|
|
64
|
+
<input id="node-input-locateType" type="checkbox" style="width:30px;" onchange="showSelectors()">
|
|
65
|
+
</div>
|
|
21
66
|
<div class="form-row">
|
|
22
67
|
<label for="node-input-locateUsing"><i class="fa fa-tasks"></i> Locate Method</label>
|
|
23
68
|
<select type="text" id="node-input-locateUsing" style="width:70%;">
|
|
@@ -34,22 +79,9 @@
|
|
|
34
79
|
<label for="node-input-locateValue"><i class="fa fa-tasks"></i> Selector</label>
|
|
35
80
|
<input id="node-input-locateValue" type="text">
|
|
36
81
|
</div>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<select type="text" id="node-input-check" style="width:70%;">
|
|
41
|
-
<option value="clickable">Is Clickable</option>
|
|
42
|
-
<option value="displayed">Is Displayed</option>
|
|
43
|
-
<option value="displayedInView">Is Displayed in Viewport</option>
|
|
44
|
-
<option value="enabled">Is Enabled</option>
|
|
45
|
-
<option value="existing">Is Existing</option>
|
|
46
|
-
<option value="focused">Is Focused</option>
|
|
47
|
-
<option value="selected">Is Selected</option>
|
|
48
|
-
</select>
|
|
49
|
-
</div>
|
|
50
|
-
<div class="form-row">
|
|
51
|
-
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
52
|
-
<input id="node-input-name" type="text">
|
|
82
|
+
<div class="form-row node-input-locateValues-container-row" style="position:relative">
|
|
83
|
+
<h4 style="margin-bottom: 3px;">Selectors :</h4>
|
|
84
|
+
<ol id="node-input-locateValues-container"></ol>
|
|
53
85
|
</div>
|
|
54
86
|
</script>
|
|
55
87
|
|
package/src/element-check.js
CHANGED
|
@@ -4,40 +4,69 @@ module.exports = function (RED) {
|
|
|
4
4
|
function elementCheck(config) {
|
|
5
5
|
RED.nodes.createNode(this, config)
|
|
6
6
|
const node = this
|
|
7
|
-
|
|
7
|
+
const context = node.context();
|
|
8
8
|
|
|
9
9
|
node.on('input', async (msg) => {
|
|
10
10
|
try {
|
|
11
|
-
|
|
12
|
-
let
|
|
11
|
+
common.clearStatus(node)
|
|
12
|
+
let multiple = config.locateType || msg.locateType;
|
|
13
|
+
let locateValues = config.locateValues || msg.locateValues;
|
|
14
|
+
let locateUsing = config.locateUsing || msg.locateUsing;
|
|
15
|
+
let locateValue = config.locateValue || msg.locateValue;
|
|
13
16
|
|
|
14
|
-
let browser = await common.getBrowser(
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
let browser = await common.getBrowser(context);
|
|
18
|
+
let elementId = null;
|
|
19
|
+
node.log = "";
|
|
20
|
+
|
|
21
|
+
if (!multiple) {
|
|
22
|
+
elementId = await common.getElementId(
|
|
23
|
+
browser,
|
|
24
|
+
locateUsing,
|
|
25
|
+
locateValue
|
|
26
|
+
);
|
|
27
|
+
if (!elementId) {
|
|
28
|
+
throw new Error(`Element not found using ${locateUsing}: ${locateValue}`);
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
for (let i = 0; i < locateValues.length; i++) {
|
|
32
|
+
const { using, value } = locateValues[i];
|
|
33
|
+
elementId = await common.getElementId(browser, using, value);
|
|
34
|
+
if (elementId) {
|
|
35
|
+
node.log += `Attempt ${i + 1}: Element found using ${using}: ${value}\n`;
|
|
36
|
+
locateUsing = using
|
|
37
|
+
locateValue = value
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
node.log += `Attempt ${i + 1}: Element not found using ${using}: ${value}\n`;
|
|
42
|
+
node.warn(`Element not found using ${using}: ${value}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!elementId) {
|
|
46
|
+
throw new Error(`Element not found using all selector values`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
20
49
|
|
|
21
50
|
if (config.check === 'clickable') {
|
|
22
|
-
node.log
|
|
51
|
+
node.log += `Check the webelement is clickable, identified using ${locateUsing}: "${locateValue}".`
|
|
23
52
|
msg.payload = await browser.$(locator).isClickable()
|
|
24
53
|
} else if (config.check === 'displayed') {
|
|
25
|
-
node.log
|
|
26
|
-
msg.payload =
|
|
54
|
+
node.log += `Check the webelement is displayed, identified using ${locateUsing}: "${locateValue}".`
|
|
55
|
+
msg.payload = await browser.$(locator).isDisplayed()
|
|
27
56
|
} else if (config.check === 'displayedInView') {
|
|
28
|
-
node.log
|
|
57
|
+
node.log += `Check the webelement is displayed in view port, identified using ${locateUsing}: "${locateValue}".`
|
|
29
58
|
msg.payload = await browser.$(locator).isDisplayedInViewport()
|
|
30
59
|
} else if (config.check === 'enabled') {
|
|
31
|
-
node.log
|
|
32
|
-
msg.payload =
|
|
60
|
+
node.log += `Check the webelement is enabled, identified using ${locateUsing}: "${locateValue}".`
|
|
61
|
+
msg.payload = await browser.$(locator).isEnabled()
|
|
33
62
|
} else if (config.check === 'existing') {
|
|
34
|
-
node.log
|
|
63
|
+
node.log += `Check the webelement is existing, identified using ${locateUsing}: "${locateValue}".`
|
|
35
64
|
msg.payload = await browser.$(locator).isExisting()
|
|
36
65
|
} else if (config.check === 'focused') {
|
|
37
|
-
node.log
|
|
38
|
-
msg.payload =
|
|
66
|
+
node.log += `Check the webelement is focused, identified using ${locateUsing}: "${locateValue}".`
|
|
67
|
+
msg.payload = await browser.$(locator).isFocused()
|
|
39
68
|
} else if (config.check === 'selected') {
|
|
40
|
-
node.log
|
|
69
|
+
node.log += `Check the webelement is selected, identified using ${locateUsing}: "${locateValue}".`
|
|
41
70
|
msg.payload = await browser.$(locator).isSelected()
|
|
42
71
|
}
|
|
43
72
|
await common.log(node)
|
|
@@ -52,9 +81,9 @@ module.exports = function (RED) {
|
|
|
52
81
|
// node.send(msg)
|
|
53
82
|
// }
|
|
54
83
|
// else{
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
84
|
+
await common.log(node)
|
|
85
|
+
common.handleError(e, node, msg)
|
|
86
|
+
}
|
|
58
87
|
//}
|
|
59
88
|
})
|
|
60
89
|
}
|
package/src/execute-script.html
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
color: '#a6bbcf',
|
|
5
5
|
defaults: {
|
|
6
6
|
name: { value: '' },
|
|
7
|
+
locateType: { value: false },
|
|
7
8
|
locateUsing: { value: 'xpath' },
|
|
8
9
|
locateValue: { value: '' },
|
|
10
|
+
locateValues: { value: [] },
|
|
9
11
|
action: { value: 'sync' },
|
|
10
12
|
script: { value: '' }
|
|
11
13
|
},
|
|
@@ -14,11 +16,53 @@
|
|
|
14
16
|
icon: 'white-globe.png',
|
|
15
17
|
label: function() {
|
|
16
18
|
return this.name || 'execute script'
|
|
17
|
-
}
|
|
19
|
+
},
|
|
20
|
+
oneditprepare: function () {
|
|
21
|
+
var that = this
|
|
22
|
+
showSelectors()
|
|
23
|
+
multiSelectorsUI(that)
|
|
24
|
+
},
|
|
25
|
+
oneditsave: function () {
|
|
26
|
+
var node = this
|
|
27
|
+
var locateType = $('#node-input-locateType').prop('checked')
|
|
28
|
+
node.locateType = locateType
|
|
29
|
+
if (locateType) {
|
|
30
|
+
var locateValues = $('#node-input-locateValues-container').editableList('items')
|
|
31
|
+
node.locateValues = []
|
|
32
|
+
locateValues.each(function () {
|
|
33
|
+
var using = $(this).find('.node-input-locateValues-using').val()
|
|
34
|
+
var value = $(this).find('.node-input-locateValues-value').val()
|
|
35
|
+
node.locateValues.push({ using, value })
|
|
36
|
+
})
|
|
37
|
+
} else {
|
|
38
|
+
node.locateValues = []
|
|
39
|
+
node.locateValue = $('#node-input-locateValue').val()
|
|
40
|
+
node.locateUsing = $('#node-input-locateUsing').val()
|
|
41
|
+
}
|
|
42
|
+
}
|
|
18
43
|
})
|
|
19
44
|
</script>
|
|
20
45
|
|
|
21
46
|
<script type="text/x-red" data-template-name="execute-script">
|
|
47
|
+
<div class="form-row">
|
|
48
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
49
|
+
<input id="node-input-name" type="text">
|
|
50
|
+
</div>
|
|
51
|
+
<div class="form-row">
|
|
52
|
+
<label for="node-input-action"><i class="fa fa-tasks"></i> Action</label>
|
|
53
|
+
<select type="text" id="node-input-action" style="width:70%;">
|
|
54
|
+
<option value="sync">Sync</option>
|
|
55
|
+
<option value="aSync">Async</option>
|
|
56
|
+
</select>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="form-row">
|
|
59
|
+
<label for="node-input-script"><i class="fa fa-tasks"></i> Script</label>
|
|
60
|
+
<input id="node-input-script" type="text" placeholder="javascript in string">
|
|
61
|
+
</div>
|
|
62
|
+
<div class="form-row">
|
|
63
|
+
<label for="node-input-locateType"><i class="fa fa-tasks"></i> Multiple Selector?</label>
|
|
64
|
+
<input id="node-input-locateType" type="checkbox" style="width:30px;" onchange="showSelectors()">
|
|
65
|
+
</div>
|
|
22
66
|
<div class="form-row">
|
|
23
67
|
<label for="node-input-locateUsing"><i class="fa fa-tasks"></i> Locate Method</label>
|
|
24
68
|
<select type="text" id="node-input-locateUsing" style="width:70%;">
|
|
@@ -35,21 +79,10 @@
|
|
|
35
79
|
<label for="node-input-locateValue"><i class="fa fa-tasks"></i> Selector</label>
|
|
36
80
|
<input id="node-input-locateValue" type="text">
|
|
37
81
|
</div>
|
|
38
|
-
<div class="form-row">
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
<option value="aSync">Async</option>
|
|
43
|
-
</select>
|
|
44
|
-
</div>
|
|
45
|
-
<div class="form-row">
|
|
46
|
-
<label for="node-input-script"><i class="fa fa-tasks"></i> Script</label>
|
|
47
|
-
<input id="node-input-script" type="text" placeholder="javascript in string">
|
|
48
|
-
</div>
|
|
49
|
-
<div class="form-row">
|
|
50
|
-
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
51
|
-
<input id="node-input-name" type="text">
|
|
52
|
-
</div>
|
|
82
|
+
<div class="form-row node-input-locateValues-container-row" style="position:relative">
|
|
83
|
+
<h4 style="margin-bottom: 3px;">Selectors :</h4>
|
|
84
|
+
<ol id="node-input-locateValues-container"></ol>
|
|
85
|
+
</div>
|
|
53
86
|
</script>
|
|
54
87
|
|
|
55
88
|
<script type="text/x-red" data-help-name="execute-script">
|
package/src/execute-script.js
CHANGED
|
@@ -1,30 +1,59 @@
|
|
|
1
1
|
const common = require('./wdio-common')
|
|
2
2
|
|
|
3
|
-
module.exports = function(RED) {
|
|
3
|
+
module.exports = function (RED) {
|
|
4
4
|
function executeScript(config) {
|
|
5
5
|
RED.nodes.createNode(this, config)
|
|
6
6
|
const node = this
|
|
7
|
-
|
|
7
|
+
const context = node.context();
|
|
8
8
|
|
|
9
9
|
node.on('input', async (msg) => {
|
|
10
10
|
try {
|
|
11
|
-
|
|
12
|
-
let
|
|
11
|
+
common.clearStatus(node);
|
|
12
|
+
let multiple = config.locateType || msg.locateType;
|
|
13
|
+
let locateValues = config.locateValues || msg.locateValues;
|
|
14
|
+
let locateUsing = config.locateUsing || msg.locateUsing;
|
|
15
|
+
let locateValue = config.locateValue || msg.locateValue;
|
|
13
16
|
|
|
14
|
-
let browser = await common.getBrowser(
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
let browser = await common.getBrowser(context);
|
|
18
|
+
let elementId = null;
|
|
19
|
+
node.log = "";
|
|
20
|
+
|
|
21
|
+
if (!multiple) {
|
|
22
|
+
elementId = await common.getElementId(
|
|
23
|
+
browser,
|
|
24
|
+
locateUsing,
|
|
25
|
+
locateValue
|
|
26
|
+
);
|
|
27
|
+
if (!elementId) {
|
|
28
|
+
throw new Error(`Element not found using ${locateUsing}: ${locateValue}`);
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
for (let i = 0; i < locateValues.length; i++) {
|
|
32
|
+
const { using, value } = locateValues[i];
|
|
33
|
+
elementId = await common.getElementId(browser, using, value);
|
|
34
|
+
if (elementId) {
|
|
35
|
+
node.log += `Attempt ${i + 1}: Element found using ${using}: ${value}\n`;
|
|
36
|
+
locateUsing = using
|
|
37
|
+
locateValue = value
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
node.log += `Attempt ${i + 1}: Element not found using ${using}: ${value}\n`;
|
|
42
|
+
node.warn(`Element not found using ${using}: ${value}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!elementId) {
|
|
46
|
+
throw new Error(`Element not found using all selector values`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
20
49
|
|
|
21
50
|
let script = config.script || msg.script
|
|
22
51
|
|
|
23
52
|
if (config.action === 'sync') {
|
|
24
|
-
node.log
|
|
53
|
+
node.log += `Execute synchronous Javascript: "${script}"${element ? ` By passing the webelement identified using ${locateUsing}: "${locateValue}"` : ''}.`
|
|
25
54
|
await browser.executeScript(script, Array.from(element))
|
|
26
55
|
} else if (config.action === 'aSync') {
|
|
27
|
-
node.log
|
|
56
|
+
node.log += `Execute the asynchronous Javascript: "${script}"${element ? ` By passing the webelement identified using ${locateUsing}: "${locateValue}"` : ''}.`
|
|
28
57
|
await browser.executeAsyncScript(script, Array.from(element))
|
|
29
58
|
}
|
|
30
59
|
await common.log(node)
|
package/src/explicit-wait.html
CHANGED
|
@@ -26,16 +26,20 @@
|
|
|
26
26
|
inputs: 1,
|
|
27
27
|
outputs: 1,
|
|
28
28
|
icon: 'white-globe.png',
|
|
29
|
-
label: function() {
|
|
29
|
+
label: function () {
|
|
30
30
|
return this.name || 'explicit wait'
|
|
31
31
|
},
|
|
32
|
-
oneditprepare: function() {
|
|
32
|
+
oneditprepare: function () {
|
|
33
33
|
setExplicitAction()
|
|
34
34
|
}
|
|
35
35
|
})
|
|
36
36
|
</script>
|
|
37
37
|
|
|
38
38
|
<script type="text/x-red" data-template-name="explicit-wait">
|
|
39
|
+
<div class="form-row">
|
|
40
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
41
|
+
<input id="node-input-name" type="text">
|
|
42
|
+
</div>
|
|
39
43
|
<div class="form-row">
|
|
40
44
|
<label for="node-input-locateUsing"><i class="fa fa-tasks"></i> Locate Method</label>
|
|
41
45
|
<select type="text" id="node-input-locateUsing" style="width:70%;">
|
|
@@ -76,11 +80,7 @@
|
|
|
76
80
|
<div class="form-row" id="actionError" >
|
|
77
81
|
<label for="node-input-error"><i class="fa fa-tasks"></i> Error Message</label>
|
|
78
82
|
<input id="node-input-error" type="text" placeholder="error message">
|
|
79
|
-
</div>
|
|
80
|
-
<div class="form-row">
|
|
81
|
-
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
82
|
-
<input id="node-input-name" type="text">
|
|
83
|
-
</div>
|
|
83
|
+
</div>
|
|
84
84
|
</script>
|
|
85
85
|
|
|
86
86
|
<script type="text/x-red" data-help-name="explicit-wait">
|
|
@@ -121,7 +121,4 @@
|
|
|
121
121
|
<p><b>Time to Wait</b> Set time to wait in milliseconds. <br></p>
|
|
122
122
|
<p><b>Reverse</b> If set to true, webdriver will wait for the <i>opposite</i> of the action selected. <br></p>
|
|
123
123
|
<p><b>Error Message</b> If an error exists this error message overrides the default error message. <br></p>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
124
|
</script>
|
package/src/explicit-wait.js
CHANGED
|
@@ -13,7 +13,6 @@ module.exports = function(RED) {
|
|
|
13
13
|
|
|
14
14
|
let browser = await common.getBrowser(node.context())
|
|
15
15
|
let locator = await common.getLocator(
|
|
16
|
-
browser,
|
|
17
16
|
locateUsing,
|
|
18
17
|
locateValue
|
|
19
18
|
)
|
|
@@ -45,4 +44,4 @@ module.exports = function(RED) {
|
|
|
45
44
|
})
|
|
46
45
|
}
|
|
47
46
|
RED.nodes.registerType('explicit-wait', explicitWait)
|
|
48
|
-
}
|
|
47
|
+
}
|