topological-nodered-wdio 0.2.6
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/LICENSE +21 -0
- package/README.md +15 -0
- package/examples/basic.json +332 -0
- package/examples/basic.png +0 -0
- package/package.json +43 -0
- package/src/alert-action.html +79 -0
- package/src/alert-action.js +51 -0
- package/src/browser-action.html +114 -0
- package/src/browser-action.js +69 -0
- package/src/delete-session.html +26 -0
- package/src/delete-session.js +28 -0
- package/src/dropdown-action.html +121 -0
- package/src/dropdown-action.js +48 -0
- package/src/element-action.html +133 -0
- package/src/element-action.js +104 -0
- package/src/element-check.html +87 -0
- package/src/element-check.js +46 -0
- package/src/execute-script.html +92 -0
- package/src/execute-script.js +39 -0
- package/src/explicit-wait.html +123 -0
- package/src/explicit-wait.js +53 -0
- package/src/frame-action.html +67 -0
- package/src/frame-action.js +37 -0
- package/src/implicit-wait-config.html +85 -0
- package/src/implicit-wait-config.js +40 -0
- package/src/new-session.html +96 -0
- package/src/new-session.js +102 -0
- package/src/wdio-common.js +151 -0
- package/src/window-action.html +91 -0
- package/src/window-action.js +42 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const common = require('./wdio-common')
|
|
2
|
+
|
|
3
|
+
module.exports = function(RED) {
|
|
4
|
+
function browserAction(config) {
|
|
5
|
+
RED.nodes.createNode(this, config)
|
|
6
|
+
const node = this
|
|
7
|
+
common.clearStatus(node)
|
|
8
|
+
|
|
9
|
+
node.on('input', async (msg) => {
|
|
10
|
+
try {
|
|
11
|
+
let browser = await common.getBrowser(node.context())
|
|
12
|
+
|
|
13
|
+
let url = config.url || msg.url
|
|
14
|
+
let height = config.height || msg.height
|
|
15
|
+
let width = config.width || msg.width
|
|
16
|
+
let keys = config.keysArr || msg.keysArr
|
|
17
|
+
|
|
18
|
+
if (config.action === 'getUrl') {
|
|
19
|
+
node.log = 'Get the url of the web page.'
|
|
20
|
+
msg.payload = await browser.getUrl()
|
|
21
|
+
} else if (config.action === 'navigateTo') {
|
|
22
|
+
node.log = `Navigate to the "${url}".`
|
|
23
|
+
await browser.navigateTo(url)
|
|
24
|
+
} else if (config.action === 'back') {
|
|
25
|
+
node.log = 'Go to previous page (browser back feature).'
|
|
26
|
+
await browser.back()
|
|
27
|
+
} else if (config.action === 'forward') {
|
|
28
|
+
node.log = 'Go for next page (browser forward feature).'
|
|
29
|
+
await browser.forward()
|
|
30
|
+
} else if (config.action === 'refresh') {
|
|
31
|
+
node.log = 'Refresh the web page.'
|
|
32
|
+
await browser.refresh()
|
|
33
|
+
} else if (config.action === 'getTitle') {
|
|
34
|
+
node.log = 'Get the title of the browser window.'
|
|
35
|
+
msg.payload = await browser.getTitle()
|
|
36
|
+
} else if (config.action === 'setSize') {
|
|
37
|
+
node.log = `Set the Size of browser window to Width: ${width}, Height: ${height}.`
|
|
38
|
+
await browser.setWindowSize(parseInt(width), parseInt(height))
|
|
39
|
+
} else if (config.action === 'maximize') {
|
|
40
|
+
node.log = 'Maximize the browser window.'
|
|
41
|
+
await browser.maximizeWindow()
|
|
42
|
+
} else if (config.action === 'takeScreenShot') {
|
|
43
|
+
node.log = 'Take the screenshot of the browser window.'
|
|
44
|
+
msg.payload = await browser.takeScreenshot()
|
|
45
|
+
} else if (config.action === 'pageSource') {
|
|
46
|
+
node.log = 'Get the Page sorce (Source code of the web page).'
|
|
47
|
+
msg.payload = await browser.getPageSource()
|
|
48
|
+
} else if (config.action === 'getCookies') {
|
|
49
|
+
node.log = 'Get the cookies stored.'
|
|
50
|
+
msg.payload = await browser.getAllCookies()
|
|
51
|
+
} else if (config.action === 'print') {
|
|
52
|
+
node.log = 'Print the page.'
|
|
53
|
+
await browser.execute('setTimeout(()=> {window.print()}, 2000)')
|
|
54
|
+
} else if (config.action === 'keyStrokes') {
|
|
55
|
+
node.log = `Enter the provide keystrokes: ${key}.`
|
|
56
|
+
let arr = keys.split(',')
|
|
57
|
+
let keyValues = arr.map((item) => item.trim())
|
|
58
|
+
await browser.keys(Array.from(keyValues))
|
|
59
|
+
}
|
|
60
|
+
await common.log(node)
|
|
61
|
+
common.successStatus(node)
|
|
62
|
+
node.send(msg)
|
|
63
|
+
} catch (e) {
|
|
64
|
+
common.handleError(e, node, msg)
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
RED.nodes.registerType('browser-action', browserAction)
|
|
69
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('delete-session', {
|
|
3
|
+
category: 'Webdriver IO',
|
|
4
|
+
color: '#a6bbcf',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: { value: '' }
|
|
7
|
+
},
|
|
8
|
+
inputs: 1,
|
|
9
|
+
outputs: 1,
|
|
10
|
+
icon: 'white-globe.png',
|
|
11
|
+
label: function() {
|
|
12
|
+
return this.name || 'delete session'
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<script type="text/x-red" data-template-name="delete-session">
|
|
18
|
+
<div class="form-row">
|
|
19
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
20
|
+
<input id="node-input-name" type="text">
|
|
21
|
+
</div>
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<script type="text/x-red" data-help-name="delete-session">
|
|
25
|
+
<h3><br><br>Deletes the session and also sets the "wdio_browser" global variable to \'\'.</h3>
|
|
26
|
+
</script>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const common = require('./wdio-common')
|
|
2
|
+
|
|
3
|
+
module.exports = function(RED) {
|
|
4
|
+
function deleteSession(config) {
|
|
5
|
+
RED.nodes.createNode(this, config)
|
|
6
|
+
const node = this
|
|
7
|
+
common.clearStatus(node)
|
|
8
|
+
|
|
9
|
+
node.on('input', async (msg) => {
|
|
10
|
+
try {
|
|
11
|
+
let browser = await common.deleteSession(node.context())
|
|
12
|
+
if (browser && browser.sessionId) {
|
|
13
|
+
node.log = 'Close the browser.'
|
|
14
|
+
msg.payload = browser.sessionId
|
|
15
|
+
} else {
|
|
16
|
+
node.log = 'No active browser detected to Close.'
|
|
17
|
+
msg.payload = 'no open session'
|
|
18
|
+
}
|
|
19
|
+
await common.log(node)
|
|
20
|
+
common.successStatus(node)
|
|
21
|
+
node.send(msg)
|
|
22
|
+
} catch (e) {
|
|
23
|
+
common.handleError(e, node, msg)
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
RED.nodes.registerType('delete-session', deleteSession)
|
|
28
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
function setDropdownAction() {
|
|
3
|
+
let action = $('#node-input-action').val()
|
|
4
|
+
$('#actionText').hide()
|
|
5
|
+
$('#actionAttr').hide()
|
|
6
|
+
$('#actionIndex').hide()
|
|
7
|
+
$('#actionValue').hide()
|
|
8
|
+
if (action == 'selectByAttr') {
|
|
9
|
+
$('#actionAttr').show()
|
|
10
|
+
$('#actionValue').show()
|
|
11
|
+
}
|
|
12
|
+
if (action == 'selectByIndex') {
|
|
13
|
+
$('#actionIndex').show()
|
|
14
|
+
}
|
|
15
|
+
if (action == 'selectByText') {
|
|
16
|
+
$('#actionText').show()
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
RED.nodes.registerType('dropdown-action', {
|
|
21
|
+
category: 'Webdriver IO',
|
|
22
|
+
color: '#a6bbcf',
|
|
23
|
+
defaults: {
|
|
24
|
+
name: { value: '' },
|
|
25
|
+
locateUsing: { value: 'xpath' },
|
|
26
|
+
locateValue: { value: '' },
|
|
27
|
+
action: { value: 'selectByAttr' },
|
|
28
|
+
text: { value: '' },
|
|
29
|
+
attribute: { value: '' },
|
|
30
|
+
index: { value: '' },
|
|
31
|
+
value: { value: '' }
|
|
32
|
+
},
|
|
33
|
+
inputs: 1,
|
|
34
|
+
outputs: 1,
|
|
35
|
+
icon: 'white-globe.png',
|
|
36
|
+
label: function() {
|
|
37
|
+
return this.name || 'dropdown action'
|
|
38
|
+
},
|
|
39
|
+
oneditprepare: function() {
|
|
40
|
+
setDropdownAction()
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<script type="text/x-red" data-template-name="dropdown-action">
|
|
46
|
+
<div class="form-row">
|
|
47
|
+
<label for="node-input-locateUsing"><i class="fa fa-tasks"></i> Locate Method</label>
|
|
48
|
+
<select type="text" id="node-input-locateUsing" style="width:70%;">
|
|
49
|
+
<option value="id">id</option>
|
|
50
|
+
<option value="name">name</option>
|
|
51
|
+
<option value="className">Class Name</option>
|
|
52
|
+
<option value="selector">Jquery Selector</option>
|
|
53
|
+
</select>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="form-row">
|
|
56
|
+
<label for="node-input-locateValue"><i class="fa fa-tasks"></i> Selector</label>
|
|
57
|
+
<input id="node-input-locateValue" type="text">
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="form-row">
|
|
61
|
+
<label for="node-input-action"><i class="fa fa-tasks"></i> Action</label>
|
|
62
|
+
<select type="text" id="node-input-action" style="width:70%;" onchange="setDropdownAction()">
|
|
63
|
+
<option value="selectByAttr">Select by Attribute</option>
|
|
64
|
+
<option value="selectByIndex">Select by Index</option>
|
|
65
|
+
<option value="selectByText">Select by Visual text</option>
|
|
66
|
+
<option value="getValue">Get Value</option>
|
|
67
|
+
</select>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="form-row" id="actionText">
|
|
70
|
+
<label for="node-input-text"><i class="fa fa-tasks"></i> Text to Select</label>
|
|
71
|
+
<input id="node-input-text" type="text">
|
|
72
|
+
</div>
|
|
73
|
+
<div class="form-row" id="actionAttr">
|
|
74
|
+
<label for="node-input-attribute"><i class="fa fa-tasks"></i> Attribute Name</label>
|
|
75
|
+
<input id="node-input-attribute" type="text">
|
|
76
|
+
</div>
|
|
77
|
+
<div class="form-row" id="actionValue">
|
|
78
|
+
<label for="node-input-value"><i class="fa fa-tasks"></i> Value</label>
|
|
79
|
+
<input id="node-input-value" type="text">
|
|
80
|
+
</div>
|
|
81
|
+
<div class="form-row" id="actionIndex">
|
|
82
|
+
<label for="node-input-index"><i class="fa fa-tasks"></i> Index</label>
|
|
83
|
+
<input id="node-input-index" type="text">
|
|
84
|
+
</div>
|
|
85
|
+
<div class="form-row">
|
|
86
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
87
|
+
<input id="node-input-name" type="text">
|
|
88
|
+
</div>
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<script type="text/x-red" data-help-name="dropdown-action">
|
|
92
|
+
<h3>Perform action on a dropdown selector</h3>
|
|
93
|
+
<h3>Inputs</h3>
|
|
94
|
+
<dl class="message-properties">
|
|
95
|
+
|
|
96
|
+
<dt><code>mgs.locateUsing</code>: <span class="property-type">string</span></dt>
|
|
97
|
+
<dd>specifies the type of web element identifier:
|
|
98
|
+
<ul>
|
|
99
|
+
<li>id</li>
|
|
100
|
+
<li>name</li>
|
|
101
|
+
<li>Class Name</li>
|
|
102
|
+
<li>Jquery selector</li>
|
|
103
|
+
</ul>
|
|
104
|
+
<br>
|
|
105
|
+
</dd>
|
|
106
|
+
<dt><code>msg.locateValue</code><span class="property-type">string</span></dt>
|
|
107
|
+
<dd>value passed to the web element identifier (Locate Method)<br></dd>
|
|
108
|
+
</dl>
|
|
109
|
+
|
|
110
|
+
<h3>Details</h3>
|
|
111
|
+
<p><b>Locate Method</b> specifies the method used to target the web element/dropdown. This option can be selected manually from the Properties panel OR it can be received from <code>mgs.locateUsing</code><br></p>
|
|
112
|
+
<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>
|
|
113
|
+
<p><b>Action</b> specifies the action to be performed on the target dropdown. Actions includes:
|
|
114
|
+
<ul>
|
|
115
|
+
<li>Select By Attribute</li>
|
|
116
|
+
<li>Select By Index</li>
|
|
117
|
+
<li>Select by Visual text</li>
|
|
118
|
+
<li>Get Value</li>
|
|
119
|
+
</ul>
|
|
120
|
+
</p>
|
|
121
|
+
</script>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const common = require('./wdio-common')
|
|
2
|
+
|
|
3
|
+
module.exports = function(RED) {
|
|
4
|
+
function dropdownAction(config) {
|
|
5
|
+
RED.nodes.createNode(this, config)
|
|
6
|
+
const node = this
|
|
7
|
+
common.clearStatus(node)
|
|
8
|
+
|
|
9
|
+
node.on('input', async (msg) => {
|
|
10
|
+
try {
|
|
11
|
+
let locateUsing = config.locateUsing || msg.locateUsing
|
|
12
|
+
let locateValue = config.locateValue || msg.locateValue
|
|
13
|
+
|
|
14
|
+
let browser = await common.getBrowser(node.context())
|
|
15
|
+
let element = await common.getElement(
|
|
16
|
+
browser,
|
|
17
|
+
locateUsing,
|
|
18
|
+
locateValue
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
let text = config.text || msg.text
|
|
22
|
+
let attribute = config.attribute || msg.attribute
|
|
23
|
+
let index = config.index || msg.index
|
|
24
|
+
let value = config.value || msg.value
|
|
25
|
+
|
|
26
|
+
if (config.action === 'selectByAttr') {
|
|
27
|
+
node.log = `Select the dropdown value using Attribute: ${attribute} with Value: ${value}.`
|
|
28
|
+
await element.selectByAttribute(attribute, value)
|
|
29
|
+
} else if (config.action === 'selectByIndex') {
|
|
30
|
+
node.log = `Select the dropdown value using Index: ${index}.`
|
|
31
|
+
await element.selectByIndex(parseInt(index))
|
|
32
|
+
} else if (config.action === 'selectByText') {
|
|
33
|
+
node.log = `Select the dropdown value using Visible text: ${text}.`
|
|
34
|
+
await element.selectByVisibleText(text)
|
|
35
|
+
} else if (config.action === 'getValue') {
|
|
36
|
+
node.log = 'Get selected drop down value.'
|
|
37
|
+
msg.payload = await element.getValue()
|
|
38
|
+
}
|
|
39
|
+
await common.log(node)
|
|
40
|
+
common.successStatus(node)
|
|
41
|
+
node.send(msg)
|
|
42
|
+
} catch (e) {
|
|
43
|
+
common.handleError(e, node, msg)
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
RED.nodes.registerType('dropdown-action', dropdownAction)
|
|
48
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
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>
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
common.handleError(e, node, msg)
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
RED.nodes.registerType('element-action', elementAction)
|
|
104
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('element-check', {
|
|
3
|
+
category: 'Webdriver IO',
|
|
4
|
+
color: '#a6bbcf',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: { value: '' },
|
|
7
|
+
locateUsing: { value: 'xpath' },
|
|
8
|
+
locateValue: { value: '' },
|
|
9
|
+
check: { value: 'selected' }
|
|
10
|
+
},
|
|
11
|
+
inputs: 1,
|
|
12
|
+
outputs: 1,
|
|
13
|
+
icon: 'white-globe.png',
|
|
14
|
+
label: function() {
|
|
15
|
+
return this.name || 'element check'
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<script type="text/x-red" data-template-name="element-check">
|
|
21
|
+
<div class="form-row">
|
|
22
|
+
<label for="node-input-locateUsing"><i class="fa fa-tasks"></i> Locate Method</label>
|
|
23
|
+
<select type="text" id="node-input-locateUsing" style="width:70%;">
|
|
24
|
+
<option value="id">id</option>
|
|
25
|
+
<option value="name">name</option>
|
|
26
|
+
<option value="css selector">CSS selector</option>
|
|
27
|
+
<option value="link text">Link text</option>
|
|
28
|
+
<option value="partial link text">Partial link text</option>
|
|
29
|
+
<option value="tag name">Tag name</option>
|
|
30
|
+
<option value="xpath" selected>XPath</option>
|
|
31
|
+
</select>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="form-row">
|
|
34
|
+
<label for="node-input-locateValue"><i class="fa fa-tasks"></i> Selector</label>
|
|
35
|
+
<input id="node-input-locateValue" type="text">
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div class="form-row">
|
|
39
|
+
<label for="node-input-check"><i class="fa fa-tasks"></i> Check</label>
|
|
40
|
+
<select type="text" id="node-input-check" style="width:70%;">
|
|
41
|
+
<option value="selected">Is Element Selected</option>
|
|
42
|
+
<option value="enabled">Is Element Enabled</option>
|
|
43
|
+
<option value="displayed">Is Element Displayed</option>
|
|
44
|
+
</select>
|
|
45
|
+
</div>
|
|
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
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<script type="text/x-red" data-help-name="element-check">
|
|
53
|
+
<h3>Selected action of the node performs a target web element inside the browser.</h3>
|
|
54
|
+
<h3>Inputs</h3>
|
|
55
|
+
<dl class="message-properties">
|
|
56
|
+
|
|
57
|
+
<dt><code>mgs.locateUsing</code>: <span class="property-type">string</span></dt>
|
|
58
|
+
<dd>specifies the type of web element identifier:
|
|
59
|
+
<ul>
|
|
60
|
+
<li>id</li>
|
|
61
|
+
<li>name</li>
|
|
62
|
+
<li>CSS selector</li>
|
|
63
|
+
<li>Link text</li>
|
|
64
|
+
<li>Partial link text</li>
|
|
65
|
+
<li>Tag name</li>
|
|
66
|
+
<li>XPath</li>
|
|
67
|
+
</ul>
|
|
68
|
+
<br>
|
|
69
|
+
</dd>
|
|
70
|
+
<dt><code>msg.locateValue</code><span class="property-type">string</span></dt>
|
|
71
|
+
<dd>value passed to the web element identifier (Locate Method)<br></dd>
|
|
72
|
+
|
|
73
|
+
</dl>
|
|
74
|
+
|
|
75
|
+
<h3>Details</h3>
|
|
76
|
+
<dl class="message-properties">
|
|
77
|
+
<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>
|
|
78
|
+
<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>
|
|
79
|
+
<p><b>Check</b> specifies the action to be performed on the target web element. Actions includes:
|
|
80
|
+
<ul>
|
|
81
|
+
<li>Is Element Selected</li>
|
|
82
|
+
<li>Is Element Enabled</li>
|
|
83
|
+
<li>Is Element Displayed</li>
|
|
84
|
+
</ul>
|
|
85
|
+
</p>
|
|
86
|
+
</dl>
|
|
87
|
+
</script>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const common = require('./wdio-common')
|
|
2
|
+
|
|
3
|
+
module.exports = function (RED) {
|
|
4
|
+
function elementCheck(config) {
|
|
5
|
+
RED.nodes.createNode(this, config)
|
|
6
|
+
const node = this
|
|
7
|
+
common.clearStatus(node)
|
|
8
|
+
|
|
9
|
+
node.on('input', async (msg) => {
|
|
10
|
+
try {
|
|
11
|
+
let locateUsing = config.locateUsing || msg.locateUsing
|
|
12
|
+
let locateValue = config.locateValue || msg.locateValue
|
|
13
|
+
|
|
14
|
+
let browser = await common.getBrowser(node.context())
|
|
15
|
+
|
|
16
|
+
let elementId = await common.getElementId(
|
|
17
|
+
browser,
|
|
18
|
+
locateUsing,
|
|
19
|
+
locateValue
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if (config.check === 'selected') {
|
|
23
|
+
node.log = `Check the webelement is selected, identified using ${locateUsing}: "${locateValue}".`
|
|
24
|
+
msg.payload = await browser.isElementSelected(elementId)
|
|
25
|
+
} else if (config.check === 'enabled') {
|
|
26
|
+
node.log = `Check the webelement is enabled, identified using ${locateUsing}: "${locateValue}".`
|
|
27
|
+
msg.payload = await browser.isElementEnabled(elementId)
|
|
28
|
+
} else if (config.check === 'displayed') {
|
|
29
|
+
let element = await common.getElement(
|
|
30
|
+
browser,
|
|
31
|
+
locateUsing,
|
|
32
|
+
locateValue
|
|
33
|
+
)
|
|
34
|
+
node.log = `Check the webelement is displayed, identified using ${locateUsing}: "${locateValue}".`
|
|
35
|
+
msg.payload = await browser.isElementDisplayed(element.elementId)
|
|
36
|
+
}
|
|
37
|
+
await common.log(node)
|
|
38
|
+
common.successStatus(node)
|
|
39
|
+
node.send(msg)
|
|
40
|
+
} catch (e) {
|
|
41
|
+
common.handleError(e, node, msg)
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
RED.nodes.registerType('element-check', elementCheck)
|
|
46
|
+
}
|