forked from Dyalog/Selenium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Selenium.dyalog
254 lines (206 loc) · 7.79 KB
/
Selenium.dyalog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
:Namespace Selenium
(⎕IO ⎕ML ⎕WX)←1 1 3
CURRENTBROWSER←'Chrome'
DEFAULTBROWSER←'Chrome'
DLLPATH←'C:\Devt\Selenium\'
RETRYLIMIT←5000
∇ {dummy}←{type}Click id;b;ok;time
⍝ Click on an element, by default identified by id. See "Find" for options
dummy←⍪⍬
:If 0=⎕NC'type' ⋄ type←'Id' ⋄ :EndIf
b←type Find id
b.Click
∇
∇ {dummy}←fromid DragAndDrop toid;from;to
⍝ Drag and Drop
dummy←⍪⍬
(from to)←Find¨fromid toid
(ACTIONS.DragAndDrop from to).Perform
∇
∇ {dummy}←fromid DragAndDropToOffset xy;from
⍝ Drag
dummy←⍪⍬
from←Find fromid
(ACTIONS.DragAndDropToOffset from,xy).Perform
∇
∇ {dummy}←{action}MoveToElement args;id;target
⍝ Move to element with optional x & y offsets
⍝ And perform optional action (Click|ClickAndHold|ContextClick|DoubleClick)
dummy←⍪⍬
(⊃args)←Find⊃args ⍝ Elements [2 3] optional x & y offsets (integers)
(ACTIONS.MoveToElement args).Perform
⎕DL 0.1
:If 2=⎕NC'action'
:If (⊂action)∊'Click' 'ClickAndHold' 'ContextClick' 'DoubleClick'
((ACTIONS⍎action)⍬).Perform
:Else
('Unsupported action: ',action)⎕SIGNAL 11
:EndIf
:EndIf
∇
∇ R←PageSource
R←BROWSER.PageSource
∇
∇ {r}←ExecuteScript script ⍝ cover for awkward syntax and meaningless result
r←BROWSER.ExecuteScript script #
∇
∇ r←{type}Find id;f;ok;time;value;attr;search;elms;mask
:If 9=⎕NC'id'
r←id ⍝ Already an object
:Else
:If 0=⎕NC'type' ⋄ type←'Id' ⋄ :EndIf
⍝ See auto-complete on BROWSER.F for a list of possible ways to find things
(id attr value)←{3↑⍵,(⍴⍵)↓'' '' ''}eis id
:If search←~0∊⍴attr
type,←('s'=¯1↑type)↓'s'
:EndIf
:If 's'=¯1↑type ⍝ The call FindElements*
f←⍎'BROWSER.FindElementsBy',¯1↓type
:Else
f←⍎'BROWSER.FindElementBy',type
:EndIf
time←⎕AI[3]
:Repeat ⍝ Other functions use Retry operator, but we need to collect the result
:Trap 0
r←f⊂id
ok←1
:Else
r←0
:If RETRYLIMIT>0 ⋄ ⎕DL 0.1 ⋄ ok←0 ⋄ :EndIf
:EndTrap
:Until ok∨(⎕AI[3]-time)>RETRYLIMIT ⍝ Try for a second
:If ok
:AndIf search
elms←⌷r
:If r←∨/mask←<\(⊂value)≡¨attr∘{⍵.GetAttribute⊂⍺}¨elms
r←⊃mask/elms
:EndIf
:EndIf
:EndIf
∇
∇ r←id FindListItems text;li;ok
⍝ Find list items with a given text within element with id (e.g. [Syncfusion ej]ListBox items)
(ok li)←{li←⌷'CssSelectors'Find'#',⍵,' li' ⋄ (0≠⍴li)li}Retry id
r←(li.Text∊eis text)/li
∇
∇ {dummy}←GoTo url
⍝ Ask the browser to navigate to a URL and check that it did it
dummy←⍪⍬
BROWSER.Navigate.GoToUrl⊂url
:If ~(⊂BROWSER.Url)∊url(url,'/')
('did not work - url is ',BROWSER.Url)⎕SIGNAL 11
:EndIf
∇
∇ InitBrowser browser;z
:If 0=⍴browser ⋄ browser←DEFAULTBROWSER ⋄ :EndIf ⍝ Empty rarg => Use DEFAULTBROWSER
:If 0=⎕NC'CURRENTBROWSER' ⋄ CURRENTBROWSER←'' ⋄ :EndIf ⍝ Avoid VALUE ERRORs
:If browser≢CURRENTBROWSER ⋄ ⎕EX'BROWSER' ⋄ :EndIf ⍝ We want to switch or need a new one
SetUsing
:Trap 0 ⍝ Try to find out if Browser is alive - not always reliable
z←BROWSER.Url
:Else
⎕←'Starting ',browser
BROWSER←⎕NEW⍎'OpenQA.Selenium.',browser,'.',browser,'Driver'
CURRENTBROWSER←browser
ACTIONS←⎕NEW OpenQA.Selenium.Interactions.Actions BROWSER
:End
∇
∇ {dummy}←id ListMgrSelect items;elements
⍝ Move items from left to right in a MiServer ejListManager control
dummy←⍪⍬
elements←(id,'_left')FindListItems items
elements DragAndDrop¨⊂id,'_right_container'
∇
∇ {dummy}←selectId Select itemText;sp;se;type
⍝ Select an item in a select element
dummy←⍪⍬
⍝ ↓↓↓ Id can be tuple of (type identifier - see Find)
:If 2=≡selectId ⋄ (type selectId)←selectId
:Else ⋄ type←'Id'
:EndIf
'Select not found'⎕SIGNAL(0≡sp←type Find selectId)/11
se←⎕NEW OpenQA.Selenium.Support.UI.SelectElement sp
se.SelectByText⊂,itemText
∇
∇ {dummy}←selectId SelectItemText itemsText;item;se
⍝ Select items in a select control
⍝ Each item can be deselected by preceding it with '-'.
⍝ A single '-' deselects all
dummy←⍪⍬
se←⎕NEW OpenQA.Selenium.Support.UI.SelectElement,⊂Find selectId
:For item :In eis itemsText
:If item≡'~'
se.DeselectAll
:ElseIf '~'=1↑item
se.DeselectByText⊂1↓item
:Else
se.SelectByText⊂,item
:EndIf
:EndFor
∇
∇ {dummy}←obj SendKeys text;q;i;k
⍝ Send keystrokes - see Keys.⎕NL -2 for special keys like Keys.Enter
⍝ Note that even 'A' Control 'X' will be interpreted as Ctrl+A,X
⍝ To get A,Ctrl+X use 'A'(Control 'X')
dummy←⍪⍬
q←Find obj
text←eis text
i←4~⍨Keys.(Shift Control Alt)⍳¯1↓text
:For k :In i
(ACTIONS.(KeyDown ##.k⌷Keys.(Shift Control Alt))).Perform
:EndFor
q.SendKeys,¨text~Keys.(Shift Control Alt)
∇
∇ SetUsing
⍝ Set the path to the Selenium DLLs
⎕USING←0⍴⎕USING
⎕USING,←⊂('/'⎕R'\\')'OpenQA.Selenium,',DLLPATH,'webdriver.dll'
⎕USING,←⊂('/'⎕R'\\')',',DLLPATH,'webdriver.support.dll'
∇
∇ Start
⎕←'DLLPATH←''',DLLPATH,''''
⎕←'DEFAULTBROWSER←''',DEFAULTBROWSER,''' ⍝ Chrome Firefox supported'
∇
∇ {dummy}←Wait msec
dummy←⍪⍬⊣⎕DL msec÷1000
∇
∇ x←eis x
⍝ Enclose if simple
:If (≡x)∊0 1 ⋄ x←,⊂,x ⋄ :EndIf
∇
∇ {dummy}←{open}ejAccordionTab(tabText ctlId)
⍝ Make sure that a control, within an accordiontab, is visible or not
dummy←⍪⍬
:If 0=⎕NC'open' ⋄ open←1 ⋄ :EndIf
:If open≠(BROWSER.FindElementById⊂ctlId).Displayed⍝ If it doesn't have the desired state
'LinkText'Click tabText
{(open ctlId)←⍵
open=(BROWSER.FindElementById⊂ctlId).Displayed}Retry open ctlId
:EndIf
∇
∇ {ok}←(fn Retry)arg;time;z
⍝ Retry fn for a while
ok←0 ⋄ time←⎕AI[3]
:Repeat
:Trap 0
ok←fn arg
:Else
⎕DL 0.1
:EndTrap
:Until (⊃ok)∨(⎕AI[3]-time)>RETRYLIMIT ⍝ Try for a second
∇
∇ r←element WaitFor args;f;text;msg
⍝ Retry until text/value of element begins with text
⍝ Return msg on failure, '' on success
:If 9≠⎕NC'element' ⋄ element←Find element ⋄ :EndIf
args←eis args
(text msg)←2↑args,(⍴args)↓'Thank You!' 'Expected output did not appear'
f←'{∨/''',((1+text='''')/text),'''','≡⍷'[1+×⍴,text]
:If element.TagName≡'input'
f,←'element.GetAttribute⊂''value''}'
:Else
f,←'element.Text}'
:EndIf
r←(~(⍎f)Retry ⍬)/msg
∇
:EndNamespace