topological-nodered-wdio 0.5.4 → 1.1.0

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.
@@ -1,133 +1,209 @@
1
- <script type="text/javascript">
2
- function setAction() {
3
- let action = $('#node-input-action').val()
4
- $('#actionSendKeys').hide()
5
- $('#getAttribute').hide()
6
- if (action == 'sendKeys') {
7
- $('#actionSendKeys').show()
8
- }
9
- if (action == 'getAttribute') {
10
- $('#getAttribute').show()
11
- }
12
- }
13
-
14
- RED.nodes.registerType('element-action', {
15
- category: 'Webdriver IO',
16
- color: '#a6bbcf',
17
- defaults: {
18
- name: { value: '' },
19
- locateUsing: { value: 'xpath' },
20
- locateValue: { value: '' },
21
- action: { value: 'click' },
22
- sendKeys: {
23
- value: '',
24
- validate: RED.validators.typedInput('object')
25
- },
26
- object: { value: '' },
27
- attribute: { value: '' }
28
- },
29
- inputs: 1,
30
- outputs: 1,
31
- icon: 'white-globe.png',
32
- label: function() {
33
- return this.name || 'element action'
34
- },
35
- oneditprepare: function() {
36
- setAction()
37
- $('#node-input-sendKeys').typedInput({
38
- default: 'str',
39
- typeField: $('#node-input-object'),
40
- types: ['msg', 'flow', 'global', 'str']
41
- })
42
- }
43
- })
44
- </script>
45
-
46
- <script type="text/x-red" data-template-name="element-action">
47
- <div class="form-row">
48
- <label for="node-input-locateUsing"><i class="fa fa-tasks"></i> Locate Method</label>
49
- <select type="text" id="node-input-locateUsing" style="width:70%;">
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">
62
- </div>
63
-
64
- <div class="form-row">
65
- <label for="node-input-action"><i class="fa fa-tasks"></i> Action</label>
66
- <select type="text" id="node-input-action" style="width:70%;" onchange="setAction()">
67
- <option value="click">Click</option>
68
- <option value="clear">Clear</option>
69
- <option value="sendKeys">Send Keys</option>
70
- <option value="getValue">Get Value</option>
71
- <option value="getText">Get Text</option>
72
- <option value="getAttribute">Get Attribute</option>
73
- <option value="takeScreenShot">Element Screenshot</option>
74
- <option value="hover">Hover</option>
75
- </select>
76
- </div>
77
- <div class="form-row" id="actionSendKeys">
78
- <label for="node-input-sendKeys"><i class="fa fa-tasks"></i> Text to Send</label>
79
- <input type="text" id="node-input-sendKeys" style="width:70%">
80
- <input type="hidden" id="node-input-object">
81
- </div>
82
- <div class="form-row" id="getAttribute">
83
- <label for="node-input-attribute"><i class="fa fa-tasks"></i>Attribute Name</label>
84
- <input id="node-input-attribute" type="text">
85
- </div>
86
- <div class="form-row">
87
- <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
88
- <input id="node-input-name" type="text">
89
- </div>
90
- </script>
91
-
92
- <script type="text/x-red" data-help-name="element-action">
93
- <h3>Perform a list of actions on a target web element.</h3>
94
- <h3>Inputs</h3>
95
- <dl class="message-properties">
96
-
97
- <dt><code>mgs.locateUsing</code>: <span class="property-type">string</span></dt>
98
- <dd>specifies the type of web element identifier:
99
- <ul>
100
- <li>id</li>
101
- <li>name</li>
102
- <li>CSS selector</li>
103
- <li>Link text</li>
104
- <li>Partial link text</li>
105
- <li>Tag name</li>
106
- <li>XPath</li>
107
- </ul>
108
- <br>
109
- </dd>
110
- <dt><code>msg.locateValue</code><span class="property-type">string</span></dt>
111
- <dd>value passed to the web element identifier (Locate Method)<br></dd>
112
-
113
- <dt><code>msg.value</code><span class="property-type">string</span></dt>
114
- <dd>If you elect to SendKeys to the web element, this is the value that would be sent</dd>
115
- </dl>
116
-
117
- <h3>Details</h3>
118
- <p><b>Locate Method</b> specifies the method used to target the web element. This option can be selected manually from the Properties panel OR it can be received from <code>mgs.locateUsing</code><br></p>
119
- <p><b>Selector</b> value used by the Locate Method to target the web element. This option can be selected manually from the Properties panel OR it can be received from <code>mgs.locateValue</code><br></p>
120
- <p><b>Action</b> specifies the action to be performed on the target web element. Actions includes:
121
- <ul>
122
- <li>Click</li>
123
- <li>Clear</li>
124
- <li>Send Keys</li>
125
- <li>Get Value</li>
126
- <li>Get Text</li>
127
- <li>Get Attribute</li>
128
- <li>Element Screenshot</li>
129
- <li>Hover</li>
130
- </ul>
131
- </p>
132
- <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>
1
+ <script type="text/javascript">
2
+ const setAction = () => {
3
+ let action = $('#node-input-action').val()
4
+ $('#actionSendKeys').hide()
5
+ $('#getAttribute').hide()
6
+ if (action == 'sendKeys') {
7
+ $('#actionSendKeys').show()
8
+ }
9
+ if (action == 'getAttribute') {
10
+ $('#getAttribute').show()
11
+ }
12
+ }
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
+
60
+ RED.nodes.registerType('element-action', {
61
+ category: 'Webdriver IO',
62
+ color: '#a6bbcf',
63
+ defaults: {
64
+ name: { value: '' },
65
+ locateUsing: { value: 'xpath' },
66
+ locateType: { value: false },
67
+ locateValue: { value: '' },
68
+ locateValues: { value: [] },
69
+ action: { value: 'click' },
70
+ sendKeys: {
71
+ value: '',
72
+ validate: RED.validators.typedInput('object')
73
+ },
74
+ object: { value: '' },
75
+ attribute: { value: '' }
76
+ },
77
+ inputs: 1,
78
+ outputs: 1,
79
+ icon: 'white-globe.png',
80
+ label: function () {
81
+ return this.name || 'element action'
82
+ },
83
+ oneditprepare: function () {
84
+ var that = this
85
+ setAction()
86
+ showSelectors()
87
+ multiSelectorsUI(that)
88
+ $('#node-input-sendKeys').typedInput({
89
+ default: 'str',
90
+ typeField: $('#node-input-object'),
91
+ types: ['msg', 'flow', 'global', 'str']
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
+ }
111
+ }
112
+ })
113
+ </script>
114
+
115
+ <script type="text/x-red" data-template-name="element-action">
116
+ <div class="form-row">
117
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
118
+ <input id="node-input-name" type="text">
119
+ </div>
120
+ <div class="form-row">
121
+ <label for="node-input-action"><i class="fa fa-tasks"></i> Action</label>
122
+ <select type="text" id="node-input-action" style="width:70%;" onchange="setAction()">
123
+ <option value="click">Click</option>
124
+ <option value="clear">Clear</option>
125
+ <option value="sendKeys">Send Keys</option>
126
+ <option value="getValue">Get Value</option>
127
+ <option value="getText">Get Text</option>
128
+ <option value="getAttribute">Get Attribute</option>
129
+ <option value="takeScreenShot">Element Screenshot</option>
130
+ <option value="hover">Hover</option>
131
+ </select>
132
+ </div>
133
+ <div class="form-row" id="actionSendKeys">
134
+ <label for="node-input-sendKeys"><i class="fa fa-tasks"></i> Text to Send</label>
135
+ <input type="text" id="node-input-sendKeys" style="width:70%">
136
+ <input type="hidden" id="node-input-object">
137
+ </div>
138
+ <div class="form-row" id="getAttribute">
139
+ <label for="node-input-attribute"><i class="fa fa-tasks"></i>Attribute Name</label>
140
+ <input id="node-input-attribute" type="text">
141
+ </div>
142
+ <div class="form-row">
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 Method</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">
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>
166
+ </script>
167
+
168
+ <script type="text/x-red" data-help-name="element-action">
169
+ <h3>Perform a list of actions on a target web element.</h3>
170
+ <h3>Inputs</h3>
171
+ <dl class="message-properties">
172
+
173
+ <dt><code>mgs.locateUsing</code>: <span class="property-type">string</span></dt>
174
+ <dd>specifies the type of web element identifier:
175
+ <ul>
176
+ <li>id</li>
177
+ <li>name</li>
178
+ <li>CSS selector</li>
179
+ <li>Link text</li>
180
+ <li>Partial link text</li>
181
+ <li>Tag name</li>
182
+ <li>XPath</li>
183
+ </ul>
184
+ <br>
185
+ </dd>
186
+ <dt><code>msg.locateValue</code><span class="property-type">string</span></dt>
187
+ <dd>value passed to the web element identifier (Locate Method)<br></dd>
188
+
189
+ <dt><code>msg.value</code><span class="property-type">string</span></dt>
190
+ <dd>If you elect to SendKeys to the web element, this is the value that would be sent</dd>
191
+ </dl>
192
+
193
+ <h3>Details</h3>
194
+ <p><b>Locate Method</b> specifies the method used to target the web element. This option can be selected manually from the Properties panel OR it can be received from <code>mgs.locateUsing</code><br></p>
195
+ <p><b>Selector</b> value used by the Locate Method to target the web element. This option can be selected manually from the Properties panel OR it can be received from <code>mgs.locateValue</code><br></p>
196
+ <p><b>Action</b> specifies the action to be performed on the target web element. Actions includes:
197
+ <ul>
198
+ <li>Click</li>
199
+ <li>Clear</li>
200
+ <li>Send Keys</li>
201
+ <li>Get Value</li>
202
+ <li>Get Text</li>
203
+ <li>Get Attribute</li>
204
+ <li>Element Screenshot</li>
205
+ <li>Hover</li>
206
+ </ul>
207
+ </p>
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>
209
+ </script>
@@ -1,105 +1,107 @@
1
- const common = require('./wdio-common')
2
-
3
- module.exports = function(RED) {
4
- function elementAction(config) {
5
- RED.nodes.createNode(this, config)
6
- const node = this
7
- const context = node.context()
8
- common.clearStatus(node)
9
-
10
- var getTypeInputValue = async (msg, type, value) => {
11
- var r = ''
12
- switch (type) {
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
- try {
24
- r = unescape(JSON.parse('"' + value + '"'))
25
- } catch (e) {
26
- r = value
27
- }
28
- break
29
- case 'num':
30
- r = parseFloat(value)
31
- break
32
- case 'json':
33
- if (value !== '') {
34
- r = JSON.parse(value)
35
- } else {
36
- r = undefined
37
- }
38
- }
39
- return r
40
- }
41
-
42
- node.on('input', async (msg) => {
43
- try {
44
- let locateUsing = config.locateUsing || msg.locateUsing
45
- let locateValue = config.locateValue || msg.locateValue
46
-
47
- let browser = await common.getBrowser(context)
48
- let capabilities = browser.capabilities
49
- let elementId = await common.getElementId(
50
- browser,
51
- locateUsing,
52
- locateValue
53
- )
54
-
55
- let attribute = config.attribute || msg.attribute
56
-
57
- if (config.action === 'click') {
58
- node.log = `Click on the webelement identified using ${locateUsing}: "${locateValue}".`
59
- await browser.elementClick(elementId)
60
- } else if (config.action === 'clear') {
61
- node.log = `Clear the Value of the webelement identified using ${locateUsing}: "${locateValue}".`
62
- await browser.elementClear(elementId)
63
- } else if (config.action === 'sendKeys') {
64
- let value = await getTypeInputValue(
65
- msg,
66
- config.object,
67
- config.sendKeys
68
- )
69
- node.log = `Enter the Value: "${value}" to the webelement identified using ${locateUsing}: "${locateValue}".`
70
- await browser.elementSendKeys(
71
- elementId,
72
- capabilities.version ? Array.from(value) : value
73
- )
74
- } else if (config.action === 'getValue') {
75
- node.log = `Get the Value of webelement identified using ${locateUsing}: "${locateValue}".`
76
- msg.payload = await browser.getElementAttribute(elementId, 'value')
77
- } else if (config.action === 'getText') {
78
- node.log = `Get the Text of webelement identified using ${locateUsing}: "${locateValue}".`
79
- msg.payload = await browser.getElementText(elementId)
80
- } else if (config.action === 'getAttribute') {
81
- node.log = `Get the Attribute: "${attribute}" of webelement identified using ${locateUsing}: "${locateValue}".`
82
- msg.payload = await browser.getElementAttribute(elementId, attribute)
83
- } else if (config.action === 'takeScreenShot') {
84
- node.log = 'Take the screenshot of the webelement.'
85
- msg.payload = await browser.takeElementScreenshot(elementId)
86
- } else if (config.action === 'hover') {
87
- let element = await common.getElement(
88
- browser,
89
- locateUsing,
90
- locateValue
91
- )
92
- node.log = `Hover on the webelement identified using ${locateUsing}: "${locateValue}".`
93
- msg.payload = await element.moveTo()
94
- }
95
- await common.log(node)
96
- common.successStatus(node)
97
- node.send(msg)
98
- } catch (e) {
99
- await common.log(node)
100
- common.handleError(e, node, msg)
101
- }
102
- })
103
- }
104
- RED.nodes.registerType('element-action', elementAction)
105
- }
1
+ const common = require('./wdio-common')
2
+
3
+ module.exports = function(RED) {
4
+ function elementAction(config) {
5
+ RED.nodes.createNode(this, config)
6
+ const node = this
7
+ const context = node.context()
8
+ common.clearStatus(node)
9
+
10
+ var getTypeInputValue = async (msg, type, value) => {
11
+ var r = ''
12
+ switch (type) {
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
+ try {
24
+ r = unescape(JSON.parse('"' + value + '"'))
25
+ } catch (e) {
26
+ r = value
27
+ }
28
+ break
29
+ case 'num':
30
+ r = parseFloat(value)
31
+ break
32
+ case 'json':
33
+ if (value !== '') {
34
+ r = JSON.parse(value)
35
+ } else {
36
+ r = undefined
37
+ }
38
+ }
39
+ return r
40
+ }
41
+
42
+ node.on('input', async (msg) => {
43
+ try {
44
+ let multiple = config.locateType || msg.locateType
45
+ let locateValues = config.locateValues || msg.locateValues
46
+ let locateUsing = multiple ? locateValues[0].using : config.locateUsing || msg.locateUsing
47
+ let locateValue = multiple ? locateValues[0].value : config.locateValue || msg.locateValue
48
+
49
+ let browser = await common.getBrowser(context)
50
+ let capabilities = browser.capabilities
51
+ let elementId = await common.getElementId(
52
+ browser,
53
+ locateUsing,
54
+ locateValue
55
+ )
56
+
57
+ let attribute = config.attribute || msg.attribute
58
+
59
+ if (config.action === 'click') {
60
+ node.log = `Click on the webelement identified using ${locateUsing}: "${locateValue}".`
61
+ await browser.elementClick(elementId)
62
+ } else if (config.action === 'clear') {
63
+ node.log = `Clear the Value of the webelement identified using ${locateUsing}: "${locateValue}".`
64
+ await browser.elementClear(elementId)
65
+ } else if (config.action === 'sendKeys') {
66
+ let value = await getTypeInputValue(
67
+ msg,
68
+ config.object,
69
+ config.sendKeys
70
+ )
71
+ node.log = `Enter the Value: "${value}" to the webelement identified using ${locateUsing}: "${locateValue}".`
72
+ await browser.elementSendKeys(
73
+ elementId,
74
+ capabilities.version ? Array.from(value) : value
75
+ )
76
+ } else if (config.action === 'getValue') {
77
+ node.log = `Get the Value of webelement identified using ${locateUsing}: "${locateValue}".`
78
+ msg.payload = await browser.getElementAttribute(elementId, 'value')
79
+ } else if (config.action === 'getText') {
80
+ node.log = `Get the Text of webelement identified using ${locateUsing}: "${locateValue}".`
81
+ msg.payload = await browser.getElementText(elementId)
82
+ } else if (config.action === 'getAttribute') {
83
+ node.log = `Get the Attribute: "${attribute}" of webelement identified using ${locateUsing}: "${locateValue}".`
84
+ msg.payload = await browser.getElementAttribute(elementId, attribute)
85
+ } else if (config.action === 'takeScreenShot') {
86
+ node.log = 'Take the screenshot of the webelement.'
87
+ msg.payload = await browser.takeElementScreenshot(elementId)
88
+ } else if (config.action === 'hover') {
89
+ let element = await common.getElement(
90
+ browser,
91
+ locateUsing,
92
+ locateValue
93
+ )
94
+ node.log = `Hover on the webelement identified using ${locateUsing}: "${locateValue}".`
95
+ msg.payload = await element.moveTo()
96
+ }
97
+ await common.log(node)
98
+ common.successStatus(node)
99
+ node.send(msg)
100
+ } catch (e) {
101
+ await common.log(node)
102
+ common.handleError(e, node, msg)
103
+ }
104
+ })
105
+ }
106
+ RED.nodes.registerType('element-action', elementAction)
107
+ }