topological-nodered-wdio 1.0.0 → 1.1.1
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.js +0 -1
- package/src/element-action.html +97 -21
- package/src/element-action.js +103 -74
- package/src/wdio-common.js +103 -111
package/package.json
CHANGED
package/src/dropdown-action.js
CHANGED
package/src/element-action.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
-
|
|
2
|
+
const setAction = () => {
|
|
3
3
|
let action = $('#node-input-action').val()
|
|
4
4
|
$('#actionSendKeys').hide()
|
|
5
5
|
$('#getAttribute').hide()
|
|
@@ -11,13 +11,61 @@
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
const showSelectors = () => {
|
|
15
|
+
let locateType = $('#node-input-locateType').prop('checked')
|
|
16
|
+
if (locateType) {
|
|
17
|
+
$('.node-input-locateValues-container-row').show()
|
|
18
|
+
$('#node-input-locateValue').parent().hide()
|
|
19
|
+
$('#node-input-locateUsing').parent().hide()
|
|
20
|
+
} else {
|
|
21
|
+
$('.node-input-locateValues-container-row').hide()
|
|
22
|
+
$('#node-input-locateValue').parent().show()
|
|
23
|
+
$('#node-input-locateUsing').parent().show()
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const multiSelectorsUI = (node) => {
|
|
28
|
+
$('#node-input-locateValues-container').css('min-height', '50vh').css('min-width', '600px').editableList({
|
|
29
|
+
addItem: function (container, index, data) {
|
|
30
|
+
container.css({
|
|
31
|
+
overflow: 'hidden',
|
|
32
|
+
whiteSpace: 'nowrap'
|
|
33
|
+
});
|
|
34
|
+
let fragment = document.createDocumentFragment();
|
|
35
|
+
var row = $('<div/>', { style: "display:flex;" }).appendTo(fragment);
|
|
36
|
+
var selectField = $('<select/>', { class: "node-input-locateValues-using", style: "width:30%; margin-right:10px;border-radius:5px; border: 1px solid lightgray; outline-color: rgba(85, 150, 230, 0.8); outline-width: thin;" }).appendTo(row);
|
|
37
|
+
selectField.append($('<option>', { value: 'id', text: 'id' }));
|
|
38
|
+
selectField.append($('<option>', { value: 'name', text: 'name' }));
|
|
39
|
+
selectField.append($('<option>', { value: 'css selector', text: 'CSS selector' }));
|
|
40
|
+
selectField.append($('<option>', { value: 'link text', text: 'Link text' }));
|
|
41
|
+
selectField.append($('<option>', { value: 'partial link text', text: 'Partial link text' }));
|
|
42
|
+
selectField.append($('<option>', { value: 'tag name', text: 'Tag name' }));
|
|
43
|
+
selectField.append($('<option>', { value: 'xpath', text: 'XPath' }));
|
|
44
|
+
var inputField = $('<input/>', { class: "node-input-locateValues-value", style: "width:65%; margin-right:10px;border-radius:5px; border: 1px solid lightgray; outline-color: rgba(85, 150, 230, 0.8); outline-width: thin;", placeholder: "selector" }).appendTo(row);
|
|
45
|
+
if (data === null || data === undefined) {
|
|
46
|
+
data = { using: 'xpath', value: '' }
|
|
47
|
+
}
|
|
48
|
+
selectField.val(data.using)
|
|
49
|
+
inputField.val(data.value)
|
|
50
|
+
container.append(fragment)
|
|
51
|
+
},
|
|
52
|
+
removable: true,
|
|
53
|
+
sortable: true
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
$('#node-input-locateValues-container').editableList('addItems', node.locateValues || []);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
14
60
|
RED.nodes.registerType('element-action', {
|
|
15
61
|
category: 'Webdriver IO',
|
|
16
62
|
color: '#a6bbcf',
|
|
17
63
|
defaults: {
|
|
18
64
|
name: { value: '' },
|
|
19
65
|
locateUsing: { value: 'xpath' },
|
|
66
|
+
locateType: { value: false },
|
|
20
67
|
locateValue: { value: '' },
|
|
68
|
+
locateValues: { value: [] },
|
|
21
69
|
action: { value: 'click' },
|
|
22
70
|
sendKeys: {
|
|
23
71
|
value: '',
|
|
@@ -29,38 +77,46 @@
|
|
|
29
77
|
inputs: 1,
|
|
30
78
|
outputs: 1,
|
|
31
79
|
icon: 'white-globe.png',
|
|
32
|
-
label: function() {
|
|
80
|
+
label: function () {
|
|
33
81
|
return this.name || 'element action'
|
|
34
82
|
},
|
|
35
|
-
oneditprepare: function() {
|
|
83
|
+
oneditprepare: function () {
|
|
84
|
+
var that = this
|
|
36
85
|
setAction()
|
|
86
|
+
showSelectors()
|
|
87
|
+
multiSelectorsUI(that)
|
|
37
88
|
$('#node-input-sendKeys').typedInput({
|
|
38
89
|
default: 'str',
|
|
39
90
|
typeField: $('#node-input-object'),
|
|
40
91
|
types: ['msg', 'flow', 'global', 'str']
|
|
41
92
|
})
|
|
93
|
+
},
|
|
94
|
+
oneditsave: function () {
|
|
95
|
+
var node = this
|
|
96
|
+
var locateType = $('#node-input-locateType').prop('checked')
|
|
97
|
+
node.locateType = locateType
|
|
98
|
+
if (locateType) {
|
|
99
|
+
var locateValues = $('#node-input-locateValues-container').editableList('items')
|
|
100
|
+
node.locateValues = []
|
|
101
|
+
locateValues.each(function () {
|
|
102
|
+
var using = $(this).find('.node-input-locateValues-using').val()
|
|
103
|
+
var value = $(this).find('.node-input-locateValues-value').val()
|
|
104
|
+
node.locateValues.push({ using, value })
|
|
105
|
+
})
|
|
106
|
+
} else {
|
|
107
|
+
node.locateValues = []
|
|
108
|
+
node.locateValue = $('#node-input-locateValue').val()
|
|
109
|
+
node.locateUsing = $('#node-input-locateUsing').val()
|
|
110
|
+
}
|
|
42
111
|
}
|
|
43
112
|
})
|
|
44
113
|
</script>
|
|
45
114
|
|
|
46
115
|
<script type="text/x-red" data-template-name="element-action">
|
|
47
116
|
<div class="form-row">
|
|
48
|
-
<label for="node-input-
|
|
49
|
-
<
|
|
50
|
-
<option value="id">id</option>
|
|
51
|
-
<option value="name">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">
|
|
117
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
118
|
+
<input id="node-input-name" type="text">
|
|
62
119
|
</div>
|
|
63
|
-
|
|
64
120
|
<div class="form-row">
|
|
65
121
|
<label for="node-input-action"><i class="fa fa-tasks"></i> Action</label>
|
|
66
122
|
<select type="text" id="node-input-action" style="width:70%;" onchange="setAction()">
|
|
@@ -84,9 +140,29 @@
|
|
|
84
140
|
<input id="node-input-attribute" type="text">
|
|
85
141
|
</div>
|
|
86
142
|
<div class="form-row">
|
|
87
|
-
<label for="node-input-
|
|
88
|
-
<input id="node-input-
|
|
143
|
+
<label for="node-input-locateType"><i class="fa fa-tasks"></i> Multiple Selector?</label>
|
|
144
|
+
<input id="node-input-locateType" type="checkbox" style="width:30px;" onchange="showSelectors()">
|
|
145
|
+
</div>
|
|
146
|
+
<div class="form-row">
|
|
147
|
+
<label for="node-input-locateUsing"><i class="fa fa-tasks"></i> Locate Using</label>
|
|
148
|
+
<select type="text" id="node-input-locateUsing" style="width:70%;">
|
|
149
|
+
<option value="id">id</option>
|
|
150
|
+
<option value="name">name</option>
|
|
151
|
+
<option value="css selector">CSS selector</option>
|
|
152
|
+
<option value="link text">Link text</option>
|
|
153
|
+
<option value="partial link text">Partial link text</option>
|
|
154
|
+
<option value="tag name">Tag name</option>
|
|
155
|
+
<option value="xpath" selected>XPath</option>
|
|
156
|
+
</select>
|
|
157
|
+
</div>
|
|
158
|
+
<div class="form-row">
|
|
159
|
+
<label for="node-input-locateValue"><i class="fa fa-tasks"></i> Selector</label>
|
|
160
|
+
<input id="node-input-locateValue" type="text">
|
|
89
161
|
</div>
|
|
162
|
+
<div class="form-row node-input-locateValues-container-row" style="position:relative">
|
|
163
|
+
<h4 style="margin-bottom: 3px;">Selectors :</h4>
|
|
164
|
+
<ol id="node-input-locateValues-container"></ol>
|
|
165
|
+
</div>
|
|
90
166
|
</script>
|
|
91
167
|
|
|
92
168
|
<script type="text/x-red" data-help-name="element-action">
|
|
@@ -130,4 +206,4 @@
|
|
|
130
206
|
</ul>
|
|
131
207
|
</p>
|
|
132
208
|
<p><b>Text to Send</b> if the Send Keys action is selected, this value would send the text to the selected web element.<br></p>
|
|
133
|
-
</script>
|
|
209
|
+
</script>
|
package/src/element-action.js
CHANGED
|
@@ -1,105 +1,134 @@
|
|
|
1
|
-
const common = require(
|
|
1
|
+
const common = require("./wdio-common");
|
|
2
2
|
|
|
3
|
-
module.exports = function(RED) {
|
|
3
|
+
module.exports = function (RED) {
|
|
4
4
|
function elementAction(config) {
|
|
5
|
-
RED.nodes.createNode(this, config)
|
|
6
|
-
const node = this
|
|
7
|
-
const context = node.context()
|
|
8
|
-
common.clearStatus(node)
|
|
5
|
+
RED.nodes.createNode(this, config);
|
|
6
|
+
const node = this;
|
|
7
|
+
const context = node.context();
|
|
8
|
+
common.clearStatus(node);
|
|
9
9
|
|
|
10
10
|
var getTypeInputValue = async (msg, type, value) => {
|
|
11
|
-
var r =
|
|
11
|
+
var r = "";
|
|
12
12
|
switch (type) {
|
|
13
|
-
case
|
|
14
|
-
r = RED.util.getMessageProperty(msg, value)
|
|
15
|
-
break
|
|
16
|
-
case
|
|
17
|
-
r = context.flow.get(value)
|
|
18
|
-
break
|
|
19
|
-
case
|
|
20
|
-
r = context.global.get(value)
|
|
21
|
-
break
|
|
22
|
-
case
|
|
13
|
+
case "msg":
|
|
14
|
+
r = RED.util.getMessageProperty(msg, value);
|
|
15
|
+
break;
|
|
16
|
+
case "flow":
|
|
17
|
+
r = context.flow.get(value);
|
|
18
|
+
break;
|
|
19
|
+
case "global":
|
|
20
|
+
r = context.global.get(value);
|
|
21
|
+
break;
|
|
22
|
+
case "str":
|
|
23
23
|
try {
|
|
24
|
-
r = unescape(JSON.parse('"' + value + '"'))
|
|
24
|
+
r = unescape(JSON.parse('"' + value + '"'));
|
|
25
25
|
} catch (e) {
|
|
26
|
-
r = value
|
|
26
|
+
r = value;
|
|
27
27
|
}
|
|
28
|
-
break
|
|
29
|
-
case
|
|
30
|
-
r = parseFloat(value)
|
|
31
|
-
break
|
|
32
|
-
case
|
|
33
|
-
if (value !==
|
|
34
|
-
r = JSON.parse(value)
|
|
28
|
+
break;
|
|
29
|
+
case "num":
|
|
30
|
+
r = parseFloat(value);
|
|
31
|
+
break;
|
|
32
|
+
case "json":
|
|
33
|
+
if (value !== "") {
|
|
34
|
+
r = JSON.parse(value);
|
|
35
35
|
} else {
|
|
36
|
-
r = undefined
|
|
36
|
+
r = undefined;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
return r
|
|
40
|
-
}
|
|
39
|
+
return r;
|
|
40
|
+
};
|
|
41
41
|
|
|
42
|
-
node.on(
|
|
42
|
+
node.on("input", async (msg) => {
|
|
43
43
|
try {
|
|
44
|
-
let
|
|
45
|
-
let
|
|
44
|
+
let multiple = config.locateType || msg.locateType;
|
|
45
|
+
let locateValues = config.locateValues || msg.locateValues;
|
|
46
|
+
let locateUsing = config.locateUsing || msg.locateUsing;
|
|
47
|
+
let locateValue = config.locateValue || msg.locateValue;
|
|
46
48
|
|
|
47
|
-
let browser = await common.getBrowser(context)
|
|
48
|
-
let capabilities = browser.capabilities
|
|
49
|
-
let elementId =
|
|
50
|
-
|
|
51
|
-
locateUsing,
|
|
52
|
-
locateValue
|
|
53
|
-
)
|
|
49
|
+
let browser = await common.getBrowser(context);
|
|
50
|
+
let capabilities = browser.capabilities;
|
|
51
|
+
let elementId = null;
|
|
52
|
+
node.log = "";
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
if (!multiple) {
|
|
55
|
+
elementId = await common.getElementId(
|
|
56
|
+
browser,
|
|
57
|
+
locateUsing,
|
|
58
|
+
locateValue
|
|
59
|
+
);
|
|
60
|
+
if (!elementId) {
|
|
61
|
+
throw new Error(`Element not found using ${locateUsing}: ${locateValue}`);
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
for (let i = 0; i < locateValues.length; i++) {
|
|
65
|
+
const { using, value } = locateValues[i];
|
|
66
|
+
elementId = await common.getElementId(browser, using, value);
|
|
67
|
+
if (elementId) {
|
|
68
|
+
node.log += `Attempt ${i + 1}: Element found using ${using}: ${value}\n`;
|
|
69
|
+
locateUsing = using
|
|
70
|
+
locateValue = value
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
node.log += `Attempt ${i + 1}: Element not found using ${using}: ${value}\n`;
|
|
75
|
+
node.warn(`Element not found using ${using}: ${value}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (!elementId) {
|
|
79
|
+
throw new Error(`Element not found using all selector values`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let attribute = config.attribute || msg.attribute;
|
|
56
84
|
|
|
57
|
-
if (config.action ===
|
|
58
|
-
node.log
|
|
59
|
-
await browser.elementClick(elementId)
|
|
60
|
-
} else if (config.action ===
|
|
61
|
-
node.log
|
|
62
|
-
await browser.elementClear(elementId)
|
|
63
|
-
} else if (config.action ===
|
|
85
|
+
if (config.action === "click") {
|
|
86
|
+
node.log += `Click on the webelement identified using ${locateUsing}: "${locateValue}".`;
|
|
87
|
+
await browser.elementClick(elementId);
|
|
88
|
+
} else if (config.action === "clear") {
|
|
89
|
+
node.log += `Clear the Value of the webelement identified using ${locateUsing}: "${locateValue}".`;
|
|
90
|
+
await browser.elementClear(elementId);
|
|
91
|
+
} else if (config.action === "sendKeys") {
|
|
64
92
|
let value = await getTypeInputValue(
|
|
65
93
|
msg,
|
|
66
94
|
config.object,
|
|
67
95
|
config.sendKeys
|
|
68
|
-
)
|
|
69
|
-
node.log
|
|
96
|
+
);
|
|
97
|
+
node.log += `Enter the Value: "${value}" to the webelement identified using ${locateUsing}: "${locateValue}".`;
|
|
70
98
|
await browser.elementSendKeys(
|
|
71
99
|
elementId,
|
|
72
100
|
capabilities.version ? Array.from(value) : value
|
|
73
|
-
)
|
|
74
|
-
} else if (config.action ===
|
|
75
|
-
node.log
|
|
76
|
-
msg.payload = await browser.getElementAttribute(elementId,
|
|
77
|
-
} else if (config.action ===
|
|
78
|
-
node.log
|
|
79
|
-
msg.payload = await browser.getElementText(elementId)
|
|
80
|
-
} else if (config.action ===
|
|
81
|
-
node.log
|
|
82
|
-
msg.payload = await browser.getElementAttribute(elementId, attribute)
|
|
83
|
-
} else if (config.action ===
|
|
84
|
-
node.log
|
|
85
|
-
msg.payload = await browser.takeElementScreenshot(elementId)
|
|
86
|
-
} else if (config.action ===
|
|
101
|
+
);
|
|
102
|
+
} else if (config.action === "getValue") {
|
|
103
|
+
node.log += `Get the Value of webelement identified using ${locateUsing}: "${locateValue}".`;
|
|
104
|
+
msg.payload = await browser.getElementAttribute(elementId, "value");
|
|
105
|
+
} else if (config.action === "getText") {
|
|
106
|
+
node.log += `Get the Text of webelement identified using ${locateUsing}: "${locateValue}".`;
|
|
107
|
+
msg.payload = await browser.getElementText(elementId);
|
|
108
|
+
} else if (config.action === "getAttribute") {
|
|
109
|
+
node.log += `Get the Attribute: "${attribute}" of webelement identified using ${locateUsing}: "${locateValue}".`;
|
|
110
|
+
msg.payload = await browser.getElementAttribute(elementId, attribute);
|
|
111
|
+
} else if (config.action === "takeScreenShot") {
|
|
112
|
+
node.log += "Take the screenshot of the webelement.";
|
|
113
|
+
msg.payload = await browser.takeElementScreenshot(elementId);
|
|
114
|
+
} else if (config.action === "hover") {
|
|
87
115
|
let element = await common.getElement(
|
|
88
116
|
browser,
|
|
89
117
|
locateUsing,
|
|
90
118
|
locateValue
|
|
91
|
-
)
|
|
92
|
-
node.log
|
|
93
|
-
msg.payload = await element.moveTo()
|
|
119
|
+
);
|
|
120
|
+
node.log += `Hover on the webelement identified using ${locateUsing}: "${locateValue}".`;
|
|
121
|
+
msg.payload = await element.moveTo();
|
|
94
122
|
}
|
|
95
|
-
await common.log(node)
|
|
96
|
-
common.successStatus(node)
|
|
97
|
-
node.send(msg)
|
|
123
|
+
await common.log(node);
|
|
124
|
+
common.successStatus(node);
|
|
125
|
+
node.send(msg);
|
|
98
126
|
} catch (e) {
|
|
99
|
-
|
|
100
|
-
common.
|
|
127
|
+
node.log = `Error: ${e.message}`;
|
|
128
|
+
await common.log(node);
|
|
129
|
+
common.handleError(e, node, msg);
|
|
101
130
|
}
|
|
102
|
-
})
|
|
131
|
+
});
|
|
103
132
|
}
|
|
104
|
-
RED.nodes.registerType(
|
|
105
|
-
}
|
|
133
|
+
RED.nodes.registerType("element-action", elementAction);
|
|
134
|
+
};
|
package/src/wdio-common.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
const wdio = require(
|
|
2
|
-
let newSessionNode
|
|
1
|
+
const wdio = require("webdriverio");
|
|
2
|
+
let newSessionNode;
|
|
3
3
|
|
|
4
4
|
module.exports.getBrowser = (context) => {
|
|
5
|
-
let browser = context.flow.get(
|
|
5
|
+
let browser = context.flow.get("wdio_browser");
|
|
6
6
|
if (!browser || !browser.sessionId)
|
|
7
|
-
throw new Error(
|
|
7
|
+
throw new Error("No session defined - call newSession first");
|
|
8
8
|
|
|
9
|
-
return browser
|
|
10
|
-
}
|
|
9
|
+
return browser;
|
|
10
|
+
};
|
|
11
11
|
|
|
12
12
|
/*
|
|
13
13
|
config = {
|
|
@@ -25,139 +25,131 @@ config = {
|
|
|
25
25
|
}
|
|
26
26
|
*/
|
|
27
27
|
module.exports.newSession = async (config, node, context) => {
|
|
28
|
-
let browser
|
|
28
|
+
let browser;
|
|
29
29
|
try {
|
|
30
|
-
browser = await wdio.remote(config)
|
|
31
|
-
context.flow.set(
|
|
32
|
-
newSessionNode = node
|
|
30
|
+
browser = await wdio.remote(config);
|
|
31
|
+
context.flow.set("wdio_browser", browser);
|
|
32
|
+
newSessionNode = node;
|
|
33
33
|
} catch (e) {
|
|
34
|
-
throw e
|
|
34
|
+
throw e;
|
|
35
35
|
}
|
|
36
|
-
return browser
|
|
37
|
-
}
|
|
36
|
+
return browser;
|
|
37
|
+
};
|
|
38
38
|
|
|
39
39
|
module.exports.deleteSession = async (context) => {
|
|
40
|
-
let b
|
|
41
|
-
let browser = context.flow.get(
|
|
40
|
+
let b;
|
|
41
|
+
let browser = context.flow.get("wdio_browser");
|
|
42
42
|
try {
|
|
43
|
-
b = { sessionId: browser.sessionId }
|
|
44
|
-
await browser.closeWindow()
|
|
45
|
-
await browser.deleteSession()
|
|
46
|
-
context.flow.set(
|
|
47
|
-
if (newSessionNode) module.exports.disconnected(newSessionNode)
|
|
43
|
+
b = { sessionId: browser.sessionId };
|
|
44
|
+
await browser.closeWindow();
|
|
45
|
+
await browser.deleteSession();
|
|
46
|
+
context.flow.set("wdio_browser", null);
|
|
47
|
+
if (newSessionNode) module.exports.disconnected(newSessionNode);
|
|
48
48
|
} catch (e) {}
|
|
49
|
-
return b
|
|
50
|
-
}
|
|
49
|
+
return b;
|
|
50
|
+
};
|
|
51
51
|
|
|
52
52
|
module.exports.getElementId = async (browser, using, value) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
53
|
+
const element = await browser.findElement(using, value);
|
|
54
|
+
return element.ELEMENT ?? "";
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
module.exports.getLocator = async (using, value) => {
|
|
58
|
+
let locator = "";
|
|
59
|
+
switch (using) {
|
|
60
|
+
case "id":
|
|
61
|
+
locator = `#${value}`;
|
|
62
|
+
break;
|
|
63
|
+
case "name":
|
|
64
|
+
locator = `[name='${value}']`;
|
|
65
|
+
break;
|
|
66
|
+
case "className":
|
|
67
|
+
locator = `.${value}`;
|
|
68
|
+
break;
|
|
69
|
+
case "tagName":
|
|
70
|
+
locator = value;
|
|
71
|
+
break;
|
|
72
|
+
case "cssSelector":
|
|
73
|
+
locator = value;
|
|
74
|
+
break;
|
|
75
|
+
case "text":
|
|
76
|
+
locator = `=${value}`;
|
|
77
|
+
break;
|
|
78
|
+
case "partialText":
|
|
79
|
+
locator = `*=${value}`;
|
|
80
|
+
break;
|
|
81
|
+
case "xPath":
|
|
82
|
+
locator = value;
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
locator = value;
|
|
69
86
|
}
|
|
70
|
-
return elementId
|
|
71
|
-
}
|
|
72
87
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
switch (using) {
|
|
76
|
-
case 'id':
|
|
77
|
-
locator = `#${value}`
|
|
78
|
-
break
|
|
79
|
-
case 'name':
|
|
80
|
-
locator = `[name='${value}']`
|
|
81
|
-
break
|
|
82
|
-
case 'className':
|
|
83
|
-
locator = `.${value}`
|
|
84
|
-
break
|
|
85
|
-
case 'tagName':
|
|
86
|
-
locator = value
|
|
87
|
-
break
|
|
88
|
-
case 'cssSelector':
|
|
89
|
-
locator = value
|
|
90
|
-
break
|
|
91
|
-
case 'text':
|
|
92
|
-
locator = `=${value}`
|
|
93
|
-
break
|
|
94
|
-
case 'partialText':
|
|
95
|
-
locator = `*=${value}`
|
|
96
|
-
break
|
|
97
|
-
case 'xPath':
|
|
98
|
-
locator = value
|
|
99
|
-
break
|
|
100
|
-
default:
|
|
101
|
-
locator = value
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return locator
|
|
105
|
-
}
|
|
88
|
+
return locator;
|
|
89
|
+
};
|
|
106
90
|
|
|
107
91
|
module.exports.handleError = (e, node, msg) => {
|
|
108
|
-
console.log(e)
|
|
109
|
-
module.exports.errorStatus(node)
|
|
110
|
-
node.error(e, msg)
|
|
111
|
-
}
|
|
92
|
+
console.log(e);
|
|
93
|
+
module.exports.errorStatus(node);
|
|
94
|
+
node.error(e, msg);
|
|
95
|
+
};
|
|
112
96
|
|
|
113
97
|
module.exports.clearStatus = (node) => {
|
|
114
|
-
node.status({})
|
|
115
|
-
}
|
|
98
|
+
node.status({});
|
|
99
|
+
};
|
|
116
100
|
|
|
117
101
|
module.exports.connectedStatus = (node) => {
|
|
118
102
|
node.status({
|
|
119
|
-
fill:
|
|
120
|
-
shape:
|
|
121
|
-
text:
|
|
122
|
-
})
|
|
123
|
-
}
|
|
103
|
+
fill: "green",
|
|
104
|
+
shape: "dot",
|
|
105
|
+
text: "connected",
|
|
106
|
+
});
|
|
107
|
+
};
|
|
124
108
|
|
|
125
109
|
module.exports.disconnectedStatus = (node) => {
|
|
126
110
|
node.status({
|
|
127
|
-
fill:
|
|
128
|
-
shape:
|
|
129
|
-
text:
|
|
130
|
-
})
|
|
131
|
-
}
|
|
111
|
+
fill: "green",
|
|
112
|
+
shape: "ring",
|
|
113
|
+
text: "disconnected",
|
|
114
|
+
});
|
|
115
|
+
};
|
|
132
116
|
|
|
133
117
|
module.exports.successStatus = (node) => {
|
|
134
118
|
node.status({
|
|
135
|
-
fill:
|
|
136
|
-
shape:
|
|
137
|
-
text:
|
|
138
|
-
})
|
|
139
|
-
}
|
|
119
|
+
fill: "green",
|
|
120
|
+
shape: "ring",
|
|
121
|
+
text: "done",
|
|
122
|
+
});
|
|
123
|
+
};
|
|
140
124
|
|
|
141
125
|
module.exports.errorStatus = (node) => {
|
|
142
126
|
node.status({
|
|
143
|
-
fill:
|
|
144
|
-
shape:
|
|
145
|
-
text:
|
|
146
|
-
})
|
|
147
|
-
}
|
|
127
|
+
fill: "red",
|
|
128
|
+
shape: "ring",
|
|
129
|
+
text: "error",
|
|
130
|
+
});
|
|
131
|
+
};
|
|
148
132
|
|
|
149
133
|
module.exports.log = async (node) => {
|
|
150
|
-
let context = node.context()
|
|
151
|
-
let stepCount = await (context.global.get(
|
|
152
|
-
let document = await context.global.get(
|
|
153
|
-
await context.global.set(
|
|
154
|
-
|
|
155
|
-
}
|
|
134
|
+
let context = node.context();
|
|
135
|
+
let stepCount = (await (context.global.get("stepCount") || 0)) + 1;
|
|
136
|
+
let document = (await context.global.get("document")) || "";
|
|
137
|
+
await context.global.set(
|
|
138
|
+
"document",
|
|
139
|
+
`${document}${stepCount}. Node (${node.id}): ${node.name} - ${node.log}\n`
|
|
140
|
+
);
|
|
141
|
+
await context.global.set("stepCount", stepCount);
|
|
142
|
+
};
|
|
156
143
|
|
|
157
144
|
module.exports.document = async (node) => {
|
|
158
|
-
let context = node.context()
|
|
159
|
-
let document = await context.global.get(
|
|
160
|
-
document = node.line
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
145
|
+
let context = node.context();
|
|
146
|
+
let document = (await context.global.get("document")) || "";
|
|
147
|
+
document = node.line
|
|
148
|
+
? `${document}\n${node.name}${
|
|
149
|
+
node.refUrl ? `\nRef: ${node.refUrl}` : ""
|
|
150
|
+
}\n\n`
|
|
151
|
+
: `${document}********************\n${node.name}${
|
|
152
|
+
node.refUrl ? `\nRef: ${node.refUrl}` : ""
|
|
153
|
+
}\n********************\n`;
|
|
154
|
+
await context.global.set("document", document.replaceAll("\\n", "\n"));
|
|
155
|
+
};
|