awetestlib 0.0.2-x86-mingw32
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.
- data/.gitignore +70 -0
- data/awetestlib.gemspec +57 -0
- data/awetestlib.windows.gemspec +41 -0
- data/awetestlib_notes.txt +4 -0
- data/awetestlib_osx.gemspec +43 -0
- data/bin/awetestlib +67 -0
- data/create_zoho_account1.rb +66 -0
- data/create_zoho_account2.rb +70 -0
- data/demo.rb +86 -0
- data/ext/mkrf_conf.rb +27 -0
- data/google_search1.rb +16 -0
- data/google_search2.rb +19 -0
- data/lib/awetestlib.rb +39 -0
- data/lib/patches/README +2 -0
- data/lib/patches/firewatir.rb +106 -0
- data/lib/patches/watir.rb +175 -0
- data/lib/regression/legacy.rb +4615 -0
- data/lib/regression/logging.rb +444 -0
- data/lib/regression/runner.rb +264 -0
- data/lib/regression/validations.rb +1508 -0
- data/lib/version.rb +4 -0
- data/zoho_util.rb +484 -0
- data/zoho_variables.xls +0 -0
- metadata +326 -0
@@ -0,0 +1,4615 @@
|
|
1
|
+
module Legacy
|
2
|
+
|
3
|
+
def run
|
4
|
+
setup
|
5
|
+
set_script_variables
|
6
|
+
run_test
|
7
|
+
rescue
|
8
|
+
fatal_to_log("(#{__LINE__}) #{$!}")
|
9
|
+
browser.close
|
10
|
+
raise
|
11
|
+
end
|
12
|
+
|
13
|
+
#TODO replace with method_missing?
|
14
|
+
# place holder to prevent method not found error in scripts
|
15
|
+
def set_script_variables
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup
|
19
|
+
# if @os_sysname =~ /Windows.+Server\s+2003/
|
20
|
+
## 'Microsoft(R) Windows(R) Server 2003, Enterprise Edition'
|
21
|
+
# @vertical_hack_ie = 110
|
22
|
+
# @vertical_hack_ff = 138
|
23
|
+
# @horizontal_hack_ie = 5
|
24
|
+
# @horizontal_hack_ff = 4
|
25
|
+
# elsif @os_sysname =~ /Windows XP Professional/
|
26
|
+
# 'Microsoft Windows XP Professional'
|
27
|
+
@vertical_hack_ie = 118
|
28
|
+
@vertical_hack_ff = 144
|
29
|
+
@horizontal_hack_ie = 5
|
30
|
+
@horizontal_hack_ff = 4
|
31
|
+
#end
|
32
|
+
|
33
|
+
@settings_display_ids = Hash[
|
34
|
+
"Currency" => "row-currencyName",
|
35
|
+
"Description" => "row-description",
|
36
|
+
"Tx Date" => "row-fmtDate",
|
37
|
+
"Total" => "row-amount",
|
38
|
+
"[currencyCode]" => "row-currencyCode",
|
39
|
+
"Date in Millis" => "row-dateInMilliseconds",
|
40
|
+
]
|
41
|
+
@column_data_display_ids = Hash[
|
42
|
+
"Currency" => "yui-dt0-th-currencyName",
|
43
|
+
"Description" => "yui-dt0-th-description",
|
44
|
+
"Tx Date" => "yui-dt0-th-fmtDate",
|
45
|
+
"Total" => "yui-dt0-th-fmtDate",
|
46
|
+
"[currencyCode]" => "yui-dt0-th-currencyCode",
|
47
|
+
"Date in Millis" => "yui-dt0-th-dateInMilliseconds",
|
48
|
+
]
|
49
|
+
@settings_panel_index = 0
|
50
|
+
@x_tolerance = 4
|
51
|
+
@y_tolerance = 4
|
52
|
+
end
|
53
|
+
|
54
|
+
def sleep_for(seconds, dbg = true, desc = '')
|
55
|
+
msg = "Sleeping for #{seconds} seconds."
|
56
|
+
msg << " #{desc}" if desc.length > 0
|
57
|
+
msg << "\n#{get_debug_list}" if dbg
|
58
|
+
info_to_log(msg)
|
59
|
+
sleep(seconds)
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_mdyy(t = Time.now)
|
63
|
+
"#{t.month}/#{t.day}/#{t.year}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def get_prefix(strg, offset)
|
67
|
+
a_slice = strg.slice(0, offset)
|
68
|
+
a_slice.downcase
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_timestamp(format = 'long', offset = nil, offset_unit = :years)
|
72
|
+
t = DateTime.now
|
73
|
+
if offset
|
74
|
+
t = t.advance(offset_unit => offset)
|
75
|
+
end
|
76
|
+
case format
|
77
|
+
when 'dateonly'
|
78
|
+
t.strftime("%m/%d/%Y")
|
79
|
+
when 'condensed'
|
80
|
+
t.strftime("%Y%m%d%H%M")
|
81
|
+
when 'condensed_seconds'
|
82
|
+
t.strftime("%Y%m%d%H%M%S")
|
83
|
+
when 'long'
|
84
|
+
t.strftime("%m/%d/%Y %I:%M %p")
|
85
|
+
when 'mdyy'
|
86
|
+
get_mdyy(t)
|
87
|
+
when 'm/d/y'
|
88
|
+
get_mdyy(t)
|
89
|
+
else
|
90
|
+
Time.now.strftime("%m/%d/%Y %H:%M:%S")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def token_auth(browser, role, token, id = 'token_pass')
|
95
|
+
set_textfield_by_id(browser, id, token)
|
96
|
+
click_button_by_value(browser, 'Continue')
|
97
|
+
if validate_text(browser, 'The requested page requires authentication\.\s*Please enter your Passcode below', nil, true)
|
98
|
+
bail_out(browser, __LINE__, "Token authorization failed on '#{token}'")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def calc_index(index, every = 1)
|
103
|
+
(index / every) + (every - 1)
|
104
|
+
end
|
105
|
+
|
106
|
+
=begin rdoc
|
107
|
+
tags: data, DOM, page
|
108
|
+
browser is any container element. Best to use is the smallest that contains the desired data.
|
109
|
+
types defaults to all of: :text, :textarea, :select_list, :span, :hidden, :checkbox, and :radio
|
110
|
+
Set types to array of subset if fewer elements are desired.
|
111
|
+
returns a single hash:
|
112
|
+
---
|
113
|
+
:name:
|
114
|
+
:span: {}
|
115
|
+
:textarea: {}
|
116
|
+
:radio: {}
|
117
|
+
:checkbox: {}
|
118
|
+
:hidden: {}
|
119
|
+
:select_list: {}
|
120
|
+
:text: {}
|
121
|
+
:index:
|
122
|
+
:span: {}
|
123
|
+
:textarea: {}
|
124
|
+
:radio: {}
|
125
|
+
:checkbox: {}
|
126
|
+
:hidden: {}
|
127
|
+
:select_list: {}
|
128
|
+
:text: {}
|
129
|
+
:id:
|
130
|
+
:span: {}
|
131
|
+
:textarea: {}
|
132
|
+
:radio: {}
|
133
|
+
:checkbox: {}
|
134
|
+
:hidden: {}
|
135
|
+
:select_list: {}
|
136
|
+
:text: {}
|
137
|
+
|
138
|
+
No positive validations are reported but failure is rescued and reported.
|
139
|
+
=end
|
140
|
+
def capture_page_data(browser, types = [:text, :textarea, :select_list, :span, :hidden, :checkbox, :radio])
|
141
|
+
start = Time.now
|
142
|
+
debug_to_log("Begin #{__method__}")
|
143
|
+
data = Hash.new
|
144
|
+
data[:id] = Hash.new
|
145
|
+
data[:name] = Hash.new
|
146
|
+
data[:index] = Hash.new
|
147
|
+
types.each do |type|
|
148
|
+
#debug_to_log("#{__method__}: #{type}. . .")
|
149
|
+
data[:id][type], data[:name][type], data[:index][type] = parse_elements(browser, type)
|
150
|
+
end
|
151
|
+
data
|
152
|
+
rescue
|
153
|
+
failed_to_log("#{__method__}: '#{$!}'")
|
154
|
+
ensure
|
155
|
+
stop = Time.now
|
156
|
+
passed_to_log("#{__method__.to_s.titleize} finished. (#{"%.5f" % (stop - start)} secs)")
|
157
|
+
#debug_to_log("End #{__method__}")
|
158
|
+
end
|
159
|
+
|
160
|
+
def compare_page_data(before, after, how, desc = '')
|
161
|
+
[:text, :textarea, :select_list, :span, :checkbox, :radio].each do |type|
|
162
|
+
before[how][type].each_key do |what|
|
163
|
+
msg = "#{desc} #{type} #{how}=#{what}: Expected '#{before[how][type][what]}'."
|
164
|
+
if after[how][type][what] == before[how][type][what]
|
165
|
+
passed_to_log(msg)
|
166
|
+
else
|
167
|
+
failed_to_log("#{msg} Found '#{after[how][type][what]}'")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
rescue
|
172
|
+
failed_to_log("Unable to compare before and after page data. '#{$!}'")
|
173
|
+
end
|
174
|
+
|
175
|
+
=begin rdoc
|
176
|
+
tags: data, DOM
|
177
|
+
data is output of capture_page_data().
|
178
|
+
how is one of :id, :name, :index
|
179
|
+
what is the target value for how
|
180
|
+
type is one of :text,:textarea,:select_list,:span,:hidden,:checkbox,:radio
|
181
|
+
get_text is used for select_list to choose selected option value or text (default)
|
182
|
+
note that multiple selections will be captured as arrays so value and text.
|
183
|
+
Not tested with multiple selections (02aug2011)
|
184
|
+
=end
|
185
|
+
def fetch_page_data(data, how, what, type, get_text = true)
|
186
|
+
rslt = data[how][type][what]
|
187
|
+
if type == :select_list
|
188
|
+
value, text = rslt.split('::')
|
189
|
+
if get_text
|
190
|
+
rslt = text
|
191
|
+
else
|
192
|
+
rslt = value
|
193
|
+
end
|
194
|
+
end
|
195
|
+
rslt
|
196
|
+
end
|
197
|
+
|
198
|
+
def capture_screen(browser, ts)
|
199
|
+
browser.maximize
|
200
|
+
browser.bring_to_front
|
201
|
+
caller = get_caller
|
202
|
+
caller.match(/:(\d+):/)
|
203
|
+
lnbr = $1
|
204
|
+
path = "#{@myRoot}/screenshot/"
|
205
|
+
screenfile = "#{@myName}_#{@myRun.id}_#{lnbr.to_s}_#{ts.to_f.to_s}.scrsht.jpg"
|
206
|
+
info_to_log("path:#{path} screenfile:#{screenfile}")
|
207
|
+
screenSpec = '"' + path + screenfile + '"'
|
208
|
+
screenSpec.gsub!('/', '\\')
|
209
|
+
screen_capture(screenSpec)
|
210
|
+
screenfile
|
211
|
+
end
|
212
|
+
|
213
|
+
def bail_out(browser, lnbr, msg)
|
214
|
+
ts = Time.new
|
215
|
+
msg = "Bailing out at util line #{lnbr} #{ts} " + msg
|
216
|
+
puts "#{msg}"
|
217
|
+
fatal_to_log(msg, nil, 1, lnbr)
|
218
|
+
debug_to_log(dump_caller(lnbr))
|
219
|
+
if is_browser?(browser)
|
220
|
+
if @browserAbbrev == 'IE'
|
221
|
+
hwnd = browser.hwnd
|
222
|
+
kill_browser(hwnd, lnbr, browser)
|
223
|
+
raise(RuntimeError, msg, caller)
|
224
|
+
elsif @browserAbbrev == 'FF'
|
225
|
+
debug_to_log("#{browser.inspect}")
|
226
|
+
debug_to_log("#{browser.to_s}")
|
227
|
+
raise(RuntimeError, msg, caller)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
@status = 'bailout'
|
231
|
+
raise(RuntimeError, msg, caller)
|
232
|
+
end
|
233
|
+
|
234
|
+
def parse_cookies(browser)
|
235
|
+
cookies = Hash.new
|
236
|
+
strg = browser.document.cookie
|
237
|
+
ary = strg.split(';')
|
238
|
+
ary.each do |c|
|
239
|
+
key, value = c.split('=')
|
240
|
+
cookies[key.lstrip] = value
|
241
|
+
end
|
242
|
+
cookies
|
243
|
+
end
|
244
|
+
|
245
|
+
=begin rdoc
|
246
|
+
tags: data, DOM
|
247
|
+
browser is any container element. best to use is the smallest that contains the desired data.
|
248
|
+
type is one of these symbols: :text,:textarea,:select_list,:span,:hidden,:checkbox,:radio
|
249
|
+
returns three hashes: id[type][id] = value, name[type][id] = value, index[type][id] = value
|
250
|
+
a given element appears once in the set of hashes depending on how is is found: id first
|
251
|
+
then name, then index.
|
252
|
+
select list value is in the form 'value::text'. parse with x.split('::')
|
253
|
+
No positive validations are reported but failure is rescued and reported.
|
254
|
+
=end
|
255
|
+
def parse_elements(browser, type)
|
256
|
+
id = Hash.new
|
257
|
+
name = Hash.new
|
258
|
+
index = Hash.new
|
259
|
+
idx = 0
|
260
|
+
#debug_to_log("#{__method__}: #{type}")
|
261
|
+
case type
|
262
|
+
when :span
|
263
|
+
collection = browser.spans
|
264
|
+
when :select_list
|
265
|
+
collection = browser.select_lists
|
266
|
+
when :radio
|
267
|
+
collection = browser.radios
|
268
|
+
when :checkbox
|
269
|
+
collection = browser.checkboxes
|
270
|
+
else
|
271
|
+
collection = browser.elements(:type, type.to_s)
|
272
|
+
end
|
273
|
+
#debug_to_log("#{__method__}: collection: #{collection.inspect}")
|
274
|
+
collection.each do |e|
|
275
|
+
case type
|
276
|
+
when :span
|
277
|
+
vlu = e.text
|
278
|
+
when :select_list
|
279
|
+
vlu = "#{e.value}::#{e.selected_options[0]}"
|
280
|
+
when :radio
|
281
|
+
vlu = e.set?
|
282
|
+
when :checkbox
|
283
|
+
vlu = e.set?
|
284
|
+
else
|
285
|
+
vlu = e.value
|
286
|
+
end
|
287
|
+
idx += 1
|
288
|
+
if e.id.length > 0 and not e.id =~ /^__[A-Z]/
|
289
|
+
id[e.id] = vlu
|
290
|
+
elsif e.name.length > 0 and not e.name =~ /^__[A-Z]/
|
291
|
+
name[e.name] = vlu
|
292
|
+
else
|
293
|
+
index[idx] = vlu if not type == :hidden
|
294
|
+
end
|
295
|
+
end
|
296
|
+
[id, name, index]
|
297
|
+
|
298
|
+
rescue
|
299
|
+
failed_to_log("#{__method__}: '#{$!}'")
|
300
|
+
end
|
301
|
+
|
302
|
+
def verify_no_element_overlap(browser, above_element, above_how, above_what, below_element, below_how, below_what, side, desc = '')
|
303
|
+
mark_testlevel("#{__method__.to_s.titleize}", 3)
|
304
|
+
msg = "#{above_element.to_s.titleize} #{above_how}=>#{above_what} does not overlap "+
|
305
|
+
"#{below_element.to_s.titleize} #{below_how}=>#{below_what} at the #{side}."
|
306
|
+
msg << " #{desc}" if desc.length > 0
|
307
|
+
above = browser.element(above_how, above_what)
|
308
|
+
below = browser.element(below_how, below_what)
|
309
|
+
if overlay?(above, below, side)
|
310
|
+
failed_to_log(msg)
|
311
|
+
else
|
312
|
+
passed_to_log(msg)
|
313
|
+
true
|
314
|
+
end
|
315
|
+
rescue
|
316
|
+
failed_to_log("Unable to verify that #{msg} '#{$!}'")
|
317
|
+
end
|
318
|
+
|
319
|
+
def verify_element_inside(inner_element, outer_element, desc = '')
|
320
|
+
mark_testlevel("#{__method__.to_s.titleize}", 3)
|
321
|
+
msg = "#{inner_element.class.to_s} (:id=#{inner_element.id}) is fully enclosed by #{outer_element.class.to_s} (:id=#{outer_element.id})."
|
322
|
+
msg << " #{desc}" if desc.length > 0
|
323
|
+
if overlay?(inner_element, outer_element, :inside)
|
324
|
+
failed_to_log(msg)
|
325
|
+
else
|
326
|
+
passed_to_log(msg)
|
327
|
+
true
|
328
|
+
end
|
329
|
+
rescue
|
330
|
+
failed_to_log("Unable to verify that #{msg} '#{$!}'")
|
331
|
+
end
|
332
|
+
|
333
|
+
def overlay?(inner, outer, side = :bottom)
|
334
|
+
#mark_testlevel("#{__method__.to_s.titleize}", 3)
|
335
|
+
inner_t, inner_b, inner_l, inner_r = inner.bounding_rectangle_offsets
|
336
|
+
outer_t, outer_b, outer_l, outer_r = outer.bounding_rectangle_offsets
|
337
|
+
#overlay = false
|
338
|
+
case side
|
339
|
+
when :bottom
|
340
|
+
overlay = inner_b > outer_t
|
341
|
+
when :top
|
342
|
+
overlay = inner_t > outer_t
|
343
|
+
when :left
|
344
|
+
overlay = inner_l < outer_r
|
345
|
+
when :right
|
346
|
+
overlay = inner_r > outer_r
|
347
|
+
when :inside
|
348
|
+
overlay = !(inner_t > outer_t and
|
349
|
+
inner_r < outer_r and
|
350
|
+
inner_l > outer_l and
|
351
|
+
inner_b < outer_b)
|
352
|
+
else
|
353
|
+
overlay = (inner_t > outer_b or
|
354
|
+
inner_r > outer_l or
|
355
|
+
inner_l < outer_r or
|
356
|
+
inner_b < outer_t)
|
357
|
+
end
|
358
|
+
overlay
|
359
|
+
rescue
|
360
|
+
failed_to_log("Unable to determine overlay. '#{$!}'")
|
361
|
+
end
|
362
|
+
|
363
|
+
def pdf_to_text(file, noblank = true)
|
364
|
+
spec = file.sub(/\.pdf$/, '')
|
365
|
+
`pdftotext #{spec}.pdf`
|
366
|
+
file = File.new("#{spec}.txt")
|
367
|
+
text = []
|
368
|
+
file.readlines.each do |l|
|
369
|
+
l.chomp! if noblank
|
370
|
+
if l.length > 0
|
371
|
+
text << l
|
372
|
+
end
|
373
|
+
end
|
374
|
+
file.close
|
375
|
+
text
|
376
|
+
end
|
377
|
+
|
378
|
+
def kill_browser(hwnd, lnbr, browser = nil, doflag = false)
|
379
|
+
# TODO Firefox
|
380
|
+
logit = false
|
381
|
+
if @browserAbbrev == 'FF'
|
382
|
+
if is_browser?(browser) # and browser.url.length > 1
|
383
|
+
logit = true
|
384
|
+
here = __LINE__
|
385
|
+
url = browser.url
|
386
|
+
capture_screen(browser, Time.new.to_f) if @screenCaptureOn
|
387
|
+
browser.close if url.length > 0
|
388
|
+
@status = 'killbrowser'
|
389
|
+
fatal_to_log("Kill browser called from line #{lnbr}")
|
390
|
+
end
|
391
|
+
elsif hwnd
|
392
|
+
pid = Watir::IE::Process.process_id_from_hwnd(hwnd)
|
393
|
+
if pid and pid > 0 and pid < 538976288
|
394
|
+
if browser.exists?
|
395
|
+
here = __LINE__
|
396
|
+
logit = true
|
397
|
+
url = browser.url
|
398
|
+
capture_screen(browser, Time.new.to_f) if @screenCaptureOn
|
399
|
+
browser.close
|
400
|
+
sleep(2)
|
401
|
+
if browser.exists?
|
402
|
+
do_taskkill(FATAL, pid)
|
403
|
+
end
|
404
|
+
@status = 'killbrowser'
|
405
|
+
end
|
406
|
+
end
|
407
|
+
if logit
|
408
|
+
debug_to_log("#{@browserName} window hwnd #{hwnd} pid #{pid} #{url} (#{here})")
|
409
|
+
fatal_to_log("Kill browser called from line #{lnbr}")
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
def do_taskkill(severity, pid)
|
415
|
+
if pid and pid > 0 and pid < 538976288
|
416
|
+
info_to_log("Executing taskkill for pid #{pid}")
|
417
|
+
log_message(severity, %x[taskkill /t /f /pid #{pid}])
|
418
|
+
end
|
419
|
+
rescue
|
420
|
+
error_to_log("#{$!} (#{__LINE__})")
|
421
|
+
end
|
422
|
+
|
423
|
+
def check_for_other_browsers
|
424
|
+
cnt1 = find_other_browsers
|
425
|
+
cnt2 = Watir::Process.count 'iexplore.exe'
|
426
|
+
debug_to_log("check_for_other_browsers: cnt1: #{cnt1} cnt2: #{cnt2}")
|
427
|
+
rescue
|
428
|
+
error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}")
|
429
|
+
end
|
430
|
+
|
431
|
+
def check_for_and_clear_other_browsers
|
432
|
+
if @targetBrowser.abbrev == 'IE'
|
433
|
+
debug_to_log("#{__method__}:")
|
434
|
+
cnt1 = find_other_browsers
|
435
|
+
cnt2 = Watir::IE.process_count
|
436
|
+
debug_to_log("#{__method__}: cnt1: #{cnt1} cnt2: #{cnt2}")
|
437
|
+
begin
|
438
|
+
Watir::IE.each do |ie|
|
439
|
+
pid = Watir::IE::Process.process_id_from_hwnd(ie.hwnd)
|
440
|
+
debug_to_log("#{__method__}: Killing browser process: hwnd #{ie.hwnd} pid #{pid} title '#{ie.title}' (#{__LINE__})")
|
441
|
+
do_taskkill(INFO, pid)
|
442
|
+
sleep_for(10)
|
443
|
+
end
|
444
|
+
#Watir::IE.close_all()
|
445
|
+
rescue
|
446
|
+
debug_to_log("#{__method__}: #{$!} (#{__LINE__})")
|
447
|
+
end
|
448
|
+
sleep(3)
|
449
|
+
cnt1 = find_other_browsers
|
450
|
+
cnt2 = Watir::IE.process_count
|
451
|
+
if cnt1 > 0 or cnt2 > 0
|
452
|
+
debug_to_log("#{__method__}:cnt1: #{cnt1} cnt2: #{cnt2}")
|
453
|
+
begin
|
454
|
+
Watir::IE.each do |ie|
|
455
|
+
pid = Watir::IE::Process.process_id_from_hwnd(ie.hwnd)
|
456
|
+
debug_to_log("#{__method__}: Killing browser process: hwnd #{ie.hwnd} pid #{pid} title '#{ie.title}' (#{__LINE__})")
|
457
|
+
do_taskkill(INFO, pid)
|
458
|
+
sleep_for(10)
|
459
|
+
end
|
460
|
+
#Watir::IE.close_all()
|
461
|
+
rescue
|
462
|
+
debug_to_log("#{__method__}:#{$!} (#{__LINE__})")
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
rescue
|
467
|
+
error_to_log("#{__method__}: #{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}")
|
468
|
+
end
|
469
|
+
|
470
|
+
#def attach_browser(browser, how, what)
|
471
|
+
# debug_to_log("Attaching browser window :#{how}=>'#{what}' ")
|
472
|
+
# uri_decoded_pattern = URI.encode(what.to_s.gsub('(?-mix:', '').gsub(')', ''))
|
473
|
+
# case @browserAbbrev
|
474
|
+
# when 'IE'
|
475
|
+
# tmpbrowser = Watir::IE.attach(how, what)
|
476
|
+
# browser.visible = true
|
477
|
+
# tmpbrowser.visible = true
|
478
|
+
# tmpbrowser.speed = :fast
|
479
|
+
# tmpbrowser
|
480
|
+
# when 'FF'
|
481
|
+
# tmpbrowser = FireWatir::Firefox.attach(how, /#{uri_decoded_pattern}/)
|
482
|
+
# when 'S'
|
483
|
+
# Watir::Safari.attach(how, what)
|
484
|
+
# tmpbrowser = browser
|
485
|
+
# when 'C'
|
486
|
+
# browser.window(how, /#{uri_decoded_pattern}/).use
|
487
|
+
# tmpbrowser = browser
|
488
|
+
# end
|
489
|
+
# debug_to_log("#{__method__}: tmpbrowser:#{tmpbrowser.inspect}")
|
490
|
+
# tmpbrowser
|
491
|
+
#end
|
492
|
+
#
|
493
|
+
def attach_browser(browser, how, what, desc = '')
|
494
|
+
debug_to_log("Attaching browser window :#{how}=>'#{what}' #{desc}")
|
495
|
+
uri_decoded_pattern = URI.encode(what.to_s.gsub('(?-mix:', '').gsub(')', ''))
|
496
|
+
case @browserAbbrev
|
497
|
+
when 'IE'
|
498
|
+
tmpbrowser = Watir::IE.attach(how, what)
|
499
|
+
browser.visible = true
|
500
|
+
if tmpbrowser
|
501
|
+
tmpbrowser.visible = true
|
502
|
+
tmpbrowser.speed = :fast
|
503
|
+
else
|
504
|
+
raise "Browser window :#{how}=>'#{what}' has at least one doc not in completed ready state."
|
505
|
+
end
|
506
|
+
when 'FF'
|
507
|
+
#TODO: This may be dependent on Firefox version if webdriver doesn't support 3.6.17 and below
|
508
|
+
browser.driver.switch_to.window(browser.driver.window_handles[0])
|
509
|
+
browser.window(how, /#{uri_decoded_pattern}/).use
|
510
|
+
tmpbrowser = browser
|
511
|
+
when 'S'
|
512
|
+
Watir::Safari.attach(how, what)
|
513
|
+
tmpbrowser = browser
|
514
|
+
when 'C'
|
515
|
+
browser.window(how, /#{uri_decoded_pattern}/).use
|
516
|
+
tmpbrowser = browser
|
517
|
+
end
|
518
|
+
debug_to_log("#{__method__}: tmpbrowser:#{tmpbrowser.inspect}")
|
519
|
+
tmpbrowser
|
520
|
+
end
|
521
|
+
|
522
|
+
def attach_browser_by_url(browser, pattern, desc = '')
|
523
|
+
attach_browser(browser, :url, pattern, desc)
|
524
|
+
end
|
525
|
+
|
526
|
+
alias attach_browser_with_url attach_browser_by_url
|
527
|
+
|
528
|
+
def attach_popup(browser, how, what, desc = '')
|
529
|
+
msg = "Attach popup :#{how}=>'#{what}'. #{desc}"
|
530
|
+
popup = attach_browser(browser, how, what, desc)
|
531
|
+
sleep_for(1)
|
532
|
+
debug_to_log("#{popup.inspect}")
|
533
|
+
if is_browser?(popup)
|
534
|
+
title = popup.title
|
535
|
+
passed_to_log("#{msg} title='#{title}'")
|
536
|
+
return popup
|
537
|
+
else
|
538
|
+
failed_to_log(msg)
|
539
|
+
end
|
540
|
+
rescue
|
541
|
+
failed_to_log("Unable to attach popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
|
542
|
+
end
|
543
|
+
|
544
|
+
def attach_popup_by_title(browser, strg, desc = '')
|
545
|
+
attach_popup(browser, :title, strg, desc)
|
546
|
+
end
|
547
|
+
|
548
|
+
def attach_popup_by_url(browser, pattern, desc = '')
|
549
|
+
attach_popup(browser, :url, pattern, desc)
|
550
|
+
end
|
551
|
+
|
552
|
+
alias get_popup_with_url attach_popup_by_url
|
553
|
+
alias attach_popup_with_url attach_popup_by_url
|
554
|
+
alias attach_iepopup attach_popup_by_url
|
555
|
+
|
556
|
+
def clear_checkbox(browser, how, what, value = nil, desc = '')
|
557
|
+
msg = "Clear checkbox #{how}=>'#{what}'"
|
558
|
+
msg << " ('#{value}')" if value
|
559
|
+
msg << " #{desc}'" if desc.length > 0
|
560
|
+
browser.checkbox(how, what).clear
|
561
|
+
if validate(browser, @myName, __LINE__)
|
562
|
+
passed_to_log(msg)
|
563
|
+
true
|
564
|
+
end
|
565
|
+
rescue
|
566
|
+
failed_to_log("Unable to #{msg} '#{$!}'")
|
567
|
+
end
|
568
|
+
|
569
|
+
def clear_checkbox_by_name(browser, strg, value = nil, desc = '')
|
570
|
+
clear_checkbox(browser, :name, strg, value, desc)
|
571
|
+
end
|
572
|
+
|
573
|
+
def clear_checkbox_by_id(browser, strg, value = nil, desc = '')
|
574
|
+
clear_checkbox(browser, :id, strg, value, desc)
|
575
|
+
end
|
576
|
+
|
577
|
+
def find_other_browsers
|
578
|
+
cnt = 0
|
579
|
+
if @targetBrowser.abbrev == 'IE'
|
580
|
+
Watir::IE.each do |ie|
|
581
|
+
debug_to_log("#{ie.inspect}")
|
582
|
+
ie.close()
|
583
|
+
cnt = cnt + 1
|
584
|
+
end
|
585
|
+
end
|
586
|
+
debug_to_log("Found #{cnt} IE browser(s).")
|
587
|
+
return cnt
|
588
|
+
rescue
|
589
|
+
error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}", __LINE__)
|
590
|
+
return 0
|
591
|
+
end
|
592
|
+
|
593
|
+
def get_trace(lnbr)
|
594
|
+
callertrace = "\nCaller trace: (#{lnbr})\n"
|
595
|
+
Kernel.caller.each_index do |x|
|
596
|
+
callertrace << ' >> ' + Kernel.caller[x].to_s + "\n"
|
597
|
+
end
|
598
|
+
callertrace
|
599
|
+
end
|
600
|
+
|
601
|
+
alias dump_caller get_trace
|
602
|
+
|
603
|
+
def translate_var_list(key)
|
604
|
+
if @var[key] and @var[key].length > 0
|
605
|
+
list = @var[key].dup
|
606
|
+
unless list =~ /^\[.+\]$/
|
607
|
+
list = "[#{list}]"
|
608
|
+
end
|
609
|
+
eval(list)
|
610
|
+
end
|
611
|
+
rescue
|
612
|
+
failed_to_log("#{__method__}: '#{$!}'")
|
613
|
+
end
|
614
|
+
|
615
|
+
def get_variables(file, login = :role, dbg = true)
|
616
|
+
debug_to_log("#{__method__}: file = #{file}")
|
617
|
+
debug_to_log("#{__method__}: role = #{login}")
|
618
|
+
|
619
|
+
@var = Hash.new
|
620
|
+
workbook = Excel.new(file)
|
621
|
+
data_index = find_sheet_with_name(workbook, 'Data')
|
622
|
+
workbook.default_sheet = workbook.sheets[data_index]
|
623
|
+
var_col = 0
|
624
|
+
|
625
|
+
2.upto(workbook.last_column) do |col|
|
626
|
+
scriptName = workbook.cell(1, col)
|
627
|
+
if scriptName == @myName
|
628
|
+
var_col = col
|
629
|
+
break
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
2.upto(workbook.last_row) do |line|
|
634
|
+
name = workbook.cell(line, 'A')
|
635
|
+
value = workbook.cell(line, var_col).to_s.strip
|
636
|
+
@var[name] = value
|
637
|
+
end
|
638
|
+
|
639
|
+
@var.keys.sort.each do |name|
|
640
|
+
message_tolog("@var #{name}: '#{@var[name]}'")
|
641
|
+
end if dbg
|
642
|
+
|
643
|
+
@login = Hash.new
|
644
|
+
login_col = 0
|
645
|
+
role_col = 0
|
646
|
+
userid_col = 0
|
647
|
+
password_col = 0
|
648
|
+
url_col = 0
|
649
|
+
name_col = 0
|
650
|
+
role_index = find_sheet_with_name(workbook, 'Login')
|
651
|
+
if role_index >= 0
|
652
|
+
workbook.default_sheet = workbook.sheets[role_index]
|
653
|
+
|
654
|
+
1.upto(workbook.last_column) do |col|
|
655
|
+
a_cell = workbook.cell(1, col)
|
656
|
+
case a_cell
|
657
|
+
when @myName
|
658
|
+
login_col = col
|
659
|
+
break
|
660
|
+
when 'role'
|
661
|
+
role_col = col
|
662
|
+
when 'userid'
|
663
|
+
userid_col = col
|
664
|
+
when 'password'
|
665
|
+
password_col = col
|
666
|
+
when 'url'
|
667
|
+
url_col = col
|
668
|
+
when 'name'
|
669
|
+
name_col = col
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
2.upto(workbook.last_row) do |line|
|
674
|
+
role = workbook.cell(line, role_col)
|
675
|
+
userid = workbook.cell(line, userid_col)
|
676
|
+
password = workbook.cell(line, password_col)
|
677
|
+
url = workbook.cell(line, url_col)
|
678
|
+
username = workbook.cell(line, name_col)
|
679
|
+
enabled = workbook.cell(line, login_col).to_s
|
680
|
+
|
681
|
+
case login
|
682
|
+
when :id
|
683
|
+
key = userid
|
684
|
+
when :role
|
685
|
+
key = role
|
686
|
+
else
|
687
|
+
key = role
|
688
|
+
end
|
689
|
+
|
690
|
+
@login[key] = Hash.new
|
691
|
+
@login[key]['role'] = role
|
692
|
+
@login[key]['userid'] = userid
|
693
|
+
@login[key]['password'] = password
|
694
|
+
@login[key]['url'] = url
|
695
|
+
@login[key]['name'] = username
|
696
|
+
@login[key]['enabled'] = enabled
|
697
|
+
|
698
|
+
end
|
699
|
+
|
700
|
+
@login.keys.sort.each do |key|
|
701
|
+
message_tolog("@login (by #{login}): #{key}=>'#{@login[key].to_yaml}'")
|
702
|
+
end if dbg
|
703
|
+
end
|
704
|
+
|
705
|
+
rescue
|
706
|
+
fatal_to_log("#{__method__}: '#{$!}'")
|
707
|
+
end
|
708
|
+
|
709
|
+
def grab_window_list(strg)
|
710
|
+
@ai.AutoItSetOption("WinTitleMatchMode", 2)
|
711
|
+
list = @ai.WinList(strg)
|
712
|
+
stuff = ''
|
713
|
+
names = list[0]
|
714
|
+
handles = list[1]
|
715
|
+
max = names.length - 1
|
716
|
+
rng = Range.new(0, max)
|
717
|
+
rng.each do |idx|
|
718
|
+
window_handle = "[HANDLE:#{handles[idx]}]"
|
719
|
+
full_text = @ai.WinGetText(window_handle)
|
720
|
+
stuff << "[#{handles[idx]}]=>#{names[idx]}=>'#{full_text}'\n"
|
721
|
+
end
|
722
|
+
debug_to_log("\n#{stuff}")
|
723
|
+
@ai.AutoItSetOption("WinTitleMatchMode", 1)
|
724
|
+
stuff
|
725
|
+
end
|
726
|
+
|
727
|
+
def debug_call_list(msg)
|
728
|
+
call_array = get_call_array
|
729
|
+
debug_to_log("#{msg}\n#{dump_array(call_array)}")
|
730
|
+
end
|
731
|
+
|
732
|
+
# TODO ugly, gotta lose the hardcoding...
|
733
|
+
def decode_options(strg)
|
734
|
+
idx = 0
|
735
|
+
@options = Hash.new
|
736
|
+
strg.each_char do |c|
|
737
|
+
idx = idx + 1
|
738
|
+
case idx
|
739
|
+
when 1
|
740
|
+
@options['load'] = c.to_i
|
741
|
+
when 2
|
742
|
+
@options['screenshot'] = c.to_i
|
743
|
+
if c.to_i > 0
|
744
|
+
@screenCaptureOn = true
|
745
|
+
end
|
746
|
+
when 3
|
747
|
+
@options['hiderun'] = c.to_i
|
748
|
+
# when 4
|
749
|
+
# @options['another'] = c.to_i
|
750
|
+
end
|
751
|
+
|
752
|
+
end
|
753
|
+
# puts @options.to_yaml
|
754
|
+
end
|
755
|
+
|
756
|
+
def click_popup_button(title, button, waitTime= 9, user_input=nil)
|
757
|
+
#TODO: is winclicker still viable/available?
|
758
|
+
wc = WinClicker.new
|
759
|
+
if wc.clickWindowsButton(title, button, waitTime)
|
760
|
+
passed_to_log("Window '#{title}' button '#{button}' found and clicked.")
|
761
|
+
true
|
762
|
+
else
|
763
|
+
failed_to_log("Window '#{title}' button '#{button}' not found. (#{__LINE__})")
|
764
|
+
end
|
765
|
+
wc = nil
|
766
|
+
# get a handle if one exists
|
767
|
+
# hwnd = $ie.enabled_popup(waitTime)
|
768
|
+
# if (hwnd) # yes there is a popup
|
769
|
+
# w = WinClicker.new
|
770
|
+
# if ( user_input )
|
771
|
+
# w.setTextValueForFileNameField( hwnd, "#{user_input}" )
|
772
|
+
# end
|
773
|
+
# # I put this in to see the text being input it is not necessary to work
|
774
|
+
# sleep 3
|
775
|
+
# # "OK" or whatever the name on the button is
|
776
|
+
# w.clickWindowsButton_hwnd( hwnd, "#{button}" )
|
777
|
+
# #
|
778
|
+
# # this is just cleanup
|
779
|
+
# w=nil
|
780
|
+
# end
|
781
|
+
end
|
782
|
+
|
783
|
+
def get_select_list(browser, how, what, desc = '')
|
784
|
+
list = browser.select_list(how, what)
|
785
|
+
if validate(browser, @myName, __LINE__)
|
786
|
+
passed_to_log("Select list #{how}='#{what}' found and returned.")
|
787
|
+
return list
|
788
|
+
end
|
789
|
+
rescue
|
790
|
+
failed_to_log("Unable to return select list #{how}='#{what}': '#{$!}' (#{__LINE__})")
|
791
|
+
end
|
792
|
+
|
793
|
+
def get_select_options(browser, how, what, dump = false)
|
794
|
+
list = browser.select_list(how, what)
|
795
|
+
dump_select_list_options(list) if dump
|
796
|
+
list.options
|
797
|
+
rescue
|
798
|
+
failed_to_log("Unable to get select options for #{how}=>#{what}. '#{$!}'")
|
799
|
+
end
|
800
|
+
|
801
|
+
def get_select_options_by_id(browser, strg, dump = false)
|
802
|
+
get_select_options(browser, :id, strg, dump)
|
803
|
+
end
|
804
|
+
|
805
|
+
def get_select_options_by_name(browser, strg, dump = false)
|
806
|
+
get_select_options(browser, :name, strg, dump)
|
807
|
+
end
|
808
|
+
|
809
|
+
def get_selected_options(browser, how, what)
|
810
|
+
begin
|
811
|
+
list = browser.select_list(how, what)
|
812
|
+
rescue => e
|
813
|
+
if not rescue_me(e, __method__, "browser.select_list(#{how}, '#{what}')", "#{browser.class}")
|
814
|
+
raise e
|
815
|
+
end
|
816
|
+
end
|
817
|
+
list.selected_options
|
818
|
+
end
|
819
|
+
|
820
|
+
def get_selected_options_by_id(browser, strg)
|
821
|
+
get_selected_options(browser, :id, strg)
|
822
|
+
end
|
823
|
+
|
824
|
+
alias get_selected_option_by_id get_selected_options_by_id
|
825
|
+
|
826
|
+
def get_selected_options_by_name(browser, strg)
|
827
|
+
get_selected_options(browser, :name, strg)
|
828
|
+
end
|
829
|
+
|
830
|
+
alias get_selected_option_by_name get_selected_options_by_name
|
831
|
+
|
832
|
+
def sec2hms(s)
|
833
|
+
Time.at(s.to_i).gmtime.strftime('%H:%M:%S')
|
834
|
+
end
|
835
|
+
|
836
|
+
def select(browser, how, what, which, value, desc = '')
|
837
|
+
msg = "Select option #{which}='#{value}' from list #{how}=#{what}. #{desc}"
|
838
|
+
list = browser.select_list(how, what)
|
839
|
+
case which
|
840
|
+
when :text
|
841
|
+
list.select(value)
|
842
|
+
when :value
|
843
|
+
list.select_value(value)
|
844
|
+
when :index
|
845
|
+
all = list.getAllContents
|
846
|
+
txt = all[value]
|
847
|
+
list.select(txt)
|
848
|
+
else
|
849
|
+
na = "#{__method__} cannot support select by '#{which}'. (#{msg})"
|
850
|
+
debug_to_log(na, __LINE__, true)
|
851
|
+
raise na
|
852
|
+
end
|
853
|
+
passed_to_log(msg)
|
854
|
+
rescue
|
855
|
+
failed_to_log("#Unable to #{msg}': '#{$!}'")
|
856
|
+
end
|
857
|
+
|
858
|
+
def select_option_from_list(list, what, what_strg, desc = '')
|
859
|
+
ok = true
|
860
|
+
msg = "#{__method__.to_s.titleize} "
|
861
|
+
if list
|
862
|
+
msg << "list id=#{list.id}: "
|
863
|
+
case what
|
864
|
+
when :text
|
865
|
+
list.select(what_strg) #TODO: regex?
|
866
|
+
when :value
|
867
|
+
list.select_value(what_strg) #TODO: regex?
|
868
|
+
when :index
|
869
|
+
list.select(list.getAllContents[what_strg.to_i])
|
870
|
+
else
|
871
|
+
msg << "select by #{what} not supported. #{desc} (#{__LINE__})"
|
872
|
+
failed_to_log(msg)
|
873
|
+
ok = false
|
874
|
+
end
|
875
|
+
if ok
|
876
|
+
msg << "#{what}='#{what_strg}' selected. #{desc}"
|
877
|
+
passed_to_log(msg)
|
878
|
+
true
|
879
|
+
end
|
880
|
+
else
|
881
|
+
failed_to_log("#{__method__.to_s.titleize} list not found. #{desc} (#{__LINE__})")
|
882
|
+
end
|
883
|
+
rescue
|
884
|
+
failed_to_log("#{__method__.to_s.titleize}: #{what}='#{what_strg}' could not be selected: '#{$!}'. #{desc} (#{__LINE__})")
|
885
|
+
end
|
886
|
+
|
887
|
+
def select_option_by_id_and_option_text(browser, strg, option, nofail=false, desc = '')
|
888
|
+
msg = "Select list id=#{strg} option text='#{option}' selected."
|
889
|
+
msg << " #{desc}" if desc.length > 0
|
890
|
+
list = browser.select_list(:id, strg)
|
891
|
+
list.select(option)
|
892
|
+
# browser.select_list(:id, strg).select(option) #(browser.select_list(:id, strg).getAllContents[option])
|
893
|
+
if validate(browser, @myName, __LINE__)
|
894
|
+
passed_to_log(msg)
|
895
|
+
true
|
896
|
+
end
|
897
|
+
rescue
|
898
|
+
if !nofail
|
899
|
+
failed_to_log("#{msg} '#{$!}'")
|
900
|
+
end
|
901
|
+
end
|
902
|
+
|
903
|
+
alias select_option_by_id select_option_by_id_and_option_text
|
904
|
+
alias select_option_by_id_and_text select_option_by_id_and_option_text
|
905
|
+
|
906
|
+
def select_option_by_name_and_option_text(browser, strg, option, desc = '')
|
907
|
+
msg = "Select list name=#{strg} option text='#{option}' selected."
|
908
|
+
msg << " #{desc}" if desc.length > 0
|
909
|
+
begin
|
910
|
+
list = browser.select_list(:name, strg)
|
911
|
+
rescue => e
|
912
|
+
if not rescue_me(e, __method__, "#{__LINE__}: select_list(:name,'#{strg}')", "#{browser.class}")
|
913
|
+
raise e
|
914
|
+
end
|
915
|
+
end
|
916
|
+
begin
|
917
|
+
list.select(option)
|
918
|
+
rescue => e
|
919
|
+
if not rescue_me(e, __method__, "#{__LINE__}: select_list#select('#{option}')", "#{browser.class}")
|
920
|
+
raise e
|
921
|
+
end
|
922
|
+
end
|
923
|
+
if validate(browser, @myName, __LINE__)
|
924
|
+
passed_to_log(msg)
|
925
|
+
true
|
926
|
+
end
|
927
|
+
rescue
|
928
|
+
failed_to_log("#{msg} '#{$!}'")
|
929
|
+
end
|
930
|
+
|
931
|
+
alias select_option_by_name select_option_by_name_and_option_text
|
932
|
+
|
933
|
+
def select_option_by_title_and_option_text(browser, strg, option, desc = '')
|
934
|
+
msg = "Select list name=#{strg} option text='#{option}' selected."
|
935
|
+
msg << " #{desc}" if desc.length > 0
|
936
|
+
browser.select_list(:title, strg).select(option)
|
937
|
+
if validate(browser, @myName, __LINE__)
|
938
|
+
passed_to_log(msg)
|
939
|
+
end
|
940
|
+
rescue
|
941
|
+
failed_to_log("#{msg} '#{$!}'")
|
942
|
+
end
|
943
|
+
|
944
|
+
def select_option_by_class_and_option_text(browser, strg, option, desc = '')
|
945
|
+
msg = "Select list class=#{strg} option text='#{option}' selected."
|
946
|
+
msg << " #{desc}" if desc.length > 0
|
947
|
+
browser.select_list(:class, strg).select(option)
|
948
|
+
if validate(browser, @myName, __LINE__)
|
949
|
+
passed_to_log(msg)
|
950
|
+
true
|
951
|
+
end
|
952
|
+
rescue
|
953
|
+
failed_to_log("#{msg} '#{$!}'")
|
954
|
+
end
|
955
|
+
|
956
|
+
def select_option_by_name_and_option_value(browser, strg, option, desc = '')
|
957
|
+
msg = "Select list name=#{strg} option value='#{option}' selected."
|
958
|
+
msg << " #{desc}" if desc.length > 0
|
959
|
+
begin
|
960
|
+
list = browser.select_list(:name, strg)
|
961
|
+
rescue => e
|
962
|
+
if not rescue_me(e, __method__, "#{__LINE__}: select_list(:name,'#{strg}')", "#{browser.class}")
|
963
|
+
raise e
|
964
|
+
end
|
965
|
+
end
|
966
|
+
begin
|
967
|
+
list.select_value(option)
|
968
|
+
rescue => e
|
969
|
+
if not rescue_me(e, __method__, "#{__LINE__}: select_list#select_value('#{option}')", "#{browser.class}")
|
970
|
+
raise e
|
971
|
+
end
|
972
|
+
end
|
973
|
+
if validate(browser, @myName, __LINE__)
|
974
|
+
passed_to_log(msg)
|
975
|
+
true
|
976
|
+
end
|
977
|
+
rescue
|
978
|
+
failed_to_log("#{msg} '#{$!}'")
|
979
|
+
end
|
980
|
+
|
981
|
+
def select_option_by_id_and_option_value(browser, strg, option, desc = '')
|
982
|
+
msg = "Select list name=#{strg} option value='#{option}' selected."
|
983
|
+
msg << " #{desc}" if desc.length > 0
|
984
|
+
begin
|
985
|
+
list = browser.select_list(:id, strg)
|
986
|
+
rescue => e
|
987
|
+
if not rescue_me(e, __method__, "#{__LINE__}: select_list(:text,'#{strg}')", "#{browser.class}")
|
988
|
+
raise e
|
989
|
+
end
|
990
|
+
end
|
991
|
+
sleep(0.5) unless @targetBrowser.abbrev == 'IE'
|
992
|
+
begin
|
993
|
+
list.select_value(option)
|
994
|
+
rescue => e
|
995
|
+
if not rescue_me(e, __method__, "#{__LINE__}: select_list#select_value('#{option}')", "#{browser.class}")
|
996
|
+
raise e
|
997
|
+
end
|
998
|
+
end
|
999
|
+
if validate(browser, @myName, __LINE__)
|
1000
|
+
passed_to_log(msg)
|
1001
|
+
true
|
1002
|
+
end
|
1003
|
+
rescue
|
1004
|
+
failed_to_log("#{msg} '#{$!}'")
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
def select_option_by_id_and_index(browser, strg, idx, desc = '')
|
1008
|
+
msg = "Select list id=#{strg} index='#{idx}' selected."
|
1009
|
+
msg << " #{desc}" if desc.length > 0
|
1010
|
+
list = browser.select_list(:id, strg)
|
1011
|
+
all = list.getAllContents
|
1012
|
+
txt = all[idx]
|
1013
|
+
browser.select_list(:id, strg).set(browser.select_list(:id, strg).getAllContents[idx])
|
1014
|
+
if validate(browser, @myName, __LINE__)
|
1015
|
+
passed_to_log(msg)
|
1016
|
+
true
|
1017
|
+
end
|
1018
|
+
rescue
|
1019
|
+
failed_to_log("#{msg} '#{$!}'")
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
# TODO add check that both list and option exist
|
1023
|
+
def select_option_by_name_and_index(browser, strg, idx)
|
1024
|
+
msg = "Select list name=#{strg} index='#{idx}' selected."
|
1025
|
+
msg << " #{desc}" if desc.length > 0
|
1026
|
+
browser.select_list(:name, strg).set(browser.select_list(:name, strg).getAllContents[idx])
|
1027
|
+
if validate(browser, @myName, __LINE__)
|
1028
|
+
passed_to_log(msg)
|
1029
|
+
true
|
1030
|
+
end
|
1031
|
+
rescue
|
1032
|
+
failed_to_log("#{msg} '#{$!}'")
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
def select_option_by_xpath_and_index(browser, strg, idx)
|
1036
|
+
msg = "Select list xpath=#{strg} index='#{idx}' selected."
|
1037
|
+
msg << " #{desc}" if desc.length > 0
|
1038
|
+
browser.select_list(:xpath, strg).set(browser.select_list(:xpath, strg).getAllContents[idx])
|
1039
|
+
if validate(browser, nil, __LINE__)
|
1040
|
+
passed_to_log(msg)
|
1041
|
+
true
|
1042
|
+
end
|
1043
|
+
rescue
|
1044
|
+
failed_to_log("#{msg} '#{$!}'")
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
def set(browser, element, how, what, value = nil, desc = '')
|
1048
|
+
msg = "Set #{element} #{how}=>'#{what}' "
|
1049
|
+
msg << "('#{value.to_s}')" if value
|
1050
|
+
msg << " '#{desc}' " if desc.length > 0
|
1051
|
+
case element
|
1052
|
+
when :radio
|
1053
|
+
browser.radio(how, what, value).set
|
1054
|
+
when :checkbox
|
1055
|
+
browser.checkbox(how, what, value).set
|
1056
|
+
else
|
1057
|
+
failed_to_log("#{__method__}: #{element} not supported")
|
1058
|
+
end
|
1059
|
+
if validate(browser, @myName, __LINE__)
|
1060
|
+
passed_to_log(msg)
|
1061
|
+
true
|
1062
|
+
end
|
1063
|
+
rescue
|
1064
|
+
failed_to_log("#{msg} '#{$!}'")
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
def set_checkbox(browser, how, what, desc = '')
|
1068
|
+
set(browser, :checkbox, how, what, nil, desc)
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
def set_checkbox_by_class(browser, strg, value = nil, desc = '')
|
1072
|
+
set(browser, :checkbox, :class, strg, value, desc)
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
def set_checkbox_by_id(browser, strg, value = nil, desc = '')
|
1076
|
+
set(browser, :checkbox, :id, strg, value, desc)
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
def set_checkbox_by_name(browser, strg, value = nil, desc = '')
|
1080
|
+
set(browser, :checkbox, :name, strg, value, desc)
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
def set_checkbox_by_title(browser, strg, value = nil, desc = '')
|
1084
|
+
set(browser, :checkbox, :title, strg, value, desc)
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
def set_checkbox_by_value(browser, strg, desc = '')
|
1088
|
+
set(browser, :checkbox, :value, strg, nil, desc)
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
def set_radio(browser, how, what, value = nil, desc = '')
|
1092
|
+
if how == :value
|
1093
|
+
set_radio_by_value(browser, what, desc)
|
1094
|
+
else
|
1095
|
+
set(browser, :radio, how, what, value, desc)
|
1096
|
+
end
|
1097
|
+
rescue
|
1098
|
+
failed_to_log("#{msg} '#{$!}'")
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
def set_radio_two_attributes(browser, how1, what1, how2, what2, desc = '')
|
1102
|
+
msg = "Set radio #{how1}='#{what1}', #{how2}= #{what2}"
|
1103
|
+
msg << " '#{desc}' " if desc.length > 0
|
1104
|
+
browser.radio(how1 => what1, how2 => what2).set
|
1105
|
+
if validate(browser, @myName, __LINE__)
|
1106
|
+
passed_to_log(msg)
|
1107
|
+
true
|
1108
|
+
end
|
1109
|
+
rescue
|
1110
|
+
failed_to_log("#{msg} '#{$!}'")
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
def set_radio_by_class(browser, strg, value = nil, desc = '')
|
1114
|
+
set(browser, :radio, :class, strg, value, desc)
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
def set_radio_by_id(browser, strg, value = nil, desc = '')
|
1118
|
+
set(browser, :radio, :id, strg, value, desc)
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
def set_radio_by_index(browser, index, desc = '')
|
1122
|
+
set(browser, :radio, :index, index, nil, desc)
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
def set_radio_by_name(browser, strg, value = nil, desc = '')
|
1126
|
+
set(browser, :radio, :name, strg, value, desc)
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
def set_radio_by_title(browser, strg, value = nil, desc = '')
|
1130
|
+
set(browser, :radio, :title, strg, value, desc)
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
def set_radio_no_wait_by_index(browser, index, desc = '')
|
1134
|
+
#TODO: Not supported by Watir 1.8.x
|
1135
|
+
msg = "Radio :index=#{index} "
|
1136
|
+
radios = browser.radios
|
1137
|
+
debug_to_log("\n#{radios}")
|
1138
|
+
radio = radios[index]
|
1139
|
+
debug_to_log("\n#{radio}")
|
1140
|
+
radio.click_no_wait
|
1141
|
+
if validate(browser)
|
1142
|
+
msg << 'set ' + desc
|
1143
|
+
passed_to_log(msg)
|
1144
|
+
true
|
1145
|
+
end
|
1146
|
+
rescue
|
1147
|
+
msg << 'not found ' + desc
|
1148
|
+
failed_to_log("#{msg} (#{__LINE__})")
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
def set_radio_by_value(browser, strg, desc = '')
|
1152
|
+
msg = "Radio :value=>'#{strg}' "
|
1153
|
+
msg << " '#{desc}' " if desc.length > 0
|
1154
|
+
browser.radio(:value, strg).set
|
1155
|
+
if validate(browser, @myName, __LINE__)
|
1156
|
+
passed_to_log(msg)
|
1157
|
+
true
|
1158
|
+
end
|
1159
|
+
rescue
|
1160
|
+
failed_to_log("#{msg} '#{$!}'")
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
def set_radio_by_name_and_index(browser, name, index, desc = '')
|
1164
|
+
set_radio_two_attributes(browser, :name, name, :index, index, desc)
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
def set_radio_by_name_and_text(browser, name, text, desc = '')
|
1168
|
+
set_radio_two_attributes(browser, :name, name, :text, text, desc)
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
def set_radio_by_value_and_index(browser, value, index, desc = '')
|
1172
|
+
set_radio_two_attributes(browser, :value, value, :index, index, desc)
|
1173
|
+
end
|
1174
|
+
|
1175
|
+
def set_radio_by_name_and_value(browser, strg, value, desc = '')
|
1176
|
+
set(browser, :radio, :name, strg, value, desc)
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
# No validation
|
1180
|
+
def clear(browser, element, how, what, value = nil, desc = '')
|
1181
|
+
msg = "Clear #{element} #{how}=>'#{what}' "
|
1182
|
+
msg << "('#{value.to_s}')" if value
|
1183
|
+
msg << " '#{desc}' " if desc.length > 0
|
1184
|
+
case element
|
1185
|
+
when :radio
|
1186
|
+
browser.radio(how, what, value).clear
|
1187
|
+
when :checkbox
|
1188
|
+
browser.checkbox(how, what, value).clear
|
1189
|
+
when :text_field
|
1190
|
+
browser.text_field(how, what).set('')
|
1191
|
+
else
|
1192
|
+
failed_to_log("#{__method__}: #{element} not supported")
|
1193
|
+
end
|
1194
|
+
if validate(browser, @myName, __LINE__)
|
1195
|
+
passed_to_log(msg)
|
1196
|
+
true
|
1197
|
+
end
|
1198
|
+
rescue
|
1199
|
+
failed_to_log("#{msg} '#{$!}'")
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
def clear_radio(browser, how, what, value = nil, desc = '')
|
1203
|
+
msg = "Clear radio #{how}=>'#{what.to_s}' "
|
1204
|
+
msg << "('#{value.to_s}')" if value
|
1205
|
+
msg << " '#{desc}' " if desc.length > 0
|
1206
|
+
radio = browser.radio(how, what, value)
|
1207
|
+
radio.clear
|
1208
|
+
if validate(browser, @myName, __LINE__)
|
1209
|
+
passed_to_log(msg)
|
1210
|
+
true
|
1211
|
+
end
|
1212
|
+
rescue
|
1213
|
+
failed_to_log("#{msg} '#{$!}'")
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
# Set skip_value_check = true when string is altered by application and/or
|
1217
|
+
# this method will be followed by validate_text
|
1218
|
+
def clear_textfield(browser, how, which, skip_value_check = false)
|
1219
|
+
if browser.text_field(how, which).exists?
|
1220
|
+
tf = browser.text_field(how, which)
|
1221
|
+
if validate(browser, @myName, __LINE__)
|
1222
|
+
tf.clear
|
1223
|
+
if validate(browser, @myName, __LINE__)
|
1224
|
+
if tf.value == ''
|
1225
|
+
passed_to_log("Textfield #{how}='#{which}' cleared.")
|
1226
|
+
true
|
1227
|
+
elsif skip_value_check
|
1228
|
+
passed_to_log("Textfield #{how}='#{which}' cleared. (skip value check)")
|
1229
|
+
true
|
1230
|
+
else
|
1231
|
+
failed_to_log("Textfield #{how}='#{which}' not cleared: Found:'#{tf.value}'. (#{__LINE__})")
|
1232
|
+
end
|
1233
|
+
end
|
1234
|
+
end
|
1235
|
+
else
|
1236
|
+
failed_to_log("Textfield id='#{id}' to clear. (#{__LINE__})")
|
1237
|
+
end
|
1238
|
+
rescue
|
1239
|
+
failed_to_log("Textfield id='#{id}' could not be cleared: '#{$!}'. (#{__LINE__})")
|
1240
|
+
end
|
1241
|
+
|
1242
|
+
def close_window_by_title(browser, title, desc = '', text = '')
|
1243
|
+
msg = "Window '#{title}':"
|
1244
|
+
if @ai.WinWait(title, text, WAIT) > 0
|
1245
|
+
passed_to_log("#{msg} appeared. #{desc}")
|
1246
|
+
myHandle = @ai.WinGetHandle(title, text)
|
1247
|
+
full_text = @ai.WinGetText(title)
|
1248
|
+
debug_to_log("#{msg} hwnd: #{myHandle.inspect}")
|
1249
|
+
debug_to_log("#{msg} title: '#{title}' text: '#{full_text}'")
|
1250
|
+
if @ai.WinClose(title, text) > 0
|
1251
|
+
passed_to_log("#{msg} closed successfully. #{desc}")
|
1252
|
+
else
|
1253
|
+
failed_to_log("#{msg} close failed. (#{__LINE__}) #{desc}")
|
1254
|
+
end
|
1255
|
+
else
|
1256
|
+
failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__}) #{desc}")
|
1257
|
+
end
|
1258
|
+
rescue
|
1259
|
+
failed_to_log("#{msg}: Unable to close: '#{$!}'. (#{__LINE__}) #{desc}")
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
def set_file_field(browser, how, what, filespec, desc = '')
|
1263
|
+
msg = "Set file field #{how}=>#{what} to '#{filespec}."
|
1264
|
+
msg << " #{desc}" if desc.length > 0
|
1265
|
+
ff = browser.file_field(how, what)
|
1266
|
+
if ff
|
1267
|
+
ff.set filespec
|
1268
|
+
sleep_for(8)
|
1269
|
+
if validate(browser, @myName, __LINE__)
|
1270
|
+
passed_to_log(msg)
|
1271
|
+
true
|
1272
|
+
end
|
1273
|
+
else
|
1274
|
+
failed_to_log("#{msg} File field not found.")
|
1275
|
+
end
|
1276
|
+
rescue
|
1277
|
+
failed_to_log("Unable to #{msg} '#{$!}'")
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
def set_file_field_by_name(browser, strg, path, desc = '')
|
1281
|
+
set_file_field(browser, :name, strg, path, desc)
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
def set_file_field_by_id(browser, strg, path, desc = '')
|
1285
|
+
set_file_field(browser, :id, strg, path, desc)
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
def set_text_field(browser, how, what, value, desc = '', skip_value_check = false)
|
1289
|
+
#TODO: fix this to handle Safari password field
|
1290
|
+
msg = "Set textfield #{how}='#{what}' to '#{value}'"
|
1291
|
+
msg << " #{desc}" if desc.length > 0
|
1292
|
+
msg << " (Skip value check)" if skip_value_check
|
1293
|
+
if browser.text_field(how, what).exists?
|
1294
|
+
tf = browser.text_field(how, what)
|
1295
|
+
debug_to_log("#{tf.inspect}")
|
1296
|
+
if validate(browser, @myName, __LINE__)
|
1297
|
+
tf.set(value)
|
1298
|
+
if validate(browser, @myName, __LINE__)
|
1299
|
+
if tf.value == value
|
1300
|
+
passed_to_log(msg)
|
1301
|
+
true
|
1302
|
+
elsif skip_value_check
|
1303
|
+
passed_to_log(msg)
|
1304
|
+
true
|
1305
|
+
else
|
1306
|
+
failed_to_log("#{msg}: Found:'#{tf.value}'.")
|
1307
|
+
end
|
1308
|
+
end
|
1309
|
+
end
|
1310
|
+
else
|
1311
|
+
failed_to_log("Textfield #{how}='#{what}' not found to set to '#{value}''")
|
1312
|
+
end
|
1313
|
+
rescue
|
1314
|
+
failed_to_log("Unable to '#{msg}': '#{$!}'")
|
1315
|
+
end
|
1316
|
+
|
1317
|
+
alias set_textfield set_text_field
|
1318
|
+
|
1319
|
+
def set_textfield_by_name(browser, name, value, desc = '', skip_value_check = false)
|
1320
|
+
if browser.text_field(:name, name).exists?
|
1321
|
+
tf = browser.text_field(:name, name)
|
1322
|
+
# Workaround because browser.text_field doesn't work for password fields in Safari
|
1323
|
+
elsif @browserAbbrev.eql?("S")
|
1324
|
+
tf = browser.password(:name, name)
|
1325
|
+
end
|
1326
|
+
if tf.exists?
|
1327
|
+
if validate(browser, @myName, __LINE__)
|
1328
|
+
tf.set(value)
|
1329
|
+
if validate(browser, @myName, __LINE__)
|
1330
|
+
if tf.value == value
|
1331
|
+
passed_to_log("Set textfield name='#{name}' to '#{value}' #{desc}")
|
1332
|
+
true
|
1333
|
+
elsif skip_value_check
|
1334
|
+
passed_to_log("Set textfield name='#{name}' to '#{value}' #{desc} (skip value check)")
|
1335
|
+
true
|
1336
|
+
else
|
1337
|
+
failed_to_log("Set textfield name='#{name}' to '#{value}': Found:'#{tf.value}'. #{desc} (#{__LINE__})")
|
1338
|
+
end
|
1339
|
+
end
|
1340
|
+
end
|
1341
|
+
else
|
1342
|
+
failed_to_log("Textfield name='#{name}' not found to set to '#{value}'. #{desc} (#{__LINE__})")
|
1343
|
+
end
|
1344
|
+
rescue
|
1345
|
+
failed_to_log("Textfield name='#{name}' could not be set to '#{value}': '#{$!}'. #{desc} (#{__LINE__})")
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
# Set skip_value_check = true when string is altered by application and/or
|
1349
|
+
# this method will be followed by validate_text
|
1350
|
+
def set_textfield_by_id(browser, id, value, desc = '', skip_value_check = false)
|
1351
|
+
set_text_field(browser, :id, id, value, desc, skip_value_check)
|
1352
|
+
end
|
1353
|
+
|
1354
|
+
def set_textfield_by_title(browser, title, value, desc = '', skip_value_check = false)
|
1355
|
+
set_text_field(browser, :title, title, value, desc, skip_value_check)
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
def set_textfield_by_class(browser, strg, value, desc = '', skip_value_check = false)
|
1359
|
+
set_text_field(browser, :class, strg, value, desc, skip_value_check)
|
1360
|
+
end
|
1361
|
+
|
1362
|
+
def set_text_field_and_validate(browser, how, what, value, desc = '', valid_value = nil)
|
1363
|
+
#NOTE: use when value and valid_value differ as with dollar reformatting
|
1364
|
+
if set_text_field(browser, how, what, value, desc, true)
|
1365
|
+
expected = valid_value ? valid_value : value
|
1366
|
+
validate_textfield_value(browser, how, what, expected)
|
1367
|
+
end
|
1368
|
+
rescue
|
1369
|
+
failed_to_log("Unable to '#{msg}': '#{$!}'")
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
=begin rdoc
|
1373
|
+
category: Logon
|
1374
|
+
tags: logon, login, user, password, url
|
1375
|
+
TODO: Needs to be more flexible about finding login id and password textfields
|
1376
|
+
TODO: Parameterize url and remove references to environment
|
1377
|
+
=end
|
1378
|
+
def login(browser, user, password)
|
1379
|
+
myURL = @myAppEnv.url
|
1380
|
+
runenv = @myAppEnv.nodename
|
1381
|
+
message_tolog("URL: #{myURL}")
|
1382
|
+
message_tolog("Beginning login: User: #{user} Environment: #{runenv}")
|
1383
|
+
if validate(browser, @myName, __LINE__)
|
1384
|
+
browser.goto(myURL)
|
1385
|
+
if validate(browser, @myName)
|
1386
|
+
set_textfield_by_name(browser, 'loginId', user)
|
1387
|
+
set_textfield_by_name(browser, 'password', password)
|
1388
|
+
click_button_by_value(browser, 'Login')
|
1389
|
+
if validate(browser, @myName)
|
1390
|
+
passed_to_log("Login successful.")
|
1391
|
+
end
|
1392
|
+
else
|
1393
|
+
failed_to_log("Unable to login to application: '#{$!}'")
|
1394
|
+
# screen_capture( "#{@myRoot}/screens/#{myName}_#{@runid}_#{__LINE__.to_s}_#{Time.new.to_f.to_s}.jpg")
|
1395
|
+
end
|
1396
|
+
end
|
1397
|
+
rescue
|
1398
|
+
failed_to_log("Unable to login to application: '#{$!}'")
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
=begin rdoc
|
1402
|
+
category: Logon
|
1403
|
+
tags: logon, login, user, password, url, basic authorization
|
1404
|
+
=end
|
1405
|
+
def basic_auth(browser, user, pswd, url, bypass_validate = false)
|
1406
|
+
mark_testlevel("Basic Authorization Login", 0)
|
1407
|
+
|
1408
|
+
message_to_report ("Login: #{user}")
|
1409
|
+
message_to_report ("URL: #{url}")
|
1410
|
+
message_to_report ("Password: #{pswd}")
|
1411
|
+
|
1412
|
+
@login_title = "Connect to"
|
1413
|
+
|
1414
|
+
a = Thread.new {
|
1415
|
+
browser.goto(url)
|
1416
|
+
}
|
1417
|
+
|
1418
|
+
sleep_for(2)
|
1419
|
+
message_to_log("#{@login_title}...")
|
1420
|
+
|
1421
|
+
if (@ai.WinWait(@login_title, "", 90) > 0)
|
1422
|
+
win_title = @ai.WinGetTitle(@login_title)
|
1423
|
+
debug_to_log("Basic Auth Login window appeared: '#{win_title}'")
|
1424
|
+
@ai.WinActivate(@login_title)
|
1425
|
+
@ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", '!u')
|
1426
|
+
@ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", user, 1)
|
1427
|
+
@ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:3]", pswd.gsub(/!/, '{!}'), 1)
|
1428
|
+
@ai.ControlClick(@login_title, "", '[CLASS:Button; INSTANCE:1]')
|
1429
|
+
else
|
1430
|
+
debug_to_log("Basic Auth Login window did not appear.")
|
1431
|
+
end
|
1432
|
+
a.join
|
1433
|
+
|
1434
|
+
validate(browser, @myName) unless bypass_validate
|
1435
|
+
|
1436
|
+
message_to_report("URL: [#{browser.url}] User: [#{user}]")
|
1437
|
+
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
def logout(browser, where = @myName, lnbr = __LINE__)
|
1441
|
+
#TODO Firewatir 1.6.5 does not implement .exists for FireWatir::Firefox class
|
1442
|
+
debug_to_log("Logging out in #{where} at line #{lnbr}.", lnbr, true)
|
1443
|
+
debug_to_log("#{__method__}: browser: #{browser.inspect} (#{__LINE__})")
|
1444
|
+
|
1445
|
+
if ['FF', 'S'].include?(@browserAbbrev) || browser.exists?
|
1446
|
+
case @browserAbbrev
|
1447
|
+
when 'FF'
|
1448
|
+
if is_browser?(browser)
|
1449
|
+
url = browser.url
|
1450
|
+
title = browser.title
|
1451
|
+
debug_to_log("#{__method__}: Firefox browser url: [#{url}]")
|
1452
|
+
debug_to_log("#{__method__}: Firefox browser title: [#{title}]")
|
1453
|
+
debug_to_log("#{__method__}: Closing browser: #{where} (#{lnbr})")
|
1454
|
+
if url and url.length > 1
|
1455
|
+
browser.close
|
1456
|
+
else
|
1457
|
+
browser = FireWatir::Firefox.attach(:title, title)
|
1458
|
+
browser.close
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
end
|
1462
|
+
when 'IE'
|
1463
|
+
hwnd = browser.hwnd
|
1464
|
+
pid = Watir::IE::Process.process_id_from_hwnd(hwnd)
|
1465
|
+
debug_to_log("#{__method__}: Closing browser: hwnd #{hwnd} pid #{pid} #{where} (#{lnbr}) (#{__LINE__})")
|
1466
|
+
browser.close
|
1467
|
+
if browser.exists? and pid > 0 and pid < 538976288 # value of uninitialized memory location
|
1468
|
+
debug_to_log("Retry close browser: hwnd #{hwnd} pid #{pid} #{where} #{lnbr} (#{__LINE__})")
|
1469
|
+
browser.close
|
1470
|
+
end
|
1471
|
+
if browser.exists? and pid > 0 and pid < 538976288 # value of uninitialized memory location
|
1472
|
+
kill_browser(browser.hwnd, __LINE__, browser, true)
|
1473
|
+
end
|
1474
|
+
when 'S'
|
1475
|
+
if is_browser?(browser)
|
1476
|
+
url = browser.url
|
1477
|
+
title = browser.title
|
1478
|
+
debug_to_log("Safari browser url: [#{url}]")
|
1479
|
+
debug_to_log("Safari browser title: [#{title}]")
|
1480
|
+
debug_to_log("Closing browser: #{where} (#{lnbr})")
|
1481
|
+
close_modal_s # to close any leftover modal dialogs
|
1482
|
+
browser.close
|
1483
|
+
end
|
1484
|
+
when 'C'
|
1485
|
+
if is_browser?(browser)
|
1486
|
+
url = browser.url
|
1487
|
+
title = browser.title
|
1488
|
+
debug_to_log("Chrome browser url: [#{url}]")
|
1489
|
+
debug_to_log("Chrome browser title: [#{title}]")
|
1490
|
+
debug_to_log("Closing browser: #{where} (#{lnbr})")
|
1491
|
+
if url and url.length > 1
|
1492
|
+
browser.close
|
1493
|
+
#else
|
1494
|
+
#browser = FireWatir::Firefox.attach(:title, title)
|
1495
|
+
#browser.close
|
1496
|
+
end
|
1497
|
+
|
1498
|
+
end
|
1499
|
+
else
|
1500
|
+
raise "Unsupported browser: '#{@browserAbbrev}'"
|
1501
|
+
end
|
1502
|
+
end
|
1503
|
+
# rescue => e
|
1504
|
+
# if not e.is_a?(Vapir::WindowGoneException)
|
1505
|
+
# raise e
|
1506
|
+
# end
|
1507
|
+
end
|
1508
|
+
|
1509
|
+
#close popup in new window
|
1510
|
+
def close_new_window_popup(popup)
|
1511
|
+
if is_browser?(popup)
|
1512
|
+
url = popup.url
|
1513
|
+
debug_to_log("Closing popup '#{url}' ")
|
1514
|
+
popup.close
|
1515
|
+
|
1516
|
+
end
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
def close_panel_by_text(browser, panel, strg = 'Close')
|
1520
|
+
if validate(browser, @myName, __LINE__)
|
1521
|
+
if @browserAbbrev == 'IE'
|
1522
|
+
panel.link(:text, strg).click!
|
1523
|
+
elsif $USE_FIREWATIR
|
1524
|
+
begin
|
1525
|
+
panel.link(:text, strg).click
|
1526
|
+
rescue => e
|
1527
|
+
if not rescue_me(e, __method__, "link(:text,'#{strg}').click", "#{panel.class}")
|
1528
|
+
raise e
|
1529
|
+
end
|
1530
|
+
end
|
1531
|
+
else
|
1532
|
+
panel.link(:text, strg).click(:wait => false)
|
1533
|
+
end
|
1534
|
+
sleep_for(1)
|
1535
|
+
if validate(browser, @myName, __LINE__)
|
1536
|
+
passed_to_log("Panel '#{strg}' (by :text) closed.")
|
1537
|
+
true
|
1538
|
+
end
|
1539
|
+
else
|
1540
|
+
failed_to_log("Panel '#{strg}' (by :text) still open.")
|
1541
|
+
end
|
1542
|
+
rescue
|
1543
|
+
failed_to_log("Click on '#{strg}'(by :text) failed: '#{$!}' (#{__LINE__})")
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
# def close_modal_ie(title="", button="OK", text='', side = 'primary', wait = WAIT)
|
1547
|
+
def close_popup(title, button = "OK", text = '', side = 'primary', wait = WAIT, desc = '', quiet = false)
|
1548
|
+
#TODO needs simplifying and debug code cleaned up
|
1549
|
+
title = translate_popup_title(title)
|
1550
|
+
msg = "'#{title}'"
|
1551
|
+
msg << " with text '#{text}'" if text.length > 0
|
1552
|
+
msg << " (#{desc})" if desc.length > 0
|
1553
|
+
@ai.Opt("WinSearchChildren", 1) # Match any substring in the title
|
1554
|
+
if @ai.WinWait(title, text, wait) > 0
|
1555
|
+
myHandle = @ai.WinGetHandle(title, text)
|
1556
|
+
full_text = @ai.WinGetText(title)
|
1557
|
+
#debug_to_report("Found popup handle:'#{myHandle}', title:'#{title}', text:'#{full_text}'")
|
1558
|
+
if myHandle.length > 0
|
1559
|
+
debug_to_log("hwnd: #{myHandle.inspect}")
|
1560
|
+
passed_to_log("#{msg} appeared.") unless quiet
|
1561
|
+
sleep_for(0.5)
|
1562
|
+
@ai.WinActivate(title, text)
|
1563
|
+
if @ai.WinActive(title, text) # > 0 #Hack to prevent fail when windows session locked
|
1564
|
+
debug_to_log("#{msg} activated.")
|
1565
|
+
if @ai.ControlFocus(title, text, button) # > 0
|
1566
|
+
controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
|
1567
|
+
if not controlHandle
|
1568
|
+
button = "&#{button}"
|
1569
|
+
controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
|
1570
|
+
end
|
1571
|
+
debug_to_log("Handle for button '#{button}': [#{controlHandle}]")
|
1572
|
+
debug_to_log("#{msg} focus gained.")
|
1573
|
+
# sleep_for(2)
|
1574
|
+
if @ai.ControlClick(title, text, button, side) # > 0
|
1575
|
+
# if @ai.ControlClick(title, text, "[Handle:#{controlHandle}]", side) > 0
|
1576
|
+
# debug_to_log("#{msg} #{side} click on 'Handle:#{controlHandle}'." )
|
1577
|
+
debug_to_log("#{msg} #{side} click on '#{button}' successful.")
|
1578
|
+
sleep_for(1)
|
1579
|
+
if @ai.WinExists(title, text) > 0
|
1580
|
+
debug_to_log("#{msg} close popup failed on click '#{button}'. Trying WinClose. (#{__LINE__})")
|
1581
|
+
@ai.WinClose(title, text)
|
1582
|
+
if @ai.WinExists(title, text) > 0
|
1583
|
+
debug_to_log("#{msg} close popup failed with WinClose('#{title}','#{text}'). (#{__LINE__})")
|
1584
|
+
@ai.WinKill(title, text)
|
1585
|
+
if @ai.WinExists(title, text) > 0
|
1586
|
+
debug_to_log("#{msg} close popup failed with WinKill('#{title}','#{text}'). (#{__LINE__})")
|
1587
|
+
else
|
1588
|
+
debug_to_log("#{msg} closed successfully with WinKill('#{title}','#{text}').")
|
1589
|
+
end
|
1590
|
+
else
|
1591
|
+
debug_to_log("#{msg} closed successfully with WinClose('#{title}','#{text}').")
|
1592
|
+
end
|
1593
|
+
else
|
1594
|
+
passed_to_log("#{msg} closed successfully.") unless quiet
|
1595
|
+
end
|
1596
|
+
else
|
1597
|
+
failed_to_log("#{msg} #{side} click on '#{button}' failed. (#{__LINE__})")
|
1598
|
+
end
|
1599
|
+
else
|
1600
|
+
failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
|
1601
|
+
end
|
1602
|
+
else
|
1603
|
+
failed_to_log("#{msg} Unable to activate (#{__LINE__})")
|
1604
|
+
end
|
1605
|
+
else
|
1606
|
+
failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
|
1607
|
+
end
|
1608
|
+
else
|
1609
|
+
failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
|
1610
|
+
end
|
1611
|
+
rescue
|
1612
|
+
failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
|
1613
|
+
end
|
1614
|
+
|
1615
|
+
alias close_popup_validate_text close_popup
|
1616
|
+
|
1617
|
+
def close_popup_by_text(popup, strg = 'Close', desc = '')
|
1618
|
+
count = 0
|
1619
|
+
url = popup.url
|
1620
|
+
if validate(popup, @myName, __LINE__)
|
1621
|
+
count = string_count_in_string(popup.text, strg)
|
1622
|
+
if count > 0
|
1623
|
+
# @waiter.wait_until( browser.link(:text, strg).exists? ) if @waiter
|
1624
|
+
begin
|
1625
|
+
popup.link(:text, strg).click
|
1626
|
+
rescue => e
|
1627
|
+
if not rescue_me(e, __method__, "link(:text,'#{strg}')", "#{popup.class}")
|
1628
|
+
raise e
|
1629
|
+
end
|
1630
|
+
end
|
1631
|
+
passed_to_log("Popup #{url} closed by clicking link with text '#{strg}'. #{desc}")
|
1632
|
+
true
|
1633
|
+
else
|
1634
|
+
failed_to_log("Link :text=>'#{strg}' for popup #{url} not found. #{desc}")
|
1635
|
+
end
|
1636
|
+
end
|
1637
|
+
rescue
|
1638
|
+
failed_to_log("Close popup #{url} with click link :text+>'#{strg}' failed: '#{$!}' (#{__LINE__})")
|
1639
|
+
debug_to_log("#{strg} appears #{count} times in popup.text.")
|
1640
|
+
raise
|
1641
|
+
end
|
1642
|
+
|
1643
|
+
# #close a modal dialog
|
1644
|
+
def close_modal(browser, title="", button="OK", text='', side = 'primary', wait = WAIT)
|
1645
|
+
case @targetBrowser.abbrev
|
1646
|
+
when 'IE'
|
1647
|
+
close_modal_ie(browser, title, button, text, side, wait)
|
1648
|
+
when 'FF'
|
1649
|
+
close_modal_ff(browser, title, button, text, side)
|
1650
|
+
when 'S'
|
1651
|
+
close_modal_s
|
1652
|
+
when 'C', 'GC'
|
1653
|
+
close_modal_c(browser, title)
|
1654
|
+
end
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
# TODO: Logging
|
1658
|
+
def close_modal_c(browser, title)
|
1659
|
+
browser.window(:url, title).close
|
1660
|
+
end
|
1661
|
+
|
1662
|
+
# TODO: Logging
|
1663
|
+
def close_modal_s
|
1664
|
+
# simply closes the frontmost Safari dialog
|
1665
|
+
Appscript.app("Safari").activate; Appscript.app("System Events").processes["Safari"].key_code(52)
|
1666
|
+
end
|
1667
|
+
|
1668
|
+
def close_modal_ie(browser, title="", button="OK", text='', side = 'primary', wait = WAIT, desc = '', quiet = false)
|
1669
|
+
#TODO needs simplifying, incorporating text verification, and debug code cleaned up
|
1670
|
+
title = translate_popup_title(title)
|
1671
|
+
msg = "Modal window (popup) '#{title}'"
|
1672
|
+
if @ai.WinWait(title, text, wait)
|
1673
|
+
myHandle = @ai.WinGetHandle(title, text)
|
1674
|
+
if myHandle.length > 0
|
1675
|
+
debug_to_log("hwnd: #{myHandle.inspect}")
|
1676
|
+
passed_to_log("#{msg} appeared.") unless quiet
|
1677
|
+
window_handle = "[HANDLE:#{myHandle}]"
|
1678
|
+
sleep_for(0.5)
|
1679
|
+
@ai.WinActivate(window_handle)
|
1680
|
+
if @ai.WinActive(window_handle)
|
1681
|
+
debug_to_log("#{msg} activated.")
|
1682
|
+
controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
|
1683
|
+
if not controlHandle.length > 0
|
1684
|
+
button = "&#{button}"
|
1685
|
+
controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
|
1686
|
+
end
|
1687
|
+
debug_to_log("Handle for button '#{button}': [#{controlHandle}]")
|
1688
|
+
debug_to_log("#{msg} focus gained.")
|
1689
|
+
if @ai.ControlClick(title, '', "[CLASS:Button; TEXT:#{button}]")
|
1690
|
+
passed_to_log("#{msg} #{side} click on '[CLASS:Button; TEXT:#{button}]' successful.")
|
1691
|
+
sleep_for(0.5)
|
1692
|
+
if @ai.WinExists(window_handle)
|
1693
|
+
debug_to_log("#{msg} close popup failed on click '#{button}'. Trying WinClose. (#{__LINE__})")
|
1694
|
+
@ai.WinClose(title, text)
|
1695
|
+
if @ai.WinExists(window_handle)
|
1696
|
+
debug_to_log("#{msg} close popup failed with WinClose(#{window_handle}). (#{__LINE__})")
|
1697
|
+
@ai.WinKill(window_handle)
|
1698
|
+
if @ai.WinExists(window_handle)
|
1699
|
+
debug_to_log("#{msg} close popup failed with WinKill(#{window_handle}). (#{__LINE__})")
|
1700
|
+
else
|
1701
|
+
debug_to_log("#{msg} closed successfully with WinKill(#{window_handle}).")
|
1702
|
+
end
|
1703
|
+
else
|
1704
|
+
debug_to_log("#{msg} closed successfully with WinClose(#{window_handle}).")
|
1705
|
+
end
|
1706
|
+
else
|
1707
|
+
passed_to_log("#{msg} closed successfully.")
|
1708
|
+
end
|
1709
|
+
else
|
1710
|
+
failed_to_log("#{msg} #{side} click on '[CLASS:Button; TEXT:#{button}]' failed. (#{window_handle}) (#{__LINE__})")
|
1711
|
+
end
|
1712
|
+
else
|
1713
|
+
failed_to_log("#{msg} Unable to activate (#{window_handle}) (#{__LINE__})")
|
1714
|
+
end
|
1715
|
+
else
|
1716
|
+
failed_to_log("#{msg} did not appear after #{wait} seconds. (#{window_handle}) (#{__LINE__})")
|
1717
|
+
end
|
1718
|
+
else
|
1719
|
+
failed_to_log("#{msg} did not appear after #{wait} seconds.(#{window_handle}) (#{__LINE__})")
|
1720
|
+
end
|
1721
|
+
rescue
|
1722
|
+
failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
|
1723
|
+
end
|
1724
|
+
|
1725
|
+
# private :close_modal_ie
|
1726
|
+
|
1727
|
+
def close_modal_ff(browser, title="", button=nil, text="", side='')
|
1728
|
+
title = translate_popup_title(title)
|
1729
|
+
msg = "Modal dialog (popup): title=#{title} button='#{button}' text='#{text}' side='#{side}':"
|
1730
|
+
modal = browser.modal_dialog(:timeout => WAIT)
|
1731
|
+
if modal.exists?
|
1732
|
+
modal_text = modal.text
|
1733
|
+
if text.length > 0
|
1734
|
+
if modal_text =~ /#{text}/
|
1735
|
+
passed_to_log("#{msg} appeared with match on '#{text}'.")
|
1736
|
+
else
|
1737
|
+
failed_to_log("#{msg} appeared but did not match '#{text}' ('#{modal_text}).")
|
1738
|
+
end
|
1739
|
+
else
|
1740
|
+
passed_to_log("#{msg} appeared.")
|
1741
|
+
end
|
1742
|
+
if button
|
1743
|
+
modal.click_button(button)
|
1744
|
+
else
|
1745
|
+
modal.close
|
1746
|
+
end
|
1747
|
+
if modal.exists?
|
1748
|
+
failed_to_log("#{msg} close failed. (#{__LINE__})")
|
1749
|
+
else
|
1750
|
+
passed_to_log("#{msg} closed successfully.")
|
1751
|
+
end
|
1752
|
+
else
|
1753
|
+
failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
|
1754
|
+
end
|
1755
|
+
rescue
|
1756
|
+
failed_to_log("#{msg} Unable to validate modal popup: '#{$!}'. (#{__LINE__})")
|
1757
|
+
end
|
1758
|
+
|
1759
|
+
def handle_popup(title, text = '', button= 'OK', side = 'primary', wait = WAIT, desc = '')
|
1760
|
+
title = translate_popup_title(title)
|
1761
|
+
msg = "'#{title}'"
|
1762
|
+
if text.length > 0
|
1763
|
+
msg << " with text '#{text}'"
|
1764
|
+
end
|
1765
|
+
@ai.Opt("WinSearchChildren", 1) # match title from start, forcing default
|
1766
|
+
|
1767
|
+
if button and button.length > 0
|
1768
|
+
if button =~ /ok|yes/i
|
1769
|
+
id = '1'
|
1770
|
+
else
|
1771
|
+
id = '2'
|
1772
|
+
end
|
1773
|
+
else
|
1774
|
+
id = ''
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
if @ai.WinWait(title, '', wait) > 0
|
1778
|
+
myHandle = @ai.WinGetHandle(title, '')
|
1779
|
+
window_handle = "[HANDLE:#{myHandle}]"
|
1780
|
+
full_text = @ai.WinGetText(window_handle)
|
1781
|
+
debug_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text:'#{full_text}'")
|
1782
|
+
|
1783
|
+
controlHandle = @ai.ControlGetHandle(window_handle, '', "[CLASS:Button; TEXT:#{button}]")
|
1784
|
+
if not controlHandle
|
1785
|
+
# button = "&#{button}"
|
1786
|
+
controlHandle = @ai.ControlGetHandle(window_handle, '', "[CLASS:Button; TEXT:&#{button}]")
|
1787
|
+
end
|
1788
|
+
|
1789
|
+
if text.length > 0
|
1790
|
+
if full_text =~ /#{text}/
|
1791
|
+
passed_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text includes '#{text}'. #{desc}")
|
1792
|
+
else
|
1793
|
+
failed_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text does not include '#{text}'. Closing it. #{desc}")
|
1794
|
+
end
|
1795
|
+
end
|
1796
|
+
|
1797
|
+
@ai.WinActivate(window_handle, '')
|
1798
|
+
@ai.ControlClick(window_handle, '', id, side)
|
1799
|
+
if @ai.WinExists(title, '') > 0
|
1800
|
+
debug_to_log("#{msg} @ai.ControlClick on '#{button}' (ID:#{id}) with handle '#{window_handle}' failed to close window. Trying title.")
|
1801
|
+
@ai.ControlClick(title, '', id, side)
|
1802
|
+
if @ai.WinExists(title, '') > 0
|
1803
|
+
debug_to_report("#{msg} @ai.ControlClick on '#{button}' (ID:#{id}) with title '#{title}' failed to close window. Forcing closed.")
|
1804
|
+
@ai.WinClose(title, '')
|
1805
|
+
if @ai.WinExists(title, '') > 0
|
1806
|
+
debug_to_report("#{msg} @ai.WinClose on title '#{title}' failed to close window. Killing window.")
|
1807
|
+
@ai.WinKill(title, '')
|
1808
|
+
if @ai.WinExists(title, '') > 0
|
1809
|
+
failed_to_log("#{msg} @ai.WinKill on title '#{title}' failed to close window")
|
1810
|
+
else
|
1811
|
+
passed_to_log("Killed: popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
|
1812
|
+
true
|
1813
|
+
end
|
1814
|
+
else
|
1815
|
+
passed_to_log("Forced closed: popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
|
1816
|
+
true
|
1817
|
+
end
|
1818
|
+
else
|
1819
|
+
passed_to_log("Closed on '#{button}': popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
|
1820
|
+
true
|
1821
|
+
end
|
1822
|
+
else
|
1823
|
+
passed_to_log("Closed on '#{button}': popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
|
1824
|
+
true
|
1825
|
+
end
|
1826
|
+
|
1827
|
+
else
|
1828
|
+
failed_to_log("#{msg} did not appear after #{wait} seconds. #{desc} (#{__LINE__})")
|
1829
|
+
end
|
1830
|
+
rescue
|
1831
|
+
failed_to_log("Unable to handle popup #{msg}: '#{$!}' #{desc} (#{__LINE__})")
|
1832
|
+
|
1833
|
+
end
|
1834
|
+
|
1835
|
+
# howLong is integer, whatFor is a browser object
|
1836
|
+
=begin rdoc
|
1837
|
+
tags: wait
|
1838
|
+
howLong is the number of seconds, text is a string to be found, threshold is the number of seconds
|
1839
|
+
after which a fail message is generated even though the text was detected within the howLong limit.
|
1840
|
+
Use this in place of wait_until_by_text when the wait time needs to be longer than the test automation default.
|
1841
|
+
=end
|
1842
|
+
def hold_for_text(browser, howLong, text, desc = '', threshold = 20, interval = 0.25)
|
1843
|
+
countdown = howLong
|
1844
|
+
while ((not browser.contains_text(text)) and countdown > 0)
|
1845
|
+
sleep(interval)
|
1846
|
+
countdown = countdown - interval
|
1847
|
+
end
|
1848
|
+
if countdown < howLong
|
1849
|
+
waittime = howLong - countdown
|
1850
|
+
passed_tolog("#{__method__} '#{text}' found after #{waittime} second(s) #{desc}")
|
1851
|
+
if waittime > threshold
|
1852
|
+
failed_tolog("#{__method__} '#{text}' took #{waittime} second(s). (threshold: #{threshold} seconds) #{desc}")
|
1853
|
+
end
|
1854
|
+
true
|
1855
|
+
else
|
1856
|
+
failed_tolog("#{__method__} '#{text}' not found after #{howLong} second(s) #{desc}")
|
1857
|
+
false
|
1858
|
+
end
|
1859
|
+
rescue
|
1860
|
+
failed_tolog("Unable to #{__method__} '#{text}'. '#{$!}' #{desc}")
|
1861
|
+
end
|
1862
|
+
|
1863
|
+
alias wait_for_text hold_for_text
|
1864
|
+
|
1865
|
+
def hover(browser, element, wait = 2)
|
1866
|
+
w1, h1, x1, y1, xc1, yc1, xlr1, ylr1 = get_element_coordinates(browser, element, true)
|
1867
|
+
@ai.MoveMouse(xc1, yc1)
|
1868
|
+
sleep_for(1)
|
1869
|
+
end
|
1870
|
+
|
1871
|
+
def get_save_file_path(root, filename)
|
1872
|
+
filespec = "#{root}/file/#{filename}"
|
1873
|
+
filespec.gsub!('/', '\\')
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
def save_file_orig(filepath, desc = '', wait = WAIT)
|
1877
|
+
# title = translate_popup_title(title)
|
1878
|
+
@ai.WinWait("File Download", "", wait)
|
1879
|
+
@ai.ControlFocus("File Download", "", "&Save")
|
1880
|
+
sleep 1
|
1881
|
+
@ai.ControlClick("File Download", "", "&Save", "left")
|
1882
|
+
@ai.WinWait("Save As", "", wait)
|
1883
|
+
sleep 1
|
1884
|
+
@ai.ControlSend("Save As", "", "Edit1", filepath)
|
1885
|
+
@ai.ControlClick("Save As", "", "&Save", "left")
|
1886
|
+
sleep 1
|
1887
|
+
@ai.WinWait("Download complete", "", wait)
|
1888
|
+
@ai.ControlClick("Download complete", "", "Close")
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
#TODO This and save_file2 have to be combined somehow.
|
1892
|
+
def save_file1(filepath, title = "File Download", desc = '', wait = WAIT)
|
1893
|
+
title = translate_popup_title(title)
|
1894
|
+
@ai.WinWait(title, '', wait)
|
1895
|
+
@ai.WinActivate(title, '')
|
1896
|
+
sleep 1
|
1897
|
+
@ai.ControlFocus(title, "", "&Save")
|
1898
|
+
sleep 3
|
1899
|
+
@ai.ControlClick(title, "", "&Save", "primary")
|
1900
|
+
sleep 2
|
1901
|
+
@ai.ControlClick(title, "", "Save", "primary")
|
1902
|
+
|
1903
|
+
@ai.WinWait("Save As", "", wait)
|
1904
|
+
sleep 1
|
1905
|
+
@ai.ControlSend("Save As", "", "Edit1", filepath)
|
1906
|
+
@ai.ControlFocus("Save As", "", "&Save")
|
1907
|
+
@ai.ControlClick("Save As", "", "&Save", "primary")
|
1908
|
+
@ai.ControlClick("Save As", "", "Save", "primary")
|
1909
|
+
|
1910
|
+
@ai.WinWait("Download complete", "", wait)
|
1911
|
+
passed_to_log("Save file '#{filepath}' succeeded. #{desc}")
|
1912
|
+
@ai.ControlClick("Download complete", "", "Close")
|
1913
|
+
rescue
|
1914
|
+
failed_to_log("Save file failed: #{desc} '#{$!}'. (#{__LINE__})")
|
1915
|
+
end
|
1916
|
+
|
1917
|
+
def save_file2(filepath, title = "File Download - Security Warning", desc = '', wait = WAIT)
|
1918
|
+
title = translate_popup_title(title)
|
1919
|
+
sleep(1)
|
1920
|
+
@ai.WinWait(title, '', wait)
|
1921
|
+
dl_hndl = @ai.WinGetHandle(title, '')
|
1922
|
+
dl_sv_hndl = @ai.ControlGetHandle(title, '', "&Save")
|
1923
|
+
@ai.WinActivate(title, '')
|
1924
|
+
sleep 1
|
1925
|
+
@ai.ControlFocus(title, "", "&Save")
|
1926
|
+
sleep 1
|
1927
|
+
@ai.ControlFocus(title, "", "Save")
|
1928
|
+
sleep 1
|
1929
|
+
@ai.ControlClick(title, "", "&Save", "primary")
|
1930
|
+
sleep 1
|
1931
|
+
@ai.ControlClick(title, "", "Save", "primary")
|
1932
|
+
sleep 1
|
1933
|
+
w = WinClicker.new
|
1934
|
+
w.clickButtonWithHandle(dl_sv_hndl)
|
1935
|
+
sleep 1
|
1936
|
+
w.clickWindowsButton_hwnd(dl_hndl, "Save")
|
1937
|
+
sleep 1
|
1938
|
+
w.clickWindowsButton_hwnd(dl_hndl, "&Save")
|
1939
|
+
|
1940
|
+
@ai.WinWait("Save As", "", wait)
|
1941
|
+
sleep 1
|
1942
|
+
@ai.ControlSend("Save As", "", "Edit1", filepath)
|
1943
|
+
@ai.ControlFocus("Save As", "", "&Save")
|
1944
|
+
@ai.ControlClick("Save As", "", "&Save", "primary")
|
1945
|
+
|
1946
|
+
@ai.WinWait("Download complete", "", wait)
|
1947
|
+
passed_to_log("Save file '#{filepath}' succeeded. #{desc}")
|
1948
|
+
@ai.ControlClick("Download complete", "", "Close")
|
1949
|
+
rescue
|
1950
|
+
failed_to_log("Save file failed: #{desc} '#{$!}'. (#{__LINE__})")
|
1951
|
+
end
|
1952
|
+
|
1953
|
+
#method for handling save dialog
|
1954
|
+
#use click_no_wait on the action that triggers the save dialog
|
1955
|
+
# TODO need version for Firefox
|
1956
|
+
# TODO need to handle first character underline, e.g. 'Cancel' and '&Cancel'
|
1957
|
+
def save_file(filepath, download_title = "File Download - Security Warning")
|
1958
|
+
download_title = translate_popup_title(download_title)
|
1959
|
+
download_text = ''
|
1960
|
+
download_control = "&Save"
|
1961
|
+
saveas_title = 'Save As'
|
1962
|
+
saveas_text = ''
|
1963
|
+
saveas_control = "Edit1"
|
1964
|
+
dnld_cmplt_title = "Download Complete"
|
1965
|
+
dnld_cmplt_title = translate_popup_title(dnld_cmplt_title)
|
1966
|
+
dnld_cmplt_text = ""
|
1967
|
+
# save_title = ""
|
1968
|
+
side = 'primary'
|
1969
|
+
msgdl = "Window '#{download_title}':"
|
1970
|
+
msgsa = "Window '#{saveas_title}':"
|
1971
|
+
msgdc = "Window '#{dnld_cmplt_title}':"
|
1972
|
+
begin
|
1973
|
+
if @ai.WinWait(download_title, download_text, WAIT)
|
1974
|
+
@ai.WinActivate(download_title, download_text)
|
1975
|
+
if @ai.WinActive(download_title, download_text)
|
1976
|
+
dl_title = @ai.WinGetTitle(download_title, download_text)
|
1977
|
+
# dl_hndl = @ai.WinGetHandle(download_title, download_text)
|
1978
|
+
# dl_text = @ai.WinGetText(download_title, download_text)
|
1979
|
+
# dl_sv_hndl = @ai.ControlGetHandle(dl_title, '', download_control)
|
1980
|
+
# dl_op_hndl = @ai.ControlGetHandle(dl_title, '', '&Open')
|
1981
|
+
# dl_cn_hndl = @ai.ControlGetHandle(dl_title, '', 'Cancel')
|
1982
|
+
debug_to_log("#{msgdl} activated. (#{__LINE__})")
|
1983
|
+
|
1984
|
+
if @ai.ControlFocus(dl_title, download_text, download_control)
|
1985
|
+
debug_to_log("#{msgdl} focus gained. (#{__LINE__})")
|
1986
|
+
|
1987
|
+
@ai.Send("S")
|
1988
|
+
# @ai.ControlSend(dl_Stitle, download_text, download_control, "{ENTER}")
|
1989
|
+
sleep_for 1
|
1990
|
+
|
1991
|
+
if @ai.ControlClick(dl_title, download_text, download_control, side)
|
1992
|
+
debug_to_log("#{msgdl} click succeeded on '#{download_control}'. (#{__LINE__})")
|
1993
|
+
|
1994
|
+
if @ai.WinWait(saveas_title, saveas_text, WAIT)
|
1995
|
+
debug_to_log("#{msgsa} appeared. (#{__LINE__})")
|
1996
|
+
sleep_for 1
|
1997
|
+
if @ai.ControlSend(saveas_title, saveas_text, saveas_control, filepath)
|
1998
|
+
debug_to_log("#{msgsa} controlsend of '#{saveas_control}' succeeded. (#{__LINE__})")
|
1999
|
+
|
2000
|
+
@ai.Send("S")
|
2001
|
+
@ai.ControlSend(saveas_title, saveas_text, saveas_control, "{ENTER}")
|
2002
|
+
sleep_for 1
|
2003
|
+
|
2004
|
+
if @ai.ControlClick(saveas_title, saveas_text, saveas_control, side)
|
2005
|
+
passed_to_log("#{msgsa} click succeeded on '#{saveas_control}'. (#{__LINE__})")
|
2006
|
+
if @ai.WinWait(dnld_cmplt_title, dnld_cmplt_text, WAIT)
|
2007
|
+
debug_to_log("#{msgdc} appeared. (#{__LINE__})")
|
2008
|
+
sleep_for 1
|
2009
|
+
if @ai.ControlClick(dnld_cmplt_title, dnld_cmplt_text, "Close", side)
|
2010
|
+
passed_to_log("Save file for #{filepath} succeeded.")
|
2011
|
+
else
|
2012
|
+
failed_to_log("#{msgdc} click failed on 'Close'. (#{__LINE__})")
|
2013
|
+
end
|
2014
|
+
else
|
2015
|
+
failed_to_log("#{msgdc} did not appear after #{WAIT} seconds. (#{__LINE__})")
|
2016
|
+
end
|
2017
|
+
else
|
2018
|
+
failed_to_log("#{msgsa} click failed on '#{saveas_control}'. (#{__LINE__})")
|
2019
|
+
end
|
2020
|
+
else
|
2021
|
+
failed_to_log("#{msgsa} controlsend of '#{saveas_control}' failed. (#{__LINE__})")
|
2022
|
+
end
|
2023
|
+
else
|
2024
|
+
failed_to_log("#{msgsa} did not appear after #{WAIT} seconds. (#{__LINE__})")
|
2025
|
+
end
|
2026
|
+
else
|
2027
|
+
failed_to_log("#{msgdl} click failed on '#{download_control}'. (#{__LINE__})")
|
2028
|
+
end
|
2029
|
+
else
|
2030
|
+
failed_to_log("#{msgdl} Unable to gain focus on control '#{dl_title}'. (#{__LINE__})")
|
2031
|
+
end
|
2032
|
+
else
|
2033
|
+
failed_to_log("#{msgdl} Unable to activate. (#{__LINE__})")
|
2034
|
+
end
|
2035
|
+
else
|
2036
|
+
failed_to_log("#{msgdl} did not appear after #{WAIT} seconds. (#{__LINE__})")
|
2037
|
+
end
|
2038
|
+
rescue
|
2039
|
+
failed_to_log("Save file failed: '#{$!}'. (#{__LINE__})")
|
2040
|
+
end
|
2041
|
+
end
|
2042
|
+
|
2043
|
+
def close_log(scriptName, lnbr = '')
|
2044
|
+
cmplTS = Time.now.to_f.to_s
|
2045
|
+
puts ("#{scriptName} finished. Closing log. #{lnbr.to_s}")
|
2046
|
+
passed_to_log("#{scriptName} run complete [#{cmplTS}]")
|
2047
|
+
@myLog.close()
|
2048
|
+
sleep(2)
|
2049
|
+
end
|
2050
|
+
|
2051
|
+
protected :close_log
|
2052
|
+
|
2053
|
+
#method for cancelling Print window
|
2054
|
+
# TODO need to handle 'Cancel' and '&Cancel' (first character underlined)
|
2055
|
+
def close_print(title = 'Print', text = '', button = '&Cancel', side = 'left')
|
2056
|
+
msg = "Popup: title=#{title} button='#{button}' text='#{text}' side='#{side}':"
|
2057
|
+
if @ai.WinWait(title, text, WAIT)
|
2058
|
+
passed_to_log("#{msg} found.")
|
2059
|
+
@ai.WinActivate(title)
|
2060
|
+
if @ai.WinActive(title, text)
|
2061
|
+
passed_to_log("#{msg} activated.")
|
2062
|
+
if @ai.ControlFocus(title, text, button)
|
2063
|
+
passed_to_log("#{msg} focus attained.")
|
2064
|
+
if @ai.ControlClick(title, text, button, side)
|
2065
|
+
passed_to_log("#{msg} closed successfully.")
|
2066
|
+
else
|
2067
|
+
failed_to_log("#{msg} click failed on button (#{__LINE__})")
|
2068
|
+
end
|
2069
|
+
else
|
2070
|
+
failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
|
2071
|
+
end
|
2072
|
+
else
|
2073
|
+
failed_to_log("#{msg} Unable to activate (#{__LINE__})")
|
2074
|
+
end
|
2075
|
+
else
|
2076
|
+
failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
|
2077
|
+
end
|
2078
|
+
rescue
|
2079
|
+
failed_to_log("Close #{msg}: '#{$!}'. (#{__LINE__})")
|
2080
|
+
end
|
2081
|
+
|
2082
|
+
#method for handling file download dialog
|
2083
|
+
#use click_no_wait on the action that triggers the save dialog
|
2084
|
+
# TODO need version for Firefox
|
2085
|
+
# TODO need to handle 'Cancel' and '&Cancel' (first character underlined)
|
2086
|
+
# TODO replace call to close_modal_ie with actual file download
|
2087
|
+
def file_download(browser = nil)
|
2088
|
+
title = 'File Download'
|
2089
|
+
title = translate_popup_title(title)
|
2090
|
+
text = ''
|
2091
|
+
button = 'Cancel'
|
2092
|
+
if @browserAbbrev == 'IE'
|
2093
|
+
close_popup(title, button, text)
|
2094
|
+
else
|
2095
|
+
|
2096
|
+
end
|
2097
|
+
end
|
2098
|
+
|
2099
|
+
#method for handling file upload dialog
|
2100
|
+
#use click_no_wait on the action that triggers the save dialog
|
2101
|
+
# TODO need version for Firefox
|
2102
|
+
def file_upload(filepath)
|
2103
|
+
title = 'Choose File'
|
2104
|
+
title = translate_popup_title(title)
|
2105
|
+
text = ''
|
2106
|
+
button = "&Open"
|
2107
|
+
control = "Edit1"
|
2108
|
+
side = 'primary'
|
2109
|
+
msg = "Window title=#{title} button='#{button}' text='#{text}' side='#{side}':"
|
2110
|
+
begin
|
2111
|
+
if @ai.WinWait(title, text, WAIT)
|
2112
|
+
passed_to_log("#{msg} found.")
|
2113
|
+
@ai.WinActivate(title, text)
|
2114
|
+
if @ai.WinActive(title, text)
|
2115
|
+
passed_to_log("#{msg} activated.")
|
2116
|
+
if @ai.ControlSend(title, text, control, filepath)
|
2117
|
+
passed_to_log("#{msg} #{control} command sent.")
|
2118
|
+
sleep_for 1
|
2119
|
+
if @ai.ControlClick(title, text, button, "primary")
|
2120
|
+
passed_to_log("#{msg} Upload of #{filepath} succeeded.")
|
2121
|
+
else
|
2122
|
+
failed_to_log("#{msg} Upload of #{filepath} failed. (#{__LINE__})")
|
2123
|
+
end
|
2124
|
+
else
|
2125
|
+
failed_to_log("#{msg} Unable to select #{filepath}. (#{__LINE__})")
|
2126
|
+
end
|
2127
|
+
else
|
2128
|
+
failed_to_log("#{msg} Unable to activate. (#{__LINE__})")
|
2129
|
+
end
|
2130
|
+
else
|
2131
|
+
failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
|
2132
|
+
end
|
2133
|
+
rescue
|
2134
|
+
failed_to_log("#{msg} Unable to upload: '#{$!}'. (#{__LINE__})")
|
2135
|
+
end
|
2136
|
+
|
2137
|
+
end
|
2138
|
+
|
2139
|
+
def find_popup(browser, how, what, desc = '')
|
2140
|
+
msg = "Find popup :#{how}=>'#{what}'. #{desc}"
|
2141
|
+
popup = Watir::IE.find(how, what) # TODO: too browser specific
|
2142
|
+
sleep_for(1)
|
2143
|
+
debug_to_log("#{popup.inspect}")
|
2144
|
+
if is_browser?(popup)
|
2145
|
+
# title = popup.title
|
2146
|
+
passed_to_log(msg)
|
2147
|
+
return popup
|
2148
|
+
else
|
2149
|
+
failed_to_log(msg)
|
2150
|
+
end
|
2151
|
+
rescue
|
2152
|
+
failed_to_log("Unable to find popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
|
2153
|
+
end
|
2154
|
+
|
2155
|
+
def find_sheet_with_name(workbook, sheet_name)
|
2156
|
+
sheets = workbook.sheets
|
2157
|
+
idx = 0
|
2158
|
+
found = false
|
2159
|
+
sheets.each do |s|
|
2160
|
+
if s == sheet_name
|
2161
|
+
found = true
|
2162
|
+
break
|
2163
|
+
end
|
2164
|
+
idx += 1
|
2165
|
+
end
|
2166
|
+
if found
|
2167
|
+
idx
|
2168
|
+
else
|
2169
|
+
-1
|
2170
|
+
end
|
2171
|
+
end
|
2172
|
+
|
2173
|
+
# howLong is integer, whatFor is a browser object
|
2174
|
+
def wait_for_text(browser, howLong, text)
|
2175
|
+
countdown = howLong
|
2176
|
+
while ((not browser.contains_text(text)) and countdown > 0)
|
2177
|
+
sleep(1)
|
2178
|
+
countdown = countdown - 1
|
2179
|
+
end
|
2180
|
+
if countdown
|
2181
|
+
passed_tolog("wait_for_text '#{text}' found after #{howLong} second(s)")
|
2182
|
+
else
|
2183
|
+
failed_tolog("wait_for_text '#{text}' not foundafter #{howLong} second(s)")
|
2184
|
+
end
|
2185
|
+
countdown
|
2186
|
+
end
|
2187
|
+
|
2188
|
+
def wait_for_element_to_reappear(browser, how, what, desc = '', timeout = 20)
|
2189
|
+
msg = "Element #{how}=#{what} exists. #{desc}"
|
2190
|
+
wait_while(browser, "While: #{msg}", timeout) { browser.element(how, what).exists? }
|
2191
|
+
wait_until(browser, "Until: #{msg}", timeout) { browser.element(how, what).exists? }
|
2192
|
+
end
|
2193
|
+
|
2194
|
+
# howLong is integer, whatFor is a browser object
|
2195
|
+
def wait_for_exists(howLong, whatFor)
|
2196
|
+
wait_for(howLong, whatFor)
|
2197
|
+
end
|
2198
|
+
|
2199
|
+
def wait_for(howLong, whatFor)
|
2200
|
+
countdown = howLong
|
2201
|
+
while ((not whatFor.exists?) and countdown > 0)
|
2202
|
+
sleep(1)
|
2203
|
+
puts whatFor.inspect+':'+countdown.to_s
|
2204
|
+
countdown = countdown - 1
|
2205
|
+
end
|
2206
|
+
if countdown
|
2207
|
+
puts 'found '+whatFor.inspect
|
2208
|
+
passed_tolog("wait_for (#{howLong} found "+whatFor.inspect)
|
2209
|
+
else
|
2210
|
+
puts 'Did not find '+whatFor.inspect
|
2211
|
+
failed_tolog("wait_for (#{howLong} did not find "+whatFor.inspect)
|
2212
|
+
end
|
2213
|
+
countdown
|
2214
|
+
end
|
2215
|
+
|
2216
|
+
#Sample usage:
|
2217
|
+
# if wait_for( 10, browser.link(:id, "wria-messagebox-yes") )
|
2218
|
+
# browser.link(:id, "wria-messagebox-yes").click
|
2219
|
+
# . .
|
2220
|
+
# else
|
2221
|
+
# @myLog.error('['+__LINE__.to_s+'] '+role+' Validate Expected Confirm Delete messagebox')
|
2222
|
+
# end
|
2223
|
+
|
2224
|
+
def wait_the_hard_way(browser, how, what, wait = 6, intvl = 0.25)
|
2225
|
+
count = (wait / intvl).to_i + 1
|
2226
|
+
tally = 0
|
2227
|
+
ok = (1 / intvl).to_i + 1
|
2228
|
+
debug_to_log("#{__method__}: wait: #{wait} secs; intvl: #{intvl} secs; count; #{count}; thresh: #{ok}")
|
2229
|
+
(1..count).each do |x|
|
2230
|
+
begin
|
2231
|
+
if browser.element(how, what).exists?
|
2232
|
+
tally += 1
|
2233
|
+
debug_to_log("#{x}: #{(x - 1) * intvl}: #{what} exists.")
|
2234
|
+
else
|
2235
|
+
tally = 0
|
2236
|
+
debug_to_log("#{x}: #{(x - 1) * intvl}: #{what} does not exist.")
|
2237
|
+
end
|
2238
|
+
rescue
|
2239
|
+
tally = 0
|
2240
|
+
debug_to_log("#{x}: #{(x - 1) * intvl}: #{what} rescue: #{$!}")
|
2241
|
+
end
|
2242
|
+
if tally >= ok
|
2243
|
+
return true
|
2244
|
+
end
|
2245
|
+
sleep(intvl)
|
2246
|
+
end
|
2247
|
+
end
|
2248
|
+
|
2249
|
+
def is_browser?(browser)
|
2250
|
+
myClass = browser.class.to_s
|
2251
|
+
case @targetBrowser.abbrev
|
2252
|
+
when 'IE'
|
2253
|
+
myClass =~ /Watir::/i # TODO: should this be /Watir::IE/i ?
|
2254
|
+
when 'FF'
|
2255
|
+
if @version.to_f < 4.0
|
2256
|
+
myClass =~ /FireWatir::/i
|
2257
|
+
else
|
2258
|
+
myClass =~ /Watir::Browser/i
|
2259
|
+
end
|
2260
|
+
when 'S'
|
2261
|
+
myClass =~ /Watir::Safari/i
|
2262
|
+
when 'C'
|
2263
|
+
myClass =~ /Watir::Browser/i
|
2264
|
+
end
|
2265
|
+
end
|
2266
|
+
|
2267
|
+
alias is_browser is_browser?
|
2268
|
+
|
2269
|
+
def nice_array(arr, space_to_underscore = false)
|
2270
|
+
new_arr = Array.new
|
2271
|
+
if space_to_underscore
|
2272
|
+
arr.each do |nty|
|
2273
|
+
new_arr << nty.gsub(/\s/, '_')
|
2274
|
+
end
|
2275
|
+
else
|
2276
|
+
new_arr = arr
|
2277
|
+
end
|
2278
|
+
"['#{new_arr.join("','")}']"
|
2279
|
+
end
|
2280
|
+
|
2281
|
+
def open_browser(url = nil)
|
2282
|
+
debug_to_log("Opening browser: #{@targetBrowser.name}")
|
2283
|
+
debug_to_log("#{__method__}: [#{get_caller_line}] #{get_callers}")
|
2284
|
+
case @targetBrowser.abbrev
|
2285
|
+
when 'IE'
|
2286
|
+
@myBrowser = open_ie
|
2287
|
+
@myHwnd = @myBrowser.hwnd
|
2288
|
+
#@waiter = Watir::Waiter.new(WAIT)
|
2289
|
+
when 'FF'
|
2290
|
+
#version = "11"
|
2291
|
+
#@myBrowser = open_ff_for_version(version)
|
2292
|
+
@myBrowser = open_ff_for_version
|
2293
|
+
when 'S'
|
2294
|
+
debug_to_log("Opening browser: #{@targetBrowser.name} legacy.rb:#{__LINE__}")
|
2295
|
+
aBrowser = Watir::Safari.new
|
2296
|
+
debug_to_log("Browser instantiated")
|
2297
|
+
@myBrowser = aBrowser
|
2298
|
+
#require 'shamisen/awetest_legacy/safari_waiter'
|
2299
|
+
#@waiter = Watir::Waiter
|
2300
|
+
when 'C', 'GC'
|
2301
|
+
@myBrowser = open_chrome
|
2302
|
+
##require 'shamisen/awetest_legacy/webdriver_waiter'
|
2303
|
+
#require 'shamisen/support/webdriver_ext/browser'
|
2304
|
+
#@waiter = Watir::Waiter
|
2305
|
+
|
2306
|
+
else
|
2307
|
+
raise "Unsupported browser: #{@targetBrowser.name}"
|
2308
|
+
end
|
2309
|
+
get_browser_version(@myBrowser)
|
2310
|
+
if url
|
2311
|
+
go_to_url(@myBrowser, url)
|
2312
|
+
end
|
2313
|
+
@myBrowser
|
2314
|
+
end
|
2315
|
+
|
2316
|
+
def open_ie(process = true)
|
2317
|
+
check_for_and_clear_other_browsers
|
2318
|
+
Watir::Browser.default = 'ie'
|
2319
|
+
#if process && !IS_WIN_2008
|
2320
|
+
# browser = Watir::IE.new_process
|
2321
|
+
#else
|
2322
|
+
browser = Watir::IE.new
|
2323
|
+
#end
|
2324
|
+
browser
|
2325
|
+
end
|
2326
|
+
|
2327
|
+
def open_ff_for_version(version = @targetVersion)
|
2328
|
+
if version.to_f < 4.0
|
2329
|
+
browser = open_ff
|
2330
|
+
#waiter = Watir::Waiter.new(WAIT)
|
2331
|
+
else
|
2332
|
+
browser = Watir::Browser.new(:firefox)
|
2333
|
+
#require 'shamisen/awetest_legacy/webdriver_waiter'
|
2334
|
+
#waiter = Watir::Waiter
|
2335
|
+
end
|
2336
|
+
browser
|
2337
|
+
end
|
2338
|
+
|
2339
|
+
def open_ff
|
2340
|
+
Watir::Browser.default = 'firefox'
|
2341
|
+
browser = Watir::Browser.new
|
2342
|
+
end
|
2343
|
+
|
2344
|
+
def open_chrome
|
2345
|
+
browser = Watir::Browser.new(:chrome)
|
2346
|
+
end
|
2347
|
+
|
2348
|
+
#=begin
|
2349
|
+
# Get the browser to navigate to a given url. If not supplied in the second argument,
|
2350
|
+
# defaults to value of FullScript.myURL, which is populated from ApplicationEnvironment.url.
|
2351
|
+
#=end
|
2352
|
+
def go_to_url(browser, url = nil, redirect = nil)
|
2353
|
+
if url
|
2354
|
+
@myURL = url
|
2355
|
+
end
|
2356
|
+
message_tolog("URL: #{@myURL}")
|
2357
|
+
browser.goto(@myURL)
|
2358
|
+
if validate(browser, @myName, __LINE__)
|
2359
|
+
# TODO .url method returns blank in Firewatir
|
2360
|
+
if redirect
|
2361
|
+
passed_to_log("Redirected to url '#{browser.url}'.")
|
2362
|
+
true
|
2363
|
+
elsif browser.url =~ /#{@myURL}/i # or @browserAbbrev == 'FF'
|
2364
|
+
passed_to_log("Navigated to url '#{@myURL}'.")
|
2365
|
+
true
|
2366
|
+
else
|
2367
|
+
failed_to_log("Navigated to url '#{browser.url}' but expected '#{@myURL}'.")
|
2368
|
+
end
|
2369
|
+
end
|
2370
|
+
rescue
|
2371
|
+
fatal_to_log("Unable to navigate to '#{@myURL}': '#{$!}'")
|
2372
|
+
end
|
2373
|
+
|
2374
|
+
#def open_log
|
2375
|
+
# start = Time.now.to_f.to_s
|
2376
|
+
#
|
2377
|
+
# logTS = Time.at(@myRun.launched.to_f).strftime("%Y%m%d%H%M%S")
|
2378
|
+
# xls = @myAppEnv.xls_name.gsub('.xls', '') + '_' if @myAppEnv.xls_name.length > 0
|
2379
|
+
# @logFileSpec = "#{@myRoot}/#{logdir}/#{@myName}_#{@targetBrowser.abbrev}_#{xls}#{logTS}.log"
|
2380
|
+
# init_logger(@logFileSpec, @myName)
|
2381
|
+
#
|
2382
|
+
# # message_tolog( self.inspect )
|
2383
|
+
# message_to_log("#{@myName} launched at [#{@myRun.launched.to_f.to_s}][#{@myScript.id}][#{@myRun.id}][#{@myChild.id}]")
|
2384
|
+
# debug_to_log("pid: #{$$}")
|
2385
|
+
# message_to_log("#{@myName} begin at [#{start}]")
|
2386
|
+
# message_to_log("#{@myName} environment [#{@myAppEnv.name}]")
|
2387
|
+
# message_to_log("#{@myName} xls_name [#{@myAppEnv.xls_name}]") if @myAppEnv.xls_name.length > 0
|
2388
|
+
# message_to_log("#{@myName} rootDir [#{@myRoot}]")
|
2389
|
+
# message_to_log("#{@myName} Target Browser [#{@targetBrowser.name}]")
|
2390
|
+
# mark_testlevel(@myParent.name, @myParent.level) # Module
|
2391
|
+
# mark_testlevel(@myChild.name, @myChild.level) # SubModule
|
2392
|
+
#
|
2393
|
+
#end
|
2394
|
+
|
2395
|
+
def click(browser, element, how, what, desc = '')
|
2396
|
+
#debug_to_log("#{__method__}: #{element}, #{how}, #{what}")
|
2397
|
+
msg = "Click #{element} :#{how}=>'#{what}'"
|
2398
|
+
msg << ", '#{desc}'" if desc.length > 0
|
2399
|
+
msg1 = "#{element}(#{how}, '#{what}')"
|
2400
|
+
begin
|
2401
|
+
case element
|
2402
|
+
when :link
|
2403
|
+
browser.link(how, what).click
|
2404
|
+
when :button
|
2405
|
+
browser.button(how, what).click
|
2406
|
+
when :image
|
2407
|
+
browser.image(how, what).click
|
2408
|
+
when :radio
|
2409
|
+
case how
|
2410
|
+
when :index
|
2411
|
+
set_radio_by_index(browser, what, desc)
|
2412
|
+
else
|
2413
|
+
browser.radio(how, what).set
|
2414
|
+
end
|
2415
|
+
when :span
|
2416
|
+
browser.span(how, what).click
|
2417
|
+
when :div
|
2418
|
+
browser.div(how, what).click
|
2419
|
+
when :cell
|
2420
|
+
browser.cell(how, what).click
|
2421
|
+
else
|
2422
|
+
browser.element(how, what).click
|
2423
|
+
end
|
2424
|
+
rescue => e
|
2425
|
+
if not rescue_me(e, __method__, "browser(#{msg1}).click", "#{browser.class}")
|
2426
|
+
raise e
|
2427
|
+
end
|
2428
|
+
end
|
2429
|
+
if validate(browser, @myName, __LINE__)
|
2430
|
+
passed_to_log(msg)
|
2431
|
+
true
|
2432
|
+
end
|
2433
|
+
rescue
|
2434
|
+
failed_to_log("Unable to #{msg}. '#{$!}'")
|
2435
|
+
end
|
2436
|
+
|
2437
|
+
def click_no_wait(browser, element, how, what, desc = '')
|
2438
|
+
debug_to_log("#{__method__}: #{element}, #{how}, #{what}")
|
2439
|
+
msg = "Click no wait #{element} :#{how}=>'#{what}'"
|
2440
|
+
msg << ", '#{desc}'" if desc.length > 0
|
2441
|
+
msg1 = "#{element}(#{how}, '#{what}'"
|
2442
|
+
begin
|
2443
|
+
case element
|
2444
|
+
when :link
|
2445
|
+
browser.link(how, what).click_no_wait
|
2446
|
+
when :button
|
2447
|
+
browser.button(how, what).click_no_wait
|
2448
|
+
when :image
|
2449
|
+
browser.image(how, what).click_no_wait
|
2450
|
+
when :radio
|
2451
|
+
case how
|
2452
|
+
when :index
|
2453
|
+
set_radio_no_wait_by_index(browser, what, desc)
|
2454
|
+
else
|
2455
|
+
browser.radio(how, what).click_no_wait
|
2456
|
+
end
|
2457
|
+
when :span
|
2458
|
+
browser.span(how, what).click_no_wait
|
2459
|
+
when :div
|
2460
|
+
browser.div(how, what).click_no_wait
|
2461
|
+
when :checkbox
|
2462
|
+
browser.checkbox(how, what).click_no_wait
|
2463
|
+
when :cell
|
2464
|
+
browser.cell(how, what).click_no_wait
|
2465
|
+
else
|
2466
|
+
browser.element(how, what).click_no_wait
|
2467
|
+
end
|
2468
|
+
rescue => e
|
2469
|
+
if not rescue_me(e, __method__, "browser(#{msg1}').click_no_wait", "#{browser.class}")
|
2470
|
+
raise e
|
2471
|
+
end
|
2472
|
+
end
|
2473
|
+
if validate(browser, @myName, __LINE__)
|
2474
|
+
passed_to_log(msg)
|
2475
|
+
true
|
2476
|
+
end
|
2477
|
+
rescue
|
2478
|
+
failed_to_log("Unable to #{msg} '#{$!}'")
|
2479
|
+
sleep_for(1)
|
2480
|
+
end
|
2481
|
+
|
2482
|
+
def click_button_by_id(browser, strg, desc = '')
|
2483
|
+
click(browser, :button, :id, strg, desc)
|
2484
|
+
end
|
2485
|
+
|
2486
|
+
def click_link_by_index(browser, strg, desc = '')
|
2487
|
+
click(browser, :link, :index, strg, desc)
|
2488
|
+
end
|
2489
|
+
|
2490
|
+
def click_link_by_href(browser, strg, desc = '')
|
2491
|
+
click(browser, :link, :href, strg, desc)
|
2492
|
+
end
|
2493
|
+
|
2494
|
+
alias click_href click_link_by_href
|
2495
|
+
|
2496
|
+
def click_link_no_wait_by_href(browser, strg, desc = '')
|
2497
|
+
click_no_wait(browser, :link, :href, strg, desc)
|
2498
|
+
end
|
2499
|
+
|
2500
|
+
alias click_href_no_wait click_link_no_wait_by_href
|
2501
|
+
|
2502
|
+
def click_button_by_index(browser, index, desc = '')
|
2503
|
+
click(browser, :button, :index, index, desc)
|
2504
|
+
end
|
2505
|
+
|
2506
|
+
def click_button_by_name(browser, strg, desc = '')
|
2507
|
+
click(browser, :button, :name, strg, desc)
|
2508
|
+
end
|
2509
|
+
|
2510
|
+
def click_button_by_text(browser, strg, desc = '')
|
2511
|
+
click(browser, :button, :text, strg, desc)
|
2512
|
+
end
|
2513
|
+
|
2514
|
+
def click_button_by_class(browser, strg, desc = '')
|
2515
|
+
click(browser, :button, :class, strg, desc)
|
2516
|
+
end
|
2517
|
+
|
2518
|
+
def click_button_no_wait_by_id(browser, strg, desc = '')
|
2519
|
+
click_no_wait(browser, :button, :id, strg, desc)
|
2520
|
+
end
|
2521
|
+
|
2522
|
+
alias click_button_by_id_no_wait click_button_no_wait_by_id
|
2523
|
+
|
2524
|
+
def click_button_no_wait_by_name(browser, strg, desc = '')
|
2525
|
+
click_no_wait(browser, :button, :name, strg, desc)
|
2526
|
+
end
|
2527
|
+
|
2528
|
+
def click_button_no_wait_by_class(browser, strg, desc = '')
|
2529
|
+
click_no_wait(browser, :button, :class, strg, desc)
|
2530
|
+
end
|
2531
|
+
|
2532
|
+
alias click_button_by_class_no_wait click_button_no_wait_by_class
|
2533
|
+
|
2534
|
+
def click_button_by_value(browser, strg, desc = '')
|
2535
|
+
click(browser, :button, :value, strg, desc)
|
2536
|
+
end
|
2537
|
+
|
2538
|
+
def click_button_by_title(browser, strg, desc = '')
|
2539
|
+
click(browser, :button, :title, strg, desc)
|
2540
|
+
end
|
2541
|
+
|
2542
|
+
def click_button_by_xpath_and_id(browser, strg, desc = '')
|
2543
|
+
msg = "Click button by xpath and id '#{strg}' #{desc}"
|
2544
|
+
if browser.button(:xpath, "//a[@id = '#{strg}']").click
|
2545
|
+
passed_to_log(msg)
|
2546
|
+
true
|
2547
|
+
else
|
2548
|
+
failed_to_log(msg)
|
2549
|
+
end
|
2550
|
+
rescue
|
2551
|
+
failed_to_log("Unable to click button by xpath and id '#{strg}' #{desc} '#{$!}' (#{__LINE__})")
|
2552
|
+
end
|
2553
|
+
|
2554
|
+
alias click_button_by_xpath click_button_by_xpath_and_id
|
2555
|
+
|
2556
|
+
def click_link_by_id(browser, strg, desc = '')
|
2557
|
+
click(browser, :link, :id, strg, desc)
|
2558
|
+
end
|
2559
|
+
|
2560
|
+
alias click_id click_link_by_id
|
2561
|
+
|
2562
|
+
def click_link_by_name(browser, strg, desc = '')
|
2563
|
+
click(browser, :link, :name, strg, desc)
|
2564
|
+
end
|
2565
|
+
|
2566
|
+
alias click_name click_link_by_name
|
2567
|
+
|
2568
|
+
def click_link_by_xpath_and_id(browser, strg, desc = '')
|
2569
|
+
msg = "Click link by xpath and id '#{strg}' #{desc}"
|
2570
|
+
if browser.link(:xpath, "//a[@id = '#{strg}']").click
|
2571
|
+
passed_to_log(msg)
|
2572
|
+
true
|
2573
|
+
else
|
2574
|
+
failed_to_log(msg)
|
2575
|
+
end
|
2576
|
+
rescue
|
2577
|
+
failed_to_log("Unable click on link by xpath and id '#{strg}' #{desc} '#{$!}' (#{__LINE__})")
|
2578
|
+
end
|
2579
|
+
|
2580
|
+
alias click_link_by_xpath click_link_by_xpath_and_id
|
2581
|
+
|
2582
|
+
def click_link_no_wait_by_id(browser, strg, desc = '')
|
2583
|
+
click_no_wait(browser, :link, :id, strg, desc)
|
2584
|
+
end
|
2585
|
+
|
2586
|
+
alias click_no_wait_id click_link_no_wait_by_id
|
2587
|
+
alias click_no_wait_by_id click_link_no_wait_by_id
|
2588
|
+
alias click_id_no_wait click_link_no_wait_by_id
|
2589
|
+
alias click_no_wait_link_by_id click_link_no_wait_by_id
|
2590
|
+
|
2591
|
+
def click_file_field_by_id(browser, strg, desc = '')
|
2592
|
+
click(browser, :file_field, :id, strg, desc)
|
2593
|
+
end
|
2594
|
+
|
2595
|
+
def click_img_by_alt(browser, strg, desc = '')
|
2596
|
+
click(browser, :image, :alt, strg, desc)
|
2597
|
+
end
|
2598
|
+
|
2599
|
+
def click_img_by_title(browser, strg, desc = '')
|
2600
|
+
click(browser, :image, :title, strg, desc)
|
2601
|
+
end
|
2602
|
+
|
2603
|
+
def click_img_by_xpath_and_name(browser, strg, desc = '')
|
2604
|
+
msg = "Click image by xpath where name='#{strg}' #{desc}"
|
2605
|
+
if browser.link(:xpath, "//input[@name = '#{strg}']").click
|
2606
|
+
passed_to_log(msg)
|
2607
|
+
true
|
2608
|
+
else
|
2609
|
+
failed_to_log(msg)
|
2610
|
+
end
|
2611
|
+
rescue
|
2612
|
+
failed_to_log("Unable to click image by xpath where name='#{strg}' #{desc} '#{$!}'")
|
2613
|
+
end
|
2614
|
+
|
2615
|
+
alias click_img_by_xpath click_img_by_xpath_and_name
|
2616
|
+
alias click_image_by_xpath click_img_by_xpath_and_name
|
2617
|
+
alias click_image_by_xpath_and_name click_img_by_xpath_and_name
|
2618
|
+
|
2619
|
+
def click_img_no_wait_by_alt(browser, strg, desc = '')
|
2620
|
+
click_no_wait(browser, :image, :alt, strg, desc)
|
2621
|
+
end
|
2622
|
+
|
2623
|
+
alias click_img_by_alt_no_wait click_img_no_wait_by_alt
|
2624
|
+
|
2625
|
+
def click_img_by_src(browser, strg, desc = '')
|
2626
|
+
click(browser, :image, :src, strg, desc)
|
2627
|
+
end
|
2628
|
+
|
2629
|
+
def click_img_by_src_and_index(browser, strg, index, desc = '')
|
2630
|
+
msg = "Click image by src='#{strg}' and index=#{index}"
|
2631
|
+
msg << " #{desc}" if desc.length > 0
|
2632
|
+
browser.image(:src => strg, :index => index).click
|
2633
|
+
if validate(browser, @myName, __LINE__)
|
2634
|
+
passed_to_log(msg)
|
2635
|
+
true
|
2636
|
+
end
|
2637
|
+
rescue
|
2638
|
+
failed_to_log("Unable to #{msg} '#{$!}'")
|
2639
|
+
end
|
2640
|
+
|
2641
|
+
def click_link_by_value(browser, strg, desc = '')
|
2642
|
+
click(browser, :link, :value, strg, desc)
|
2643
|
+
end
|
2644
|
+
|
2645
|
+
def click_link_by_text(browser, strg, desc = '')
|
2646
|
+
click(browser, :link, :text, strg, desc)
|
2647
|
+
end
|
2648
|
+
|
2649
|
+
alias click_link click_link_by_text
|
2650
|
+
alias click_text click_link_by_text
|
2651
|
+
alias click_js_button click_link_by_text
|
2652
|
+
|
2653
|
+
def click_link_by_class(browser, strg, desc = '')
|
2654
|
+
click(browser, :link, :class, strg, desc)
|
2655
|
+
end
|
2656
|
+
|
2657
|
+
alias click_class click_link_by_class
|
2658
|
+
|
2659
|
+
def click_button_no_wait_by_text(browser, strg, desc = '')
|
2660
|
+
click_no_wait(browser, :button, :text, strg, desc)
|
2661
|
+
end
|
2662
|
+
|
2663
|
+
def click_button_no_wait_by_value(browser, strg, desc = '')
|
2664
|
+
click_no_wait(browser, :button, :value, strg, desc)
|
2665
|
+
end
|
2666
|
+
|
2667
|
+
def click_link_by_name_no_wait(browser, strg, desc = '')
|
2668
|
+
click_no_wait(browser, :link, :name, strg, desc)
|
2669
|
+
end
|
2670
|
+
|
2671
|
+
alias click_no_wait_name click_link_by_name_no_wait
|
2672
|
+
alias click_name_no_wait click_link_by_name_no_wait
|
2673
|
+
|
2674
|
+
def click_link_by_text_no_wait(browser, strg, desc = '')
|
2675
|
+
click_no_wait(browser, :link, :text, strg, desc)
|
2676
|
+
end
|
2677
|
+
|
2678
|
+
alias click_no_wait_text click_link_by_text_no_wait
|
2679
|
+
alias click_text_no_wait click_link_by_text_no_wait
|
2680
|
+
|
2681
|
+
def click_span_by_text(browser, strg, desc = '')
|
2682
|
+
if not desc and not strg.match(/Save|Open|Close|Submit|Cancel/)
|
2683
|
+
desc = 'to navigate to selection'
|
2684
|
+
end
|
2685
|
+
msg = "Click span containing text '#{strg}'."
|
2686
|
+
msg << " #{desc}" if desc.length > 0
|
2687
|
+
if validate(browser, @myName, __LINE__)
|
2688
|
+
passed_to_log("#{msg}")
|
2689
|
+
end
|
2690
|
+
rescue
|
2691
|
+
failed_to_log("Unable to #{msg}: '#{$!}'")
|
2692
|
+
end
|
2693
|
+
|
2694
|
+
# TODO no logging yet. slow.
|
2695
|
+
def click_span_with_text(browser, trgt, desc = '')
|
2696
|
+
msg = "Find and click span containing text '#{trgt}'."
|
2697
|
+
msg << " #{desc}" if desc.length > 0
|
2698
|
+
spans = browser.spans
|
2699
|
+
x = 0
|
2700
|
+
spans.each do |span|
|
2701
|
+
x += 1
|
2702
|
+
debug_to_log("Span #{x}: #{span.text}")
|
2703
|
+
aText = span.text
|
2704
|
+
if aText and aText.size > 0
|
2705
|
+
if aText =~ /#{trgt}/
|
2706
|
+
break
|
2707
|
+
end
|
2708
|
+
end
|
2709
|
+
end
|
2710
|
+
spans[x].click
|
2711
|
+
end
|
2712
|
+
|
2713
|
+
def click_link_by_title(browser, strg, desc = '')
|
2714
|
+
click(browser, :link, :title, strg, desc)
|
2715
|
+
end
|
2716
|
+
|
2717
|
+
alias click_title click_link_by_title
|
2718
|
+
|
2719
|
+
def click_title_no_wait(browser, strg, desc = '')
|
2720
|
+
click_no_wait(browser, :link, :title, strg, desc)
|
2721
|
+
end
|
2722
|
+
|
2723
|
+
def click_table_row_with_text_by_id(browser, ptrn, strg, column = nil)
|
2724
|
+
msg = "id=#{ptrn} row with text='#{strg}"
|
2725
|
+
table = get_table_by_id(browser, /#{ptrn}/)
|
2726
|
+
if table
|
2727
|
+
index = get_index_of_row_with_text(table, strg, column)
|
2728
|
+
if index
|
2729
|
+
table[index].click
|
2730
|
+
if validate(browser, @myName, __LINE__)
|
2731
|
+
passed_to_log("Click #{msg} row index=#{index}.")
|
2732
|
+
index
|
2733
|
+
end
|
2734
|
+
else
|
2735
|
+
failed_to_log("Table #{msg} not found to click.")
|
2736
|
+
end
|
2737
|
+
else
|
2738
|
+
failed_to_log("Table id=#{ptrn} not found.")
|
2739
|
+
end
|
2740
|
+
rescue
|
2741
|
+
failed_to_log("Unable to click table #{msg}: '#{$!}' (#{__LINE__}) ")
|
2742
|
+
end
|
2743
|
+
|
2744
|
+
def click_table_row_with_text_by_index(browser, idx, strg, column = nil)
|
2745
|
+
msg = "index=#{idx} row with text='#{strg}"
|
2746
|
+
table = get_table_by_index(browser, idx)
|
2747
|
+
if table
|
2748
|
+
index = get_index_of_row_with_text(table, strg, column)
|
2749
|
+
if index
|
2750
|
+
table[index].click
|
2751
|
+
if validate(browser, @myName, __LINE__)
|
2752
|
+
passed_to_log("Click #{msg} row index=#{index}.")
|
2753
|
+
index
|
2754
|
+
end
|
2755
|
+
else
|
2756
|
+
failed_to_log("Table #{msg} not found to click.")
|
2757
|
+
end
|
2758
|
+
else
|
2759
|
+
failed_to_log("Table id=#{ptrn} not found.")
|
2760
|
+
end
|
2761
|
+
rescue
|
2762
|
+
failed_to_log("Unable to click table #{msg}: '#{$!}' (#{__LINE__}) ")
|
2763
|
+
end
|
2764
|
+
|
2765
|
+
def double_click_table_row_with_text_by_id(browser, ptrn, strg, column = nil)
|
2766
|
+
msg = "id=#{ptrn} row with text='#{strg}"
|
2767
|
+
table = get_table_by_id(browser, /#{ptrn}/)
|
2768
|
+
if table
|
2769
|
+
index = get_index_of_row_with_text(table, strg, column)
|
2770
|
+
if index
|
2771
|
+
table[index].fire_event('ondblclick')
|
2772
|
+
if validate(browser, @myName, __LINE__)
|
2773
|
+
passed_to_log("Double click #{msg} row index=#{index}.")
|
2774
|
+
index
|
2775
|
+
end
|
2776
|
+
else
|
2777
|
+
failed_to_log("Table #{msg} not found to double click.")
|
2778
|
+
end
|
2779
|
+
else
|
2780
|
+
failed_to_log("Table id=#{ptrn} not found.")
|
2781
|
+
end
|
2782
|
+
rescue
|
2783
|
+
failed_to_log("Unable to double click table #{msg}: '#{$!}' (#{__LINE__}) ")
|
2784
|
+
end
|
2785
|
+
|
2786
|
+
def double_click_table_row_with_text_by_index(browser, idx, strg, column = nil)
|
2787
|
+
msg = "index=#{idx} row with text='#{strg}"
|
2788
|
+
table = get_table_by_index(browser, idx)
|
2789
|
+
if table
|
2790
|
+
index = get_index_of_row_with_text(table, strg, column)
|
2791
|
+
if index
|
2792
|
+
row = table[index]
|
2793
|
+
table[index].fire_event('ondblclick')
|
2794
|
+
row.fire_event('ondblclick')
|
2795
|
+
if validate(browser, @myName, __LINE__)
|
2796
|
+
passed_to_log("Double click #{msg} row index=#{index}.")
|
2797
|
+
index
|
2798
|
+
end
|
2799
|
+
else
|
2800
|
+
failed_to_log("Table #{msg} not found to double click.")
|
2801
|
+
end
|
2802
|
+
else
|
2803
|
+
failed_to_log("Table id=#{ptrn} not found.")
|
2804
|
+
end
|
2805
|
+
rescue
|
2806
|
+
failed_to_log("Unable to double click table #{msg}: '#{$!}' (#{__LINE__}) ")
|
2807
|
+
end
|
2808
|
+
|
2809
|
+
def flash_text(browser, strg, count, desc = '')
|
2810
|
+
msg = "Flash link text='#{strg}' #{count} times."
|
2811
|
+
msg << " #{desc}" if desc.length > 0
|
2812
|
+
strgCnt = string_count_in_string(browser.text, strg)
|
2813
|
+
if strgCnt > 0
|
2814
|
+
browser.link(:text, strg).flash(count)
|
2815
|
+
if validate(browser, @myName, __LINE__)
|
2816
|
+
passed_to_log(msg)
|
2817
|
+
true
|
2818
|
+
end
|
2819
|
+
else
|
2820
|
+
failed_to_log("#{msg} Link not found.")
|
2821
|
+
end
|
2822
|
+
rescue
|
2823
|
+
failed_to_log("Unable to #{msg} '#{$!}'")
|
2824
|
+
end
|
2825
|
+
|
2826
|
+
def flash_id(browser, strg, count)
|
2827
|
+
msg = "Flash link id='#{strg}' #{count} times."
|
2828
|
+
msg << " #{desc}" if desc.length > 0
|
2829
|
+
browser.link(:id, strg).flash(count)
|
2830
|
+
if validate(browser, @myName, __LINE__)
|
2831
|
+
passed_to_log(msg)
|
2832
|
+
true
|
2833
|
+
end
|
2834
|
+
rescue
|
2835
|
+
failed_to_log("Unable to #{msg} '#{$!}'")
|
2836
|
+
end
|
2837
|
+
|
2838
|
+
def flash(element, count = 4)
|
2839
|
+
element.flash(count)
|
2840
|
+
debug_to_log("'#{element.inspect}' flashed #{count} times.")
|
2841
|
+
true
|
2842
|
+
rescue
|
2843
|
+
debug_to_log("Flash '#{element.inspect}' failed: '#{$!}' (#{__LINE__})")
|
2844
|
+
end
|
2845
|
+
|
2846
|
+
def upload_file(data_path)
|
2847
|
+
limit = 180 # .seconds
|
2848
|
+
Timeout::timeout(limit) {
|
2849
|
+
wait = 20
|
2850
|
+
@ai.WinWait("Choose File to Upload", "", wait)
|
2851
|
+
sleep 1
|
2852
|
+
@ai.ControlSend("Choose File to Upload", "", "Edit1", data_path)
|
2853
|
+
@ai.ControlClick("Choose File to Upload", "", "[CLASS:Button; INSTANCE:2]", "left")
|
2854
|
+
sleep 4
|
2855
|
+
#sleep 1
|
2856
|
+
}
|
2857
|
+
failed_to_log("Choose File to Upload not found after #{limit} '#{$!}'")
|
2858
|
+
rescue Timeout::Error
|
2859
|
+
failed_to_log("File Upload timeout after #{limit} '#{$!}'")
|
2860
|
+
end
|
2861
|
+
|
2862
|
+
#TODO put rescue inside the do loop
|
2863
|
+
#parameters: browser and a list of column link text values
|
2864
|
+
#example: exercise_sorting(browser,['Division', 'Payee', 'Date'], 'Sortable columns on this page')
|
2865
|
+
|
2866
|
+
def exercise_sorting(browser, columnList, desc = '')
|
2867
|
+
columnList.each do |column|
|
2868
|
+
click(browser, :link, :text, column, desc)
|
2869
|
+
end
|
2870
|
+
end
|
2871
|
+
|
2872
|
+
alias validate_sorting exercise_sorting
|
2873
|
+
|
2874
|
+
def focus_on_textfield_by_id(browser, strg, desc = '')
|
2875
|
+
msg = "Set focus on textfield name='#{strg}' "
|
2876
|
+
msg << " #{desc}" if desc.length > 0
|
2877
|
+
tf = browser.text_field(:id, strg)
|
2878
|
+
if validate(browser, @myName, __LINE__)
|
2879
|
+
tf.focus
|
2880
|
+
if validate(browser, @myName, __LINE__)
|
2881
|
+
passed_to_log(msg)
|
2882
|
+
true
|
2883
|
+
end
|
2884
|
+
end
|
2885
|
+
rescue
|
2886
|
+
failed_to_log("Unable to #{msg} '#{$!}'")
|
2887
|
+
end
|
2888
|
+
|
2889
|
+
def open_popup_through_link_title(browser, title, pattern, name)
|
2890
|
+
click_title(browser, title)
|
2891
|
+
#TODO need some kind of wait for process here
|
2892
|
+
sleep_for 2
|
2893
|
+
attach_iepopup(browser, pattern, name)
|
2894
|
+
rescue
|
2895
|
+
failed_to_log("Unable to open popup '#{name}': '#{$!}' (#{__LINE__})")
|
2896
|
+
end
|
2897
|
+
|
2898
|
+
def get_div(browser, how, what, desc = '', dbg = false)
|
2899
|
+
msg = "Get division #{how}=>#{what}."
|
2900
|
+
msg << " #{desc}" if desc.length > 0
|
2901
|
+
Watir::Wait.until { browser.div(how, what).exists? }
|
2902
|
+
div = browser.div(how, what)
|
2903
|
+
debug_to_log(div.inspect) if dbg
|
2904
|
+
if validate(browser, @myName, __LINE__)
|
2905
|
+
if div
|
2906
|
+
passed_to_log(msg)
|
2907
|
+
return div
|
2908
|
+
else
|
2909
|
+
failed_to_log(msg)
|
2910
|
+
end
|
2911
|
+
end
|
2912
|
+
rescue
|
2913
|
+
failed_to_log("Unable to '#{msg}' '#{$!}'")
|
2914
|
+
end
|
2915
|
+
|
2916
|
+
def get_div_by_id(browser, strg, desc = '', dbg = false)
|
2917
|
+
get_div(browser, :id, strg, desc, dbg)
|
2918
|
+
end
|
2919
|
+
|
2920
|
+
def get_div_by_class(browser, strg, desc = '', dbg = false)
|
2921
|
+
get_div(browser, :class, strg, desc, dbg)
|
2922
|
+
end
|
2923
|
+
|
2924
|
+
def get_div_by_text(browser, strg, desc = '', dbg = false)
|
2925
|
+
get_div(browser, :text, strg, desc, dbg)
|
2926
|
+
end
|
2927
|
+
|
2928
|
+
def get_form(browser, how, strg)
|
2929
|
+
begin
|
2930
|
+
# Watir::Wait.until( browser.form(how, strg).exists? ) # fails in wait_until
|
2931
|
+
rescue => e
|
2932
|
+
if not rescue_me(e, __method__, "browser.form(#{how}, '#{strg}').exists?", "#{browser.class}")
|
2933
|
+
raise e
|
2934
|
+
end
|
2935
|
+
end
|
2936
|
+
myForm = browser.form(how, strg)
|
2937
|
+
if validate(browser, @myName, __LINE__)
|
2938
|
+
passed_to_log("Form #{how}='#{strg}' found and returned.")
|
2939
|
+
return myForm
|
2940
|
+
end
|
2941
|
+
rescue
|
2942
|
+
failed_to_log("Unable to return form #{how}='#{strg}': '#{$!}' (#{__LINE__})")
|
2943
|
+
end
|
2944
|
+
|
2945
|
+
def get_form_by_id(browser, strg)
|
2946
|
+
get_form(browser, :id, strg)
|
2947
|
+
end
|
2948
|
+
|
2949
|
+
def get_frame(browser, how, strg, desc = '')
|
2950
|
+
# begin
|
2951
|
+
# Watir::Wait.until(browser.frame(how, strg).exists?) # fails in wait_until
|
2952
|
+
# rescue => e
|
2953
|
+
# if not rescue_me(e, __method__, "browser.frame(#{how}, '#{strg}').exists?", "#{browser.class}")
|
2954
|
+
# raise e
|
2955
|
+
# end
|
2956
|
+
# end
|
2957
|
+
begin
|
2958
|
+
frame = browser.frame(how, strg)
|
2959
|
+
rescue => e
|
2960
|
+
if not rescue_me(e, __method__, "browser.frame(#{how}, '#{strg}').exists?", "#{browser.class}")
|
2961
|
+
raise e
|
2962
|
+
end
|
2963
|
+
end
|
2964
|
+
if validate(browser, @myName, __LINE__)
|
2965
|
+
passed_to_log("Frame #{how}='#{strg}' found and returned. #{desc}")
|
2966
|
+
return frame
|
2967
|
+
end
|
2968
|
+
rescue
|
2969
|
+
failed_to_log("Unable to return frame #{how}='#{strg}'. #{desc}: '#{$!}' (#{__LINE__})")
|
2970
|
+
end
|
2971
|
+
|
2972
|
+
def get_frame_by_id(browser, strg, desc = '')
|
2973
|
+
get_frame(browser, :id, strg, desc)
|
2974
|
+
end
|
2975
|
+
|
2976
|
+
def get_frame_by_index(browser, index, desc = '')
|
2977
|
+
get_frame(browser, :index, index, desc)
|
2978
|
+
end
|
2979
|
+
|
2980
|
+
def get_frame_by_name(browser, strg, desc = '')
|
2981
|
+
get_frame(browser, :name, strg, desc)
|
2982
|
+
end
|
2983
|
+
|
2984
|
+
def get_span(browser, how, strg, desc = '')
|
2985
|
+
begin
|
2986
|
+
#TODO: use LegacyExtensions#wait_until
|
2987
|
+
Watir::Wait.until { browser.span(how, strg).exists? }
|
2988
|
+
rescue => e
|
2989
|
+
if not rescue_me(e, __method__, "browser.span(#{how}, '#{strg}').exists?", "#{browser.class}")
|
2990
|
+
raise e
|
2991
|
+
end
|
2992
|
+
end
|
2993
|
+
begin
|
2994
|
+
span = browser.span(how, strg)
|
2995
|
+
rescue => e
|
2996
|
+
if not rescue_me(e, __method__, "browser.span(#{how}, '#{strg}').exists?", "#{browser.class}")
|
2997
|
+
raise e
|
2998
|
+
end
|
2999
|
+
end
|
3000
|
+
if validate(browser, @myName, __LINE__)
|
3001
|
+
passed_to_log("Span #{how}='#{strg}' found and returned. #{desc}")
|
3002
|
+
return span
|
3003
|
+
end
|
3004
|
+
rescue
|
3005
|
+
failed_to_log("Unable to return span #{how}='#{strg}'. #{desc}: '#{$!}' (#{__LINE__})")
|
3006
|
+
end
|
3007
|
+
|
3008
|
+
def get_span_by_id(browser, strg, desc = '')
|
3009
|
+
get_span(browser, :id, strg, desc)
|
3010
|
+
end
|
3011
|
+
|
3012
|
+
def get_table(browser, how, what, desc = '')
|
3013
|
+
msg = "Return table :#{how}='#{what}'. #{desc}"
|
3014
|
+
tbl = browser.table(how, what)
|
3015
|
+
if validate(browser, @myName, __LINE__)
|
3016
|
+
passed_to_log(msg)
|
3017
|
+
tbl
|
3018
|
+
end
|
3019
|
+
rescue
|
3020
|
+
failed_to_log("#{msg}': '#{$!}'")
|
3021
|
+
end
|
3022
|
+
|
3023
|
+
def get_table_by_id(browser, strg, desc = '')
|
3024
|
+
get_table(browser, :id, strg, desc)
|
3025
|
+
end
|
3026
|
+
|
3027
|
+
def get_table_by_index(browser, idx)
|
3028
|
+
get_table(browser, :index, idx, desc)
|
3029
|
+
end
|
3030
|
+
|
3031
|
+
def get_table_by_text(browser, strg)
|
3032
|
+
get_table(browser, :text, strg, desc)
|
3033
|
+
end
|
3034
|
+
|
3035
|
+
def get_table_headers(table, header_index = 1)
|
3036
|
+
headers = Hash.new
|
3037
|
+
headers['index'] = Hash.new
|
3038
|
+
headers['name'] = Hash.new
|
3039
|
+
count = 1
|
3040
|
+
table[header_index].each do |cell|
|
3041
|
+
if cell.text.length > 0
|
3042
|
+
name = cell.text.gsub(/\s+/, ' ')
|
3043
|
+
headers['index'][count] = name
|
3044
|
+
headers['name'][name] = count
|
3045
|
+
end
|
3046
|
+
count += 1
|
3047
|
+
end
|
3048
|
+
#debug_to_log("#{__method__}:****** headers:\n#{headers.to_yaml}")
|
3049
|
+
headers
|
3050
|
+
rescue
|
3051
|
+
failed_to_log("Unable to get content headers. '#{$!}'")
|
3052
|
+
end
|
3053
|
+
|
3054
|
+
def get_textfield_value(browser, how, what, desc = '')
|
3055
|
+
msg = "Return value in textfield #{how}='#{what}'"
|
3056
|
+
msg << " #{desc}" if desc.length > 0
|
3057
|
+
tf = browser.text_field(how, what)
|
3058
|
+
if validate(browser, @myName, __LINE__)
|
3059
|
+
if tf
|
3060
|
+
debug_to_log("#{tf.inspect}")
|
3061
|
+
vlu = tf.value
|
3062
|
+
passed_to_log("#{msg} Value='#{vlu}'")
|
3063
|
+
vlu
|
3064
|
+
else
|
3065
|
+
failed_to_log("#{msg}")
|
3066
|
+
end
|
3067
|
+
end
|
3068
|
+
rescue
|
3069
|
+
failed_to_log("Unable to #{msg}: '#{$!}'")
|
3070
|
+
end
|
3071
|
+
|
3072
|
+
def get_textfield_value_by_name(browser, strg, desc = '')
|
3073
|
+
get_textfield_value(browser, :name, strg, desc)
|
3074
|
+
end
|
3075
|
+
|
3076
|
+
def get_textfield_value_by_id(browser, strg)
|
3077
|
+
get_textfield_value(browser, :id, strg)
|
3078
|
+
end
|
3079
|
+
|
3080
|
+
def string_count_in_string(strg, substrg)
|
3081
|
+
count = strg.scan(substrg).length
|
3082
|
+
count
|
3083
|
+
end
|
3084
|
+
|
3085
|
+
def translate_popup_title(title)
|
3086
|
+
new_title = title
|
3087
|
+
case @browserAbbrev
|
3088
|
+
when 'IE'
|
3089
|
+
if @browserVersion
|
3090
|
+
case @browserVersion
|
3091
|
+
when '8.0'
|
3092
|
+
case title
|
3093
|
+
when "Microsoft Internet Explorer"
|
3094
|
+
new_title = "Message from webpage"
|
3095
|
+
when "The page at"
|
3096
|
+
new_title = "Message from webpage"
|
3097
|
+
end
|
3098
|
+
when '7.0'
|
3099
|
+
case title
|
3100
|
+
when "Message from webpage"
|
3101
|
+
new_title = "Microsoft Internet Explorer"
|
3102
|
+
when "The page at"
|
3103
|
+
new_title = "Windows Internet Explorer"
|
3104
|
+
end
|
3105
|
+
when '6.0'
|
3106
|
+
case title
|
3107
|
+
when "Message from webpage"
|
3108
|
+
new_title = "Microsoft Internet Explorer"
|
3109
|
+
when "The page at"
|
3110
|
+
new_title = "Microsoft Internet Explorer"
|
3111
|
+
end
|
3112
|
+
else
|
3113
|
+
case title
|
3114
|
+
when "Microsoft Internet Explorer"
|
3115
|
+
new_title = "Message from webpage"
|
3116
|
+
when "The page at"
|
3117
|
+
new_title = "Message from webpage"
|
3118
|
+
end
|
3119
|
+
end
|
3120
|
+
else
|
3121
|
+
case title
|
3122
|
+
when "Microsoft Internet Explorer"
|
3123
|
+
new_title = "Message from webpage"
|
3124
|
+
when "The page at"
|
3125
|
+
new_title = "Message from webpage"
|
3126
|
+
end
|
3127
|
+
end
|
3128
|
+
when 'FF'
|
3129
|
+
case title
|
3130
|
+
when 'File Download'
|
3131
|
+
new_title = 'Opening'
|
3132
|
+
when "Microsoft Internet Explorer"
|
3133
|
+
new_title = 'The page at'
|
3134
|
+
when "Message from webpage"
|
3135
|
+
new_title = 'The page at'
|
3136
|
+
end
|
3137
|
+
when 'C'
|
3138
|
+
case title
|
3139
|
+
when 'File Download'
|
3140
|
+
new_title = 'Save As'
|
3141
|
+
when "Microsoft Internet Explorer"
|
3142
|
+
new_title = 'The page at'
|
3143
|
+
when "Message from webpage"
|
3144
|
+
new_title = 'The page at'
|
3145
|
+
end
|
3146
|
+
end
|
3147
|
+
new_title
|
3148
|
+
end
|
3149
|
+
|
3150
|
+
#def translate_popup_title(title)
|
3151
|
+
# new_title = title
|
3152
|
+
# case @browserAbbrev
|
3153
|
+
# when 'IE'
|
3154
|
+
#
|
3155
|
+
#
|
3156
|
+
# case title
|
3157
|
+
# when "Microsoft Internet Explorer"
|
3158
|
+
# new_title = "Message from webpage"
|
3159
|
+
# when "The page at"
|
3160
|
+
# new_title = "Message from webpage"
|
3161
|
+
# end
|
3162
|
+
#
|
3163
|
+
#
|
3164
|
+
#
|
3165
|
+
#
|
3166
|
+
# when 'FF'
|
3167
|
+
# case title
|
3168
|
+
# when 'File Download'
|
3169
|
+
# new_title = 'Opening'
|
3170
|
+
# when "Microsoft Internet Explorer"
|
3171
|
+
# new_title = 'The page at'
|
3172
|
+
# when "Message from webpage"
|
3173
|
+
# new_title = 'The page at'
|
3174
|
+
# end
|
3175
|
+
#
|
3176
|
+
# when 'C'
|
3177
|
+
# case title
|
3178
|
+
# when 'File Download'
|
3179
|
+
# new_title = 'Save As'
|
3180
|
+
# when "Microsoft Internet Explorer"
|
3181
|
+
# new_title = 'The page at'
|
3182
|
+
# when "Message from webpage"
|
3183
|
+
# new_title = 'The page at'
|
3184
|
+
# end
|
3185
|
+
# end
|
3186
|
+
# new_title
|
3187
|
+
#end
|
3188
|
+
|
3189
|
+
def get_browser_version(browser)
|
3190
|
+
debug_to_log("starting get_browser_version")
|
3191
|
+
case @targetBrowser.abbrev
|
3192
|
+
when 'IE'
|
3193
|
+
@browserAbbrev = 'IE'
|
3194
|
+
@browserName = 'Internet Explorer'
|
3195
|
+
@browserAppInfo = browser.document.invoke('parentWindow').navigator.appVersion
|
3196
|
+
@browserAppInfo =~ /MSIE\s(.*?);/
|
3197
|
+
@browserVersion = $1
|
3198
|
+
when 'FF'
|
3199
|
+
#@browserAbbrev = 'FF'
|
3200
|
+
#@browserName = 'Firefox'
|
3201
|
+
#js_stuff = <<-end_js_stuff
|
3202
|
+
#var info = Components.classes["@mozilla.org/xre/app-info;1"]
|
3203
|
+
#.getService(Components.interfaces.nsIXULAppInfo);
|
3204
|
+
#[info, info.name, info.version];
|
3205
|
+
#end_js_stuff
|
3206
|
+
#js_stuff.gsub!("\n", " ")
|
3207
|
+
#info = browser.execute_script(js_stuff)
|
3208
|
+
#info, aName, @browserVersion = info.split(',')
|
3209
|
+
#debug_to_log("FF info: [#{info}]")
|
3210
|
+
#debug_to_log("FF name: [#{aName}]")
|
3211
|
+
#debug_to_log("FF vrsn: [#{@browserVersion}]")
|
3212
|
+
@browserAbbrev = 'FF'
|
3213
|
+
@browserName = 'Firefox'
|
3214
|
+
@browserVersion = '6.01' #TODO: get actual version from browser
|
3215
|
+
debug_to_log("Firefox, in get_browser_version (#{@browserVersion})")
|
3216
|
+
when 'S'
|
3217
|
+
@browserAbbrev = 'S'
|
3218
|
+
@browserName = 'Safari'
|
3219
|
+
@browserVersion = '5.0.4' #TODO: get actual version from browser itself
|
3220
|
+
debug_to_log("Safari, in get_browser_version (#{@browserVersion})")
|
3221
|
+
when 'C'
|
3222
|
+
@browserAbbrev = 'C'
|
3223
|
+
@browserName = 'Chrome'
|
3224
|
+
@browserVersion = '11.0' #TODO: get actual version from browser
|
3225
|
+
debug_to_log("Chrome, in get_browser_version (#{@browserVersion})")
|
3226
|
+
end
|
3227
|
+
# if [notify_queue, notify_class, notify_id].all?
|
3228
|
+
# Resque::Job.create(notify_queue, notify_class, :id => notify_id, :browser_used => "#{@browserName} #{@browserVersion}")
|
3229
|
+
#end
|
3230
|
+
rescue
|
3231
|
+
debug_to_log("Unable to determine #{@browserAbbrev} browser version: '#{$!}' (#{__LINE__})")
|
3232
|
+
|
3233
|
+
# TODO: can we get rid of this?
|
3234
|
+
# js for getting firefox version information
|
3235
|
+
# function getAppID() {
|
3236
|
+
# var id;
|
3237
|
+
# if("@mozilla.org/xre/app-info;1" in Components.classes) {
|
3238
|
+
# // running under Mozilla 1.8 or later
|
3239
|
+
# id = Components.classes["@mozilla.org/xre/app-info;1"]
|
3240
|
+
# .getService(Components.interfaces.nsIXULAppInfo).ID;
|
3241
|
+
# } else {
|
3242
|
+
# try {
|
3243
|
+
# id = Components.classes["@mozilla.org/preferences-service;1"]
|
3244
|
+
# .getService(Components.interfaces.nsIPrefBranch)
|
3245
|
+
# .getCharPref("app.id");
|
3246
|
+
# } catch(e) {
|
3247
|
+
# // very old version
|
3248
|
+
# dump(e);
|
3249
|
+
# }
|
3250
|
+
# }
|
3251
|
+
# return id;
|
3252
|
+
# }
|
3253
|
+
# alert(getAppID());
|
3254
|
+
# another snippet that shows getting attributes from object
|
3255
|
+
# var info = Components.classes["@mozilla.org/xre/app-info;1"]
|
3256
|
+
# .getService(Components.interfaces.nsIXULAppInfo);
|
3257
|
+
# // Get the name of the application running us
|
3258
|
+
# info.name; // Returns "Firefox" for Firefox
|
3259
|
+
# info.version; // Returns "2.0.0.1" for Firefox version 2.0.0.1
|
3260
|
+
ensure
|
3261
|
+
message_to_log("Browser: [#{@browserAbbrev} #{@browserVersion}]")
|
3262
|
+
end
|
3263
|
+
|
3264
|
+
protected :get_browser_version
|
3265
|
+
|
3266
|
+
def fire_event(browser, element, how, what, event, desc = '')
|
3267
|
+
msg = "#{element.to_s.titlecase}: #{how}=>'#{what}' event:'#{event}'"
|
3268
|
+
msg1 = "#{element.to_s.titlecase}(#{how}, '#{what}')"
|
3269
|
+
begin
|
3270
|
+
case element
|
3271
|
+
when :link
|
3272
|
+
browser.link(how, what).fire_event(event)
|
3273
|
+
when :button
|
3274
|
+
browser.button(how, what).fire_event(event)
|
3275
|
+
when :image
|
3276
|
+
browser.image(how, what).fire_event(event)
|
3277
|
+
when :span
|
3278
|
+
browser.span(how, what).fire_event(event)
|
3279
|
+
when :div
|
3280
|
+
browser.div(how, what).fire_event(event)
|
3281
|
+
else
|
3282
|
+
browser.element(how, what).fire_event(event)
|
3283
|
+
end
|
3284
|
+
rescue => e
|
3285
|
+
if not rescue_me(e, __method__, "browser(#{msg1}).fire_event('#{event}')", "#{browser.class}")
|
3286
|
+
raise e
|
3287
|
+
end
|
3288
|
+
end
|
3289
|
+
if validate(browser, @myName, __LINE__)
|
3290
|
+
passed_to_log("Fire event: #{msg}. #{desc}")
|
3291
|
+
true
|
3292
|
+
end
|
3293
|
+
rescue
|
3294
|
+
failed_to_log("Unable to fire event: #{msg}. '#{$!}' #{desc}")
|
3295
|
+
end
|
3296
|
+
|
3297
|
+
def fire_event_on_link_by_text(browser, strg, event = 'onclick', desc = '')
|
3298
|
+
fire_event(browser, :link, :text, strg, event, desc)
|
3299
|
+
end
|
3300
|
+
|
3301
|
+
alias fire_event_text fire_event_on_link_by_text
|
3302
|
+
alias fire_event_by_text fire_event_on_link_by_text
|
3303
|
+
|
3304
|
+
def fire_event_on_link_by_id(browser, strg, event = 'onclick', desc = '')
|
3305
|
+
fire_event(browser, :link, :id, strg, event, desc)
|
3306
|
+
end
|
3307
|
+
|
3308
|
+
alias fire_event_id fire_event_on_link_by_id
|
3309
|
+
alias fire_event_by_id fire_event_on_link_by_id
|
3310
|
+
|
3311
|
+
def fire_event_on_image_by_src(browser, strg, event = 'onclick', desc = '')
|
3312
|
+
fire_event(browser, :img, :src, strg, event, desc)
|
3313
|
+
end
|
3314
|
+
|
3315
|
+
alias fire_event_src fire_event_on_image_by_src
|
3316
|
+
alias fire_event_image_by_src fire_event_on_image_by_src
|
3317
|
+
|
3318
|
+
def wait_until_exists(browser, element, how, what, desc = '')
|
3319
|
+
msg = "Wait until (#{element} :#{how}=>#{what}) exists."
|
3320
|
+
msg << " #{desc}" if desc.length > 0
|
3321
|
+
start = Time.now.to_f
|
3322
|
+
# TODO: try Watir::Wait.until { browser.element(how, what).exists? } instead of this (cumbersome) case statement
|
3323
|
+
# TODO: above fails on frame
|
3324
|
+
begin
|
3325
|
+
case element
|
3326
|
+
when :link
|
3327
|
+
Watir::Wait.until { browser.link(how, what).exists? }
|
3328
|
+
when :button
|
3329
|
+
Watir::Wait.until { browser.button(how, what).exists? }
|
3330
|
+
when :radio
|
3331
|
+
Watir::Wait.until { browser.radio(how, what).exists? }
|
3332
|
+
when :checkbox
|
3333
|
+
Watir::Wait.until { browser.checkbox(how, what).exists? }
|
3334
|
+
when :div
|
3335
|
+
Watir::Wait.until { browser.div(how, what).exists? }
|
3336
|
+
when :select_list
|
3337
|
+
Watir::Wait.until { browser.select_list(how, what).exists? }
|
3338
|
+
when :text_field
|
3339
|
+
Watir::Wait.until { browser.text_field(how, what).exists? }
|
3340
|
+
when :frame
|
3341
|
+
Watir::Wait.until { browser.frame(how, what).exists? }
|
3342
|
+
when :form
|
3343
|
+
Watir::Wait.until { browser.form(how, what).exists? }
|
3344
|
+
when :cell
|
3345
|
+
Watir::Wait.until { browser.cell(how, what).exists? }
|
3346
|
+
when :image
|
3347
|
+
Watir::Wait.until { browser.image(how, what).exists? }
|
3348
|
+
else
|
3349
|
+
Watir::Wait.until { browser.element(how, what).exists? }
|
3350
|
+
end
|
3351
|
+
rescue => e
|
3352
|
+
if e.class.to_s =~ /TimeOutException/
|
3353
|
+
failed_to_log("#{msg}: '#{$!}'")
|
3354
|
+
return false
|
3355
|
+
elsif not rescue_me(e, __method__, "#{block.to_s}", "#{browser.class}")
|
3356
|
+
raise e
|
3357
|
+
end
|
3358
|
+
end
|
3359
|
+
stop = Time.now.to_f
|
3360
|
+
#debug_to_log("#{__method__}: start:#{start} stop:#{stop}")
|
3361
|
+
# sleep 1
|
3362
|
+
if validate(browser, @myName, __LINE__)
|
3363
|
+
passed_to_log("#{msg} (#{stop - start} seconds)")
|
3364
|
+
true
|
3365
|
+
end
|
3366
|
+
rescue
|
3367
|
+
failed_to_log("Unable to complete #{msg}: '#{$!}'")
|
3368
|
+
end
|
3369
|
+
|
3370
|
+
#TODO: Would like to be able to see the block code in the log message instead of the identification
|
3371
|
+
def wait_while(browser, desc, timeout = 45, &block)
|
3372
|
+
msg = "Wait while #{desc}:"
|
3373
|
+
start = Time.now.to_f
|
3374
|
+
begin
|
3375
|
+
#Watir::Wait.until(timeout) { block.call(nil) }
|
3376
|
+
if block.call(nil)
|
3377
|
+
Watir::Wait.while(timeout) { block.call(nil) }
|
3378
|
+
end
|
3379
|
+
rescue => e
|
3380
|
+
if e.class.to_s =~ /TimeOutException/ or e.message =~ /timed out/
|
3381
|
+
failed_to_log("#{msg}: '#{$!}' ")
|
3382
|
+
return false
|
3383
|
+
elsif not rescue_me(e, __method__, "#{block.to_s}", "#{browser.class}")
|
3384
|
+
raise e
|
3385
|
+
end
|
3386
|
+
end
|
3387
|
+
stop = Time.now.to_f
|
3388
|
+
#debug_to_log("#{__method__}: start:#{start} stop:#{stop} block: #{block.to_s}")
|
3389
|
+
# sleep 1
|
3390
|
+
if validate(browser, @myName, __LINE__)
|
3391
|
+
passed_to_log("#{msg} (#{"%.5f" % (stop - start)} seconds)") # {#{block.to_s}}")
|
3392
|
+
true
|
3393
|
+
end
|
3394
|
+
rescue
|
3395
|
+
failed_to_log("Unable to complete #{msg}. '#{$!}'")
|
3396
|
+
end
|
3397
|
+
|
3398
|
+
alias wait_while_true wait_while
|
3399
|
+
|
3400
|
+
#TODO: Would like to be able to see the block code in the log message instead of the identification
|
3401
|
+
def wait_until(browser, desc, timeout = 45, skip_pass = false, &block)
|
3402
|
+
msg = "Wait until #{desc}"
|
3403
|
+
start = Time.now.to_f
|
3404
|
+
begin
|
3405
|
+
Watir::Wait.until(timeout) { block.call(nil) }
|
3406
|
+
rescue => e
|
3407
|
+
if e.class.to_s =~ /TimeOutException/ or e.message =~ /timed out/
|
3408
|
+
failed_to_log("#{msg} '#{$!}'")
|
3409
|
+
return false
|
3410
|
+
elsif not rescue_me(e, __method__, "#{block.to_s}", "#{browser.class}")
|
3411
|
+
raise e
|
3412
|
+
end
|
3413
|
+
end
|
3414
|
+
stop = Time.now.to_f
|
3415
|
+
#debug_to_log("#{__method__}: start:#{start} stop:#{stop} block: #{block.to_s}")
|
3416
|
+
# sleep 1
|
3417
|
+
if validate(browser, @myName, __LINE__)
|
3418
|
+
passed_to_log("#{msg} (#{"%.5f" % (stop - start)} seconds)") unless skip_pass # {#{block.to_s}}")
|
3419
|
+
true
|
3420
|
+
end
|
3421
|
+
rescue
|
3422
|
+
failed_to_log("Unable to complete #{msg} '#{$!}'")
|
3423
|
+
end
|
3424
|
+
|
3425
|
+
alias wait_until_true wait_until
|
3426
|
+
|
3427
|
+
def wait_until_by_radio_value(browser, strg, desc = '')
|
3428
|
+
wait_until_exists(browser, :radio, :value, strg, desc)
|
3429
|
+
end
|
3430
|
+
|
3431
|
+
def wait_until_ready(browser, how, what, desc = '', timeout = 90, verbose = false)
|
3432
|
+
msg = "#{__method__.to_s.titleize}: element: #{how}='#{what}'"
|
3433
|
+
msg << " #{desc}" if desc.length > 0
|
3434
|
+
proc_exists = Proc.new { browser.element(how, what).exists? }
|
3435
|
+
proc_enabled = Proc.new { browser.element(how, what).enabled? }
|
3436
|
+
case how
|
3437
|
+
when :href
|
3438
|
+
proc_exists = Proc.new { browser.link(how, what).exists? }
|
3439
|
+
proc_enabled = Proc.new { browser.link(how, what).enabled? }
|
3440
|
+
end
|
3441
|
+
if verbose
|
3442
|
+
if wait_until(browser, "#{msg} Element exists.", timeout) { proc_exists.call(nil) }
|
3443
|
+
if wait_until(browser, "#{msg} Element enabled.", timeout) { proc_enabled.call(nil) }
|
3444
|
+
passed_to_log(msg)
|
3445
|
+
true
|
3446
|
+
else
|
3447
|
+
failed_to_log(msg)
|
3448
|
+
end
|
3449
|
+
else
|
3450
|
+
failed_to_log(msg)
|
3451
|
+
end
|
3452
|
+
else
|
3453
|
+
start = Time.now.to_f
|
3454
|
+
if Watir::Wait.until(timeout) { proc_exists.call(nil) }
|
3455
|
+
if Watir::Wait.until(timeout) { proc_enabled.call(nil) }
|
3456
|
+
stop = Time.now.to_f
|
3457
|
+
#debug_to_log("#{__method__}: start:#{"%.5f" % start} stop:#{"%.5f" % stop}")
|
3458
|
+
passed_to_log("#{msg} (#{"%.5f" % (stop - start)} seconds)")
|
3459
|
+
true
|
3460
|
+
else
|
3461
|
+
failed_to_log(msg)
|
3462
|
+
end
|
3463
|
+
else
|
3464
|
+
failed_to_log(msg)
|
3465
|
+
end
|
3466
|
+
end
|
3467
|
+
rescue
|
3468
|
+
failed_to_log("Unable to #{msg}. '#{$!}'")
|
3469
|
+
end
|
3470
|
+
|
3471
|
+
def wait_until_ready_quiet(browser, how, what, desc = '', timeout = 45, quiet = true)
|
3472
|
+
msg = "#{__method__.to_s.titleize}: element: #{how}='#{what}'"
|
3473
|
+
msg << " #{desc}" if desc.length > 0
|
3474
|
+
proc_exists = Proc.new { browser.element(how, what).exists? }
|
3475
|
+
proc_enabled = Proc.new { browser.element(how, what).enabled? }
|
3476
|
+
case how
|
3477
|
+
when :href
|
3478
|
+
proc_exists = Proc.new { browser.link(how, what).exists? }
|
3479
|
+
proc_enabled = Proc.new { browser.link(how, what).enabled? }
|
3480
|
+
end
|
3481
|
+
start = Time.now.to_f
|
3482
|
+
if Watir::Wait.until(timeout) { proc_exists.call(nil) }
|
3483
|
+
if Watir::Wait.until(timeout) { proc_enabled.call(nil) }
|
3484
|
+
stop = Time.now.to_f
|
3485
|
+
#debug_to_log("#{msg}: start:#{"%.5f" % start} stop:#{"%.5f" % stop}")
|
3486
|
+
passed_to_log("#{msg} (#{"%.5f" % (stop - start)} seconds)") unless quiet
|
3487
|
+
true
|
3488
|
+
else
|
3489
|
+
failed_to_log(msg)
|
3490
|
+
end
|
3491
|
+
else
|
3492
|
+
failed_to_log(msg)
|
3493
|
+
end
|
3494
|
+
rescue
|
3495
|
+
failed_to_log("Unable to #{msg}. '#{$!}'")
|
3496
|
+
end
|
3497
|
+
|
3498
|
+
def wait_until_text(browser, strg, desc = '', timeout = 60)
|
3499
|
+
if not strg.class.to_s.match('String')
|
3500
|
+
raise "#{__method__} requires String for search target. #{strg.class} is not supported."
|
3501
|
+
end
|
3502
|
+
wait_until(browser, "'#{strg}' #{desc}", timeout) { browser.text.include? strg }
|
3503
|
+
end
|
3504
|
+
|
3505
|
+
alias wait_until_by_text wait_until_text
|
3506
|
+
|
3507
|
+
def wait_until_by_link_text(browser, strg, desc = '')
|
3508
|
+
wait_until_exists(browser, :link, :text, strg, desc)
|
3509
|
+
end
|
3510
|
+
|
3511
|
+
def wait_until_enabled(browser, what, how, value, desc = '')
|
3512
|
+
start = Time.now.to_f
|
3513
|
+
begin
|
3514
|
+
case what
|
3515
|
+
when :link
|
3516
|
+
Watir::Wait.until { browser.link(how, value).enabled? }
|
3517
|
+
when :button
|
3518
|
+
Watir::Wait.until { browser.button(how, value).enabled? }
|
3519
|
+
when :radio
|
3520
|
+
Watir::Wait.until { browser.radio(how, value).enabled? }
|
3521
|
+
when :checkbox
|
3522
|
+
Watir::Wait.until { browser.checkbox(how, value).enabled? }
|
3523
|
+
when :div
|
3524
|
+
Watir::Wait.until { browser.div(how, value).enabled? }
|
3525
|
+
when :select_list
|
3526
|
+
Watir::Wait.until { browser.select_list(how, value).enabled? }
|
3527
|
+
when :text_field
|
3528
|
+
Watir::Wait.until { browser.text_field(how, value).enabled? }
|
3529
|
+
when :table
|
3530
|
+
Watir::Wait.until { browser.table(how, value).enabled? }
|
3531
|
+
else
|
3532
|
+
raise "#{__method__}: Element #{what} not supported."
|
3533
|
+
end
|
3534
|
+
rescue => e
|
3535
|
+
if e.class.to_s =~ /TimeOutException/
|
3536
|
+
failed_to_log("Wait until (#{what} :#{how}=>#{value}) enabled. #{desc}: '#{$!}' #{desc}")
|
3537
|
+
return false
|
3538
|
+
elsif not rescue_me(e, __method__, "#{block.to_s}", "#{browser.class}")
|
3539
|
+
raise e
|
3540
|
+
end
|
3541
|
+
end
|
3542
|
+
stop = Time.now.to_f
|
3543
|
+
#debug_to_log("#{__method__}: start:#{start} stop:#{stop}")
|
3544
|
+
# sleep 1
|
3545
|
+
if validate(browser, @myName, __LINE__)
|
3546
|
+
passed_to_log("Wait until (#{what} :#{how}=>#{value}) enabled. #{desc} (#{stop - start} seconds)")
|
3547
|
+
true
|
3548
|
+
end
|
3549
|
+
rescue
|
3550
|
+
failed_to_log("Unable to complete wait until (#{what} :#{how}=>#{value}) enabled. #{desc}: '#{$!}'")
|
3551
|
+
end
|
3552
|
+
|
3553
|
+
def wait_until_visible(browser, element, how, what, desc = '')
|
3554
|
+
start = Time.now.to_f
|
3555
|
+
Watir::Wait.until(20) { browser.element(how, what).exists? }
|
3556
|
+
begin
|
3557
|
+
case element
|
3558
|
+
when :link
|
3559
|
+
Watir::Wait.until { browser.link(how, what).visible? }
|
3560
|
+
when :button
|
3561
|
+
Watir::Wait.until { browser.button(how, what).visible? }
|
3562
|
+
when :radio
|
3563
|
+
Watir::Wait.until { browser.radio(how, what).visible? }
|
3564
|
+
when :checkbox
|
3565
|
+
Watir::Wait.until { browser.checkbox(how, what).visible? }
|
3566
|
+
when :div
|
3567
|
+
Watir::Wait.until { browser.div(how, what).visible? }
|
3568
|
+
when :select_list
|
3569
|
+
Watir::Wait.until { browser.select_list(how, what).visible? }
|
3570
|
+
when :text_field
|
3571
|
+
Watir::Wait.until { browser.text_field(how, what).visible? }
|
3572
|
+
else
|
3573
|
+
Watir::Wait.until { browser.element(how, what).visible? }
|
3574
|
+
# raise "#{__method__}: Element #{what} not supported."
|
3575
|
+
end
|
3576
|
+
rescue => e
|
3577
|
+
if e.class.to_s =~ /TimeOutException/
|
3578
|
+
failed_to_log("Wait until (#{what} :#{how}=>#{what}) visible. #{desc}: '#{$!}' #{desc}")
|
3579
|
+
return false
|
3580
|
+
elsif not rescue_me(e, __method__, '', "#{browser.class}")
|
3581
|
+
raise e
|
3582
|
+
end
|
3583
|
+
end
|
3584
|
+
stop = Time.now.to_f
|
3585
|
+
#debug_to_log("#{__method__}: start:#{start} stop:#{stop}")
|
3586
|
+
# sleep 1
|
3587
|
+
if validate(browser, @myName, __LINE__)
|
3588
|
+
passed_to_log("Wait until (#{element} :#{how}=>#{what}) visible. #{desc} (#{stop - start} seconds)")
|
3589
|
+
true
|
3590
|
+
end
|
3591
|
+
rescue
|
3592
|
+
failed_to_log("Unable to complete wait until (#{element} :#{how}=>#{what}) visible. #{desc}: '#{$!}'")
|
3593
|
+
end
|
3594
|
+
|
3595
|
+
def rescue_me(e, me = nil, what = nil, where = nil, who = nil)
|
3596
|
+
#TODO: these are rescues from exceptions raised in Watir/Firewatir
|
3597
|
+
debug_to_log("#{__method__}: Enter")
|
3598
|
+
ok = false
|
3599
|
+
begin
|
3600
|
+
gaak = who.inspect
|
3601
|
+
located = gaak =~ /located=true/i
|
3602
|
+
rescue
|
3603
|
+
debug_to_log("#{__method__}: gaak: '#{gaak}'")
|
3604
|
+
end
|
3605
|
+
msg = e.message
|
3606
|
+
debug_to_log("#{__method__}: msg = #{msg}")
|
3607
|
+
if msg =~ /undefined method\s+.join.\s+for/i # firewatir to_s implementation error
|
3608
|
+
ok = true
|
3609
|
+
elsif msg =~ /undefined method\s+.match.\s+for.+WIN32OLERuntimeError/i # watir and firewatir
|
3610
|
+
ok = true
|
3611
|
+
elsif msg =~ /undefined method\s+.match.\s+for.+UnknownObjectException/i # watir
|
3612
|
+
ok = true
|
3613
|
+
elsif msg =~ /window\.getBrowser is not a function/i # firewatir
|
3614
|
+
ok = true
|
3615
|
+
elsif msg =~ /WIN32OLERuntimeError/i # watir
|
3616
|
+
ok = true
|
3617
|
+
elsif msg =~ /undefined method\s+.match.\s+for/i # watir
|
3618
|
+
ok = true
|
3619
|
+
elsif msg =~ /wrong number of arguments \(1 for 0\)/i
|
3620
|
+
ok = true
|
3621
|
+
elsif (msg =~ /unable to locate element/i)
|
3622
|
+
if located
|
3623
|
+
ok = true
|
3624
|
+
elsif where == 'Watir::Div'
|
3625
|
+
ok = true
|
3626
|
+
end
|
3627
|
+
elsif (msg =~ /HRESULT error code:0x80070005/)
|
3628
|
+
ok = true
|
3629
|
+
#elsif msg =~ /missing\s+\;\s+before statement/
|
3630
|
+
# ok = true
|
3631
|
+
end
|
3632
|
+
if ok
|
3633
|
+
debug_to_log("#{__method__}: RESCUED: \n#{who.to_yaml}=> #{what} in #{me}()\n=> '#{$!}'")
|
3634
|
+
debug_to_log("#{__method__}: #{who.inspect}") if who
|
3635
|
+
debug_to_log("#{__method__}: #{where.inspect}")
|
3636
|
+
debug_to_log("#{__method__}: #{get_callers(6, true)}")
|
3637
|
+
else
|
3638
|
+
debug_to_log("#{__method__}: NO RESCUE: #{e.message}")
|
3639
|
+
debug_to_log("#{__method__}: NO RESCUE: \n#{get_callers(6, true)}")
|
3640
|
+
end
|
3641
|
+
debug_to_log("#{__method__}: Exit")
|
3642
|
+
ok
|
3643
|
+
end
|
3644
|
+
|
3645
|
+
def close_popup_by_button_title(popup, strg, desc = '')
|
3646
|
+
click(popup, :link, :title, strg, desc)
|
3647
|
+
end
|
3648
|
+
|
3649
|
+
def move_element_with_handle(browser, element, handle_id, dx, dy)
|
3650
|
+
# msg = "Move element "
|
3651
|
+
# w1, h1, x1, y1, xc1, yc1, xlr1, ylr1 = get_element_coordinates(browser, element, true)
|
3652
|
+
# newx = w1 + dx
|
3653
|
+
# newy = h1 + dy
|
3654
|
+
# msg << " by [#{dx}, #{dy}] to expected [[#{newx}, #{newy}] "
|
3655
|
+
# handle = get_resize_handle(element, handle_id)
|
3656
|
+
# hw, hh, hx, hy, hxc, hyc, hxlr, hylr = get_element_coordinates(browser, handle, true)
|
3657
|
+
|
3658
|
+
# drag_and_drop(hxc, hyc, dx, dy)
|
3659
|
+
|
3660
|
+
# w2, h2, x2, y2, xc2, yc2, xlr2, ylr2 = get_element_coordinates(browser, element, true)
|
3661
|
+
|
3662
|
+
# xerr = x2 - newx
|
3663
|
+
# yerr = y2 - newy
|
3664
|
+
# xdsp = (x1 - x2).abs
|
3665
|
+
# ydsp = (y1 - y2).abs
|
3666
|
+
|
3667
|
+
# if x2 == newx and y2 == newy
|
3668
|
+
# msg << "succeeded."
|
3669
|
+
# passed_to_log(msg)
|
3670
|
+
# else
|
3671
|
+
# msg << "failed. "
|
3672
|
+
# failed_to_log(msg)
|
3673
|
+
# debug_to_log("x: actual #{x2}, error #{xerr}, displace #{xdsp}. y: actual #{y2}, error #{yerr}, displace #{ydsp}.")
|
3674
|
+
# end
|
3675
|
+
|
3676
|
+
end
|
3677
|
+
|
3678
|
+
#TODO enhance to accept differing percentages in each direction
|
3679
|
+
def resize_element_with_handle(browser, element, target, dx, dy=nil)
|
3680
|
+
msg = "Resize element "
|
3681
|
+
w1, h1, x1, y1, xc1, yc1, xlr1, ylr1 = get_element_coordinates(browser, element, true)
|
3682
|
+
if dy
|
3683
|
+
deltax = dx
|
3684
|
+
deltay = dy
|
3685
|
+
neww = w1 + dx
|
3686
|
+
newh = h1 + dy
|
3687
|
+
msg << " by [#{dx}, #{dy}] " #"" to expected dimension [#{neww}, #{newh}] "
|
3688
|
+
else
|
3689
|
+
deltax, deltay, neww, newh = adjust_dimensions_by_percent(w1, h1, dx, true)
|
3690
|
+
msg << "by #{dx} percent " #"" to expected dimension [#{neww}, #{newh}] "
|
3691
|
+
end
|
3692
|
+
handle = get_resize_handle_by_class(element, target) #, true)
|
3693
|
+
sleep_for(0.5)
|
3694
|
+
hw, hh, hx, hy, hxc, hyc, hxlr, hylr = get_element_coordinates(browser, handle, true)
|
3695
|
+
hxlr_diff = 0
|
3696
|
+
hylr_diff = 0
|
3697
|
+
|
3698
|
+
# TODO These adjustments are adhoc and empirical. Need to be derived more rigorously
|
3699
|
+
if @browserAbbrev == 'IE'
|
3700
|
+
hxlr_diff = (xlr1 - hxlr)
|
3701
|
+
hylr_diff = (ylr1 - hylr)
|
3702
|
+
x_start = hxlr - 2
|
3703
|
+
y_start = hylr - 2
|
3704
|
+
else
|
3705
|
+
hxlr_diff = (xlr1 - hxlr) / 2 unless (xlr1 - hxlr) == 0
|
3706
|
+
hylr_diff = (ylr1 - hylr) / 2 unless (ylr1 - hylr) == 0
|
3707
|
+
x_start = hxlr
|
3708
|
+
y_start = hylr
|
3709
|
+
end
|
3710
|
+
|
3711
|
+
newxlr = xlr1 + deltax
|
3712
|
+
newylr = ylr1 + deltay
|
3713
|
+
# msg << ", lower right [#{newxlr}, #{newylr}] - "
|
3714
|
+
sleep_for(0.5)
|
3715
|
+
|
3716
|
+
drag_and_drop(x_start, y_start, deltax, deltay)
|
3717
|
+
|
3718
|
+
sleep_for(1.5)
|
3719
|
+
w2, h2, x2, y2, xc2, yc2, xlr2, ylr2 = get_element_coordinates(browser, element, true)
|
3720
|
+
|
3721
|
+
werr = w2 - neww
|
3722
|
+
herr = h2 - newh
|
3723
|
+
|
3724
|
+
# TODO This adjustment is adhoc and empirical. Needs to be derived more rigorously
|
3725
|
+
xlrerr = xlr2 - newxlr + hxlr_diff
|
3726
|
+
ylrerr = ylr2 - newylr + hylr_diff
|
3727
|
+
|
3728
|
+
xlrdsp = (xlr1 - xlr2).abs
|
3729
|
+
ylrdsp = (ylr1 - ylr2).abs
|
3730
|
+
|
3731
|
+
debug_to_log("\n" +
|
3732
|
+
"\t\t hxlr_diff: #{hxlr_diff}\n" +
|
3733
|
+
"\t\t hylr_diff: #{hylr_diff}\n" +
|
3734
|
+
"\t\t werr: #{werr}\n" +
|
3735
|
+
"\t\t herr: #{herr}\n" +
|
3736
|
+
"\t\t xlrerr: #{xlrerr}\n" +
|
3737
|
+
"\t\t ylrerr: #{ylrerr}\n" +
|
3738
|
+
"\t\t xlrdsp: #{xlrdsp}\n" +
|
3739
|
+
"\t\t ylrdsp: #{ylrdsp}\n" +
|
3740
|
+
"\t\t @min_width: #{@min_width}\n" +
|
3741
|
+
"\t\t@min_height: #{@min_height}\n" +
|
3742
|
+
"\t\t x tol: #{@x_tolerance}\n" +
|
3743
|
+
"\t\t y tol: #{@y_tolerance}\n"
|
3744
|
+
)
|
3745
|
+
|
3746
|
+
#TODO Add check that window _was_ resized.
|
3747
|
+
x_ok, x_msg = validate_move(w2, xlrerr, @x_tolerance, @min_width, xlr2)
|
3748
|
+
y_ok, y_msg = validate_move(h2, ylrerr, @y_tolerance, @min_height, ylr2)
|
3749
|
+
msg = msg + "x: #{x_msg}, y: #{y_msg}"
|
3750
|
+
|
3751
|
+
if x_ok and y_ok
|
3752
|
+
passed_to_log(msg)
|
3753
|
+
else
|
3754
|
+
failed_to_log(msg)
|
3755
|
+
debug_to_log("x - actual #{xlr2}, error #{xlrerr}, displace #{xlrdsp}, y - actual #{ylr2}, error #{ylrerr}, displace #{ylrdsp}.")
|
3756
|
+
end
|
3757
|
+
sleep_for(1)
|
3758
|
+
rescue
|
3759
|
+
failed_to_log("Unable to validate resize. #{$!} (#{__LINE__})")
|
3760
|
+
sleep_for(1)
|
3761
|
+
end
|
3762
|
+
|
3763
|
+
def get_resize_handle_by_id(element, id, dbg=nil)
|
3764
|
+
handle = get_div_by_id(element, id, dbg)
|
3765
|
+
sleep_for(1)
|
3766
|
+
handle.flash(5)
|
3767
|
+
return handle
|
3768
|
+
end
|
3769
|
+
|
3770
|
+
def get_resize_handle_by_class(element, strg, dbg=nil)
|
3771
|
+
handle = get_div_by_class(element, strg, dbg)
|
3772
|
+
sleep_for(0.5)
|
3773
|
+
handle.flash(5)
|
3774
|
+
return handle
|
3775
|
+
end
|
3776
|
+
|
3777
|
+
def get_element_coordinates(browser, element, dbg=nil)
|
3778
|
+
bx, by, bw, bh = get_browser_coord(browser, dbg)
|
3779
|
+
if @browserAbbrev == 'IE'
|
3780
|
+
x_hack = @horizontal_hack_ie
|
3781
|
+
y_hack = @vertical_hack_ie
|
3782
|
+
elsif @browserAbbrev == 'FF'
|
3783
|
+
x_hack = @horizontal_hack_ff
|
3784
|
+
y_hack = @vertical_hack_ff
|
3785
|
+
end
|
3786
|
+
sleep_for(1)
|
3787
|
+
w, h = element.dimensions.to_a
|
3788
|
+
xc, yc = element.client_offset.to_a
|
3789
|
+
# xcc, ycc = element.client_center.to_a
|
3790
|
+
xcc = xc + w/2
|
3791
|
+
ycc = yc + h/2
|
3792
|
+
# screen offset:
|
3793
|
+
xs = bx + x_hack + xc - 1
|
3794
|
+
ys = by + y_hack + yc - 1
|
3795
|
+
# screen center:
|
3796
|
+
xsc = xs + w/2
|
3797
|
+
ysc = ys + h/2
|
3798
|
+
xslr = xs + w
|
3799
|
+
yslr = ys + h
|
3800
|
+
if dbg
|
3801
|
+
debug_to_log(
|
3802
|
+
"\n\t\tElement: #{element.inspect}"+
|
3803
|
+
"\n\t\tbrowser screen offset: x: #{bx} y: #{by}"+
|
3804
|
+
"\n\t\t dimensions: x: #{w} y: #{h}"+
|
3805
|
+
"\n\t\t client offset x: #{xc} y: #{yc}"+
|
3806
|
+
"\n\t\t screen offset x: #{xs} y: #{ys}"+
|
3807
|
+
"\n\t\t client center x: #{xcc} y: #{ycc}"+
|
3808
|
+
"\n\t\t screen center x: #{xsc} y: #{ysc}"+
|
3809
|
+
"\n\t\t screen lower right x: #{xslr} y: #{yslr}")
|
3810
|
+
end
|
3811
|
+
[w, h, xs, ys, xsc, ysc, xslr, yslr]
|
3812
|
+
end
|
3813
|
+
|
3814
|
+
def get_element(browser, element, how, what, value = nil)
|
3815
|
+
target = nil
|
3816
|
+
what = Regexp.new(Regexp.escape(what)) unless how == :index or what.is_a?(Regexp)
|
3817
|
+
case element
|
3818
|
+
when :link
|
3819
|
+
target = browser.link(how, what)
|
3820
|
+
when :button
|
3821
|
+
target = browser.button(how, what)
|
3822
|
+
when :div
|
3823
|
+
target = browser.div(how, what)
|
3824
|
+
when :checkbox
|
3825
|
+
target = browser.checkbox(how, what, value)
|
3826
|
+
when :text_field, :textfield
|
3827
|
+
target = browser.text_field(how, what)
|
3828
|
+
when :image
|
3829
|
+
target = browser.image(how, what)
|
3830
|
+
when :file_field, :filefield
|
3831
|
+
target = browser.file_field(how, what)
|
3832
|
+
when :form
|
3833
|
+
target = browser.form(how, what)
|
3834
|
+
when :frame
|
3835
|
+
target = browser.frame(how, what)
|
3836
|
+
when :radio
|
3837
|
+
target = browser.radio(how, what, value)
|
3838
|
+
when :span
|
3839
|
+
target = browser.span(how, what)
|
3840
|
+
when :table
|
3841
|
+
target = browser.table(how, what)
|
3842
|
+
when :li
|
3843
|
+
target = browser.li(how, what)
|
3844
|
+
when :select_list, :selectlist
|
3845
|
+
target = browser.select_list(how, what)
|
3846
|
+
when :hidden
|
3847
|
+
target = browser.hidden(how, what)
|
3848
|
+
when :area
|
3849
|
+
target = browser.area(how, what)
|
3850
|
+
end
|
3851
|
+
if target.exists?
|
3852
|
+
target
|
3853
|
+
else
|
3854
|
+
nil
|
3855
|
+
end
|
3856
|
+
rescue => e
|
3857
|
+
if not rescue_me(e, __method__, "browser.#{element}(#{how}, '#{what}')", "#{browser.class}", target)
|
3858
|
+
raise e
|
3859
|
+
end
|
3860
|
+
end
|
3861
|
+
|
3862
|
+
def get_element_text(browser, element, how, what, desc = '')
|
3863
|
+
msg = "Return text in #{element} #{how}='#{what}'"
|
3864
|
+
msg << " #{desc}" if desc.length > 0
|
3865
|
+
text = browser.element(how, what).text
|
3866
|
+
if validate(browser, @myName, __LINE__)
|
3867
|
+
passed_to_log("#{msg} text='#{text}'")
|
3868
|
+
text
|
3869
|
+
end
|
3870
|
+
rescue
|
3871
|
+
failed_to_log("Unable to #{msg}: '#{$!}'")
|
3872
|
+
end
|
3873
|
+
|
3874
|
+
def adjust_dimensions_by_percent(w, h, p, returnnew=nil)
|
3875
|
+
p += 100
|
3876
|
+
nw = (w * (p/100.0)).to_i
|
3877
|
+
nh = (h * (p/100.0)).to_i
|
3878
|
+
deltaw = nw - w
|
3879
|
+
deltah = nh - h
|
3880
|
+
if returnnew
|
3881
|
+
[deltaw, deltah, nw, nh]
|
3882
|
+
else
|
3883
|
+
[deltaw, deltah]
|
3884
|
+
end
|
3885
|
+
end
|
3886
|
+
|
3887
|
+
def get_browser_coord(browser=nil, dbg=nil)
|
3888
|
+
browser = @myBrowser if not browser
|
3889
|
+
title = browser.title
|
3890
|
+
x = @ai.WinGetPosX(title)
|
3891
|
+
y = @ai.WinGetPosY(title)
|
3892
|
+
w = @ai.WinGetPosWidth(title)
|
3893
|
+
h = @ai.WinGetPosHeight(title)
|
3894
|
+
if dbg
|
3895
|
+
debug_to_log("\n\t\tBrowser #{browser.inspect}\n"+
|
3896
|
+
"\t\tdimensions: x: #{w} y: #{h}"+
|
3897
|
+
"\t\tscreen offset x: #{x} y: #{y}")
|
3898
|
+
end
|
3899
|
+
[x, y, w, h]
|
3900
|
+
end
|
3901
|
+
|
3902
|
+
def get_index_for_column_head(panel, table_index, strg)
|
3903
|
+
rgx = Regexp.new(strg)
|
3904
|
+
panel.tables[table_index].each do |row|
|
3905
|
+
if row.text =~ rgx
|
3906
|
+
index = 1
|
3907
|
+
row.each do |cell|
|
3908
|
+
if cell.text =~ rgx
|
3909
|
+
return index
|
3910
|
+
end
|
3911
|
+
index += 1
|
3912
|
+
end
|
3913
|
+
end
|
3914
|
+
end
|
3915
|
+
end
|
3916
|
+
|
3917
|
+
def get_index_of_last_row(table, pad = 2, every = 1)
|
3918
|
+
index = calc_index(table.row_count, every)
|
3919
|
+
index = index.to_s.rjust(pad, '0')
|
3920
|
+
#debug_to_log("#{__method__}: index='#{index}' row_count=#{table.row_count} pad=#{pad} every=#{every}")
|
3921
|
+
index
|
3922
|
+
end
|
3923
|
+
|
3924
|
+
alias get_index_for_last_row get_index_of_last_row
|
3925
|
+
|
3926
|
+
def get_index_of_last_row_with_text(table, strg, column_index = nil)
|
3927
|
+
debug_to_log("#{__method__}: #{get_callers(5)}")
|
3928
|
+
msg = "Find last row in table :id=#{table.id} with text '#{strg}'"
|
3929
|
+
msg << " in column #{column_index}" if column_index
|
3930
|
+
dbg = "#{__method__}: #{table.id} text by row "
|
3931
|
+
dbg << "in column #{column_index}" if column_index
|
3932
|
+
index = 0
|
3933
|
+
found = false
|
3934
|
+
at_index = 0
|
3935
|
+
#row_count = table.row_count
|
3936
|
+
table.rows.each do |row|
|
3937
|
+
cell_count = get_cell_count(row)
|
3938
|
+
index += 1
|
3939
|
+
text = ''
|
3940
|
+
if column_index
|
3941
|
+
col_idx = column_index.to_i
|
3942
|
+
if cell_count >= col_idx
|
3943
|
+
text = row[col_idx].text
|
3944
|
+
end
|
3945
|
+
else
|
3946
|
+
text = row.text
|
3947
|
+
end
|
3948
|
+
dbg << "\n#{index}. [#{text}]"
|
3949
|
+
if text =~ /#{strg}/
|
3950
|
+
found = true
|
3951
|
+
at_index = index
|
3952
|
+
end
|
3953
|
+
end
|
3954
|
+
debug_to_log(dbg)
|
3955
|
+
if found
|
3956
|
+
passed_to_log("#{msg} at index #{index}.")
|
3957
|
+
at_index
|
3958
|
+
else
|
3959
|
+
failed_to_log("#{msg}")
|
3960
|
+
nil
|
3961
|
+
end
|
3962
|
+
rescue
|
3963
|
+
failed_to_log("Unable to #{msg}. '#{$!}'")
|
3964
|
+
end
|
3965
|
+
|
3966
|
+
alias get_index_for_last_row_with_text get_index_of_last_row_with_text
|
3967
|
+
|
3968
|
+
def get_index_of_row_with_text(table, strg, column_index = nil, fail_if_found = false)
|
3969
|
+
debug_to_log("#{__method__}: #{get_callers(5)}")
|
3970
|
+
if fail_if_found
|
3971
|
+
msg = 'No '
|
3972
|
+
else
|
3973
|
+
msg = 'Find '
|
3974
|
+
end
|
3975
|
+
msg << "row in table :id=#{table.id} with text '#{strg}'"
|
3976
|
+
msg << " in column #{column_index}" if column_index
|
3977
|
+
dbg = "#{__method__}: #{table.id} text by row "
|
3978
|
+
dbg << "in column #{column_index}" if column_index
|
3979
|
+
index = 0
|
3980
|
+
found = false
|
3981
|
+
table.rows.each do |row|
|
3982
|
+
cell_count = row.cells.length
|
3983
|
+
index += 1
|
3984
|
+
text = ''
|
3985
|
+
if column_index
|
3986
|
+
col_idx = column_index.to_i
|
3987
|
+
if cell_count >= col_idx
|
3988
|
+
text = row[col_idx].text
|
3989
|
+
end
|
3990
|
+
else
|
3991
|
+
text = row.text
|
3992
|
+
end
|
3993
|
+
dbg << "\n#{index}. [#{text}]"
|
3994
|
+
if text =~ /#{strg}/
|
3995
|
+
found = true
|
3996
|
+
break
|
3997
|
+
end
|
3998
|
+
end
|
3999
|
+
debug_to_log(dbg)
|
4000
|
+
if found
|
4001
|
+
if fail_if_found
|
4002
|
+
failed_to_log("#{msg} at index #{index}.")
|
4003
|
+
else
|
4004
|
+
passed_to_log("#{msg} at index #{index}.")
|
4005
|
+
end
|
4006
|
+
index
|
4007
|
+
else
|
4008
|
+
if fail_if_found
|
4009
|
+
passed_to_log("#{msg}")
|
4010
|
+
else
|
4011
|
+
failed_to_log("#{msg}")
|
4012
|
+
end
|
4013
|
+
nil
|
4014
|
+
end
|
4015
|
+
rescue
|
4016
|
+
failed_to_log("Unable to #{msg}. '#{$!}'")
|
4017
|
+
end
|
4018
|
+
|
4019
|
+
def get_index_of_row_with_textfield_value(table, strg, how, what, column_index = nil)
|
4020
|
+
msg = "Find row in table :id=#{table.id} with value '#{strg}' in text_field #{how}=>'#{what} "
|
4021
|
+
msg << " in column #{column_index}" if column_index
|
4022
|
+
index = 0
|
4023
|
+
found = false
|
4024
|
+
table.rows.each do |row|
|
4025
|
+
cell_count = get_cell_count(row)
|
4026
|
+
index += 1
|
4027
|
+
text = ''
|
4028
|
+
if column_index
|
4029
|
+
col_idx = column_index.to_i
|
4030
|
+
if cell_count >= col_idx
|
4031
|
+
if row[col_idx].text_field(how, what).exists?
|
4032
|
+
value = row[col_idx].text_field(how, what).value
|
4033
|
+
end
|
4034
|
+
end
|
4035
|
+
else
|
4036
|
+
if row.text_field(how, what).exists?
|
4037
|
+
value = row.text_field(how, what).value
|
4038
|
+
sleep(0.25)
|
4039
|
+
end
|
4040
|
+
end
|
4041
|
+
if value and value =~ /#{strg}/
|
4042
|
+
found = true
|
4043
|
+
break
|
4044
|
+
end
|
4045
|
+
end
|
4046
|
+
if found
|
4047
|
+
passed_to_log("#{msg} at index #{index}.")
|
4048
|
+
else
|
4049
|
+
failed_to_log("#{msg}")
|
4050
|
+
end
|
4051
|
+
index
|
4052
|
+
rescue
|
4053
|
+
failed_to_log("Unable to #{msg}. '#{$!}'")
|
4054
|
+
end
|
4055
|
+
|
4056
|
+
def get_index_for_table_containing_text(browser, strg, ordinal = 1)
|
4057
|
+
msg = "Get index for table containing text '#{strg}'"
|
4058
|
+
index = 0
|
4059
|
+
found = 0
|
4060
|
+
browser.tables.each do |t|
|
4061
|
+
index += 1
|
4062
|
+
if t.text =~ /#{strg}/
|
4063
|
+
found += 1
|
4064
|
+
if ordinal > 0 and found == ordinal
|
4065
|
+
break
|
4066
|
+
end
|
4067
|
+
end
|
4068
|
+
end
|
4069
|
+
if found
|
4070
|
+
passed_to_log("#{msg}: #{index}")
|
4071
|
+
index
|
4072
|
+
else
|
4073
|
+
passed_to_log("#{msg}.")
|
4074
|
+
nil
|
4075
|
+
end
|
4076
|
+
rescue
|
4077
|
+
failed_to_log("Unable to find index of table containing text '#{strg}' '#{$!}' ")
|
4078
|
+
end
|
4079
|
+
|
4080
|
+
def get_table_containing_text(browser, strg, ordinal = 1)
|
4081
|
+
msg = "Get table #{ordinal} containing text '#{strg}'"
|
4082
|
+
index = get_index_for_table_containing_text(browser, strg, ordinal)
|
4083
|
+
if index
|
4084
|
+
passed_to_log(msg)
|
4085
|
+
browser.tables[index]
|
4086
|
+
else
|
4087
|
+
failed_to_log(msg)
|
4088
|
+
nil
|
4089
|
+
end
|
4090
|
+
rescue
|
4091
|
+
failed_to_log("Unable to find index of table containing text '#{strg}' '#{$!}' ")
|
4092
|
+
end
|
4093
|
+
|
4094
|
+
def get_cell_text_from_row_with_string(nc_element, table_index, column_index, strg)
|
4095
|
+
rgx = Regexp.new(strg)
|
4096
|
+
text = ''
|
4097
|
+
debug_to_log("strg:'#{strg}', rgx:'#{rgx}', table_index:'#{table_index}', column_index:'#{column_index}'")
|
4098
|
+
nc_element.tables[table_index].each do |row|
|
4099
|
+
cell_count = get_cell_count(row)
|
4100
|
+
if cell_count >= column_index
|
4101
|
+
#TODO this assumes column 1 is a number column
|
4102
|
+
# debug_to_log("row:'#{row.cells}'")
|
4103
|
+
cell_1 = row[1].text
|
4104
|
+
if cell_1 =~ /\d+/
|
4105
|
+
row_text = row.text
|
4106
|
+
if row_text =~ rgx
|
4107
|
+
text = row[column_index].text
|
4108
|
+
break
|
4109
|
+
end
|
4110
|
+
end
|
4111
|
+
end
|
4112
|
+
end
|
4113
|
+
text
|
4114
|
+
end
|
4115
|
+
|
4116
|
+
def count_rows_with_string(container, table_index, strg)
|
4117
|
+
hit = 0
|
4118
|
+
container.tables[table_index].each do |row|
|
4119
|
+
if get_cell_count(row) >= 1
|
4120
|
+
# debug_to_log("#{__method__}: #{row.text}")
|
4121
|
+
#TODO this assumes column 1 is a number column
|
4122
|
+
if row[1].text =~ /\d+/
|
4123
|
+
if row.text =~ /#{strg}/i
|
4124
|
+
hit += 1
|
4125
|
+
debug_to_log("#{__method__}: #{row.text}")
|
4126
|
+
end
|
4127
|
+
end
|
4128
|
+
end
|
4129
|
+
end
|
4130
|
+
debug_to_log("#{__method__}: hit row count: #{hit}")
|
4131
|
+
hit
|
4132
|
+
end
|
4133
|
+
|
4134
|
+
def fetch_array_for_table_column(nc_element, table_index, column_index)
|
4135
|
+
ary = []
|
4136
|
+
nc_element.tables[table_index].each do |row|
|
4137
|
+
if get_cell_count(row) >= column_index
|
4138
|
+
#TODO this assumes column 1 is a number column
|
4139
|
+
if row[1].text =~ /\d+/
|
4140
|
+
ary << row[column_index].text
|
4141
|
+
end
|
4142
|
+
end
|
4143
|
+
end
|
4144
|
+
return ary f
|
4145
|
+
end
|
4146
|
+
|
4147
|
+
def fetch_hash_for_table_column(table, column_index, start_row = 2)
|
4148
|
+
hash = Hash.new
|
4149
|
+
row_count = 0
|
4150
|
+
table.each do |row|
|
4151
|
+
row_count += 1
|
4152
|
+
if get_cell_count(row) >= column_index
|
4153
|
+
if row_count >= start_row
|
4154
|
+
hash[row_count] = row[column_index].text
|
4155
|
+
end
|
4156
|
+
end
|
4157
|
+
end
|
4158
|
+
hash
|
4159
|
+
end
|
4160
|
+
|
4161
|
+
def get_row_cells_text_as_array(row)
|
4162
|
+
ary = []
|
4163
|
+
row.each do |cell|
|
4164
|
+
ary << cell.text
|
4165
|
+
end
|
4166
|
+
ary
|
4167
|
+
end
|
4168
|
+
|
4169
|
+
def count_data_rows(container, data_index, column_index)
|
4170
|
+
cnt = 0
|
4171
|
+
# get_objects(container, :tables, true)
|
4172
|
+
table = container.tables[data_index]
|
4173
|
+
dump_table_and_rows(table)
|
4174
|
+
if table
|
4175
|
+
table.rows.each do |row|
|
4176
|
+
if get_cell_count(row) >= column_index
|
4177
|
+
#TODO this assumes column 1 is a number column
|
4178
|
+
if row[column_index].text =~ /\d+/
|
4179
|
+
cnt += 1
|
4180
|
+
end
|
4181
|
+
end
|
4182
|
+
end
|
4183
|
+
end
|
4184
|
+
sleep_for(2)
|
4185
|
+
cnt
|
4186
|
+
end
|
4187
|
+
|
4188
|
+
def drag_and_drop(x1, y1, dx, dy, speed=nil)
|
4189
|
+
speed = 10 if not speed
|
4190
|
+
x2 = x1 + dx
|
4191
|
+
y2 = y1 + dy
|
4192
|
+
debug_to_log("drag_and_drop: start: [#{x1}, #{y1}] end: [#{x2}, #{y2}]")
|
4193
|
+
|
4194
|
+
@ai.MouseMove(x1, y1, speed)
|
4195
|
+
@ai.MouseClick("primary", x1, y1)
|
4196
|
+
sleep_for(0.5)
|
4197
|
+
@ai.MouseClick("primary", x1, y1)
|
4198
|
+
sleep_for(0.5)
|
4199
|
+
@ai.MouseClickDrag("primary", x1, y1, x2, y2, speed)
|
4200
|
+
end
|
4201
|
+
|
4202
|
+
def drag_and_drop_element(browser, element, dx, dy, speed = nil)
|
4203
|
+
speed = 10 if not speed
|
4204
|
+
w1, h1, x1, y1, xc1, yc1, xlr1, ylr1 = get_element_coordinates(browser, element, true)
|
4205
|
+
msg = "Move #{element} by [#{dx}, #{dy}] from center[#{xc1}, #{yc1}] "
|
4206
|
+
newxc = xc1 + dx
|
4207
|
+
newyc = yc1 + dy
|
4208
|
+
msg << "to center[[#{newxc}, #{newyc}]"
|
4209
|
+
sleep_for(0.5)
|
4210
|
+
|
4211
|
+
drag_and_drop(xc1, yc1, dx, dy)
|
4212
|
+
|
4213
|
+
sleep_for(1)
|
4214
|
+
w2, h2, x2, y2, xc2, yc2, xlr2, ylr2 = get_element_coordinates(browser, element, true)
|
4215
|
+
|
4216
|
+
# TODO This adjustment is adhoc and empirical. Needs to be derived more rigorously
|
4217
|
+
xcerr = xc2 - xc1
|
4218
|
+
ycerr = yc2 - yc1
|
4219
|
+
|
4220
|
+
debug_to_log("\n" +
|
4221
|
+
"\t\t xc1: #{xc1}\n" +
|
4222
|
+
"\t\t yc1: #{yc1}\n" +
|
4223
|
+
"\t\t xc2: #{xc2}\n" +
|
4224
|
+
"\t\t yc2: #{yc2}\n" +
|
4225
|
+
"\t\t xcerr: #{xlrerr}\n" +
|
4226
|
+
"\t\t ycerr: #{ylrerr}\n" +
|
4227
|
+
"\t\t x tol: #{@x_tolerance}\n" +
|
4228
|
+
"\t\t y tol: #{@y_tolerance}\n"
|
4229
|
+
)
|
4230
|
+
|
4231
|
+
#TODO Add check that window _was_ resized.
|
4232
|
+
x_ok, x_msg = validate_drag_drop(xcerr, @x_tolerance, newxc, xc2)
|
4233
|
+
y_ok, y_msg = validate_drag_drop(ycerr, @y_tolerance, newyc, yc2)
|
4234
|
+
msg = msg + "x: #{x_msg}, y: #{y_msg}"
|
4235
|
+
|
4236
|
+
if x_ok and y_ok
|
4237
|
+
passed_to_log(msg)
|
4238
|
+
else
|
4239
|
+
failed_to_log(msg)
|
4240
|
+
end
|
4241
|
+
sleep_for(1)
|
4242
|
+
rescue
|
4243
|
+
failed_to_log("Unable to validate drag and drop. #{$!} (#{__LINE__})")
|
4244
|
+
sleep_for(1)
|
4245
|
+
end
|
4246
|
+
|
4247
|
+
def get_objects(browser, which, dbg=false)
|
4248
|
+
cnt = 0
|
4249
|
+
case which
|
4250
|
+
when :links
|
4251
|
+
list = browser.links
|
4252
|
+
sleep(1)
|
4253
|
+
when :tables
|
4254
|
+
list = browser.tables
|
4255
|
+
when :divs
|
4256
|
+
list = browser.divs
|
4257
|
+
when :buttons
|
4258
|
+
list = browser.buttons
|
4259
|
+
when :checkboxes
|
4260
|
+
list = browser.checkboxes
|
4261
|
+
when :radios
|
4262
|
+
list = browser.radios
|
4263
|
+
when :selectlists
|
4264
|
+
list = browser.selectlists
|
4265
|
+
when :textfields
|
4266
|
+
list = browser.textfields
|
4267
|
+
when :lis
|
4268
|
+
list = browser.lis
|
4269
|
+
else
|
4270
|
+
debug_to_log("Unrecognized dom object '#{which}'")
|
4271
|
+
end
|
4272
|
+
if dbg
|
4273
|
+
list.each do |obj|
|
4274
|
+
cnt += 1
|
4275
|
+
debug_to_log("\n============== #{which}:\nindex: #{cnt}\n#{obj}\n#{obj.to_yaml}")
|
4276
|
+
end
|
4277
|
+
end
|
4278
|
+
list
|
4279
|
+
end
|
4280
|
+
|
4281
|
+
def get_ole(element)
|
4282
|
+
ole = element.ole_object
|
4283
|
+
if ole
|
4284
|
+
passed_to_log("Found ole_object for #{element}.")
|
4285
|
+
ole
|
4286
|
+
else
|
4287
|
+
failed_to_log("Did not find ole_object for #{element}.")
|
4288
|
+
end
|
4289
|
+
rescue
|
4290
|
+
failed_to_log("Unable to find ole_object for #{element}. #{$!}")
|
4291
|
+
end
|
4292
|
+
|
4293
|
+
def find_all_links_with_exact_href(browser, href)
|
4294
|
+
links = browser.links
|
4295
|
+
hash = Hash.new
|
4296
|
+
idx = 0
|
4297
|
+
links.each do |l|
|
4298
|
+
idx += 1
|
4299
|
+
an_href = href
|
4300
|
+
my_href = l.href
|
4301
|
+
if my_href == an_href
|
4302
|
+
hash[idx] = l
|
4303
|
+
debug_to_log("#{__method__}:#{idx}\n********\n#{l.to_s}\n\n#{l.to_yaml}")
|
4304
|
+
end
|
4305
|
+
end
|
4306
|
+
hash
|
4307
|
+
end
|
4308
|
+
|
4309
|
+
def find_link_with_exact_href(browser, href)
|
4310
|
+
links = browser.links
|
4311
|
+
link = nil
|
4312
|
+
index = 0
|
4313
|
+
links.each do |l|
|
4314
|
+
index += 1
|
4315
|
+
an_href = href
|
4316
|
+
my_href = l.href
|
4317
|
+
if my_href == an_href
|
4318
|
+
link = l
|
4319
|
+
# debug_to_log("#{__method__}:#{__LINE__}\n********\n#{l.to_s}\n\n#{l.to_yaml}")
|
4320
|
+
break
|
4321
|
+
end
|
4322
|
+
end
|
4323
|
+
link
|
4324
|
+
end
|
4325
|
+
|
4326
|
+
def find_index_for_object(browser, obj, how, ord, strg)
|
4327
|
+
obj_sym = (obj.to_s.pluralize).to_sym
|
4328
|
+
how_str = how.to_s
|
4329
|
+
ptrn = /#{how}:\s+#{strg}/i
|
4330
|
+
list = get_objects(browser, obj_sym, true)
|
4331
|
+
cnt = 0
|
4332
|
+
idx = 0
|
4333
|
+
list.each do |nty|
|
4334
|
+
s = nty.to_s
|
4335
|
+
# a = nty.to_a
|
4336
|
+
if s =~ ptrn
|
4337
|
+
cnt += 1
|
4338
|
+
if cnt == ord
|
4339
|
+
break
|
4340
|
+
end
|
4341
|
+
end
|
4342
|
+
idx += 1
|
4343
|
+
end
|
4344
|
+
idx
|
4345
|
+
end
|
4346
|
+
|
4347
|
+
def right_click(element)
|
4348
|
+
x = element.left_edge_absolute + 2
|
4349
|
+
y = element.top_edge_absolute + 2
|
4350
|
+
@ai.MouseClick("secondary", x, y)
|
4351
|
+
end
|
4352
|
+
|
4353
|
+
def left_click(element)
|
4354
|
+
x = element.left_edge_absolute + 2
|
4355
|
+
y = element.top_edge_absolute + 2
|
4356
|
+
@ai.MouseClick("primary", x, y)
|
4357
|
+
end
|
4358
|
+
|
4359
|
+
def get_cell_count(row)
|
4360
|
+
# if @browserAbbrev == 'IE' or $use_firewatir
|
4361
|
+
row.cells.length
|
4362
|
+
# else
|
4363
|
+
# row.cell_count
|
4364
|
+
# end
|
4365
|
+
end
|
4366
|
+
|
4367
|
+
def screen_offset(element, browser=nil)
|
4368
|
+
bx, by, bw, bh = get_browser_coord(browser)
|
4369
|
+
ex = element.left_edge
|
4370
|
+
ey = element.top_edge
|
4371
|
+
[bx + ex, by + ey]
|
4372
|
+
end
|
4373
|
+
|
4374
|
+
def screen_center(element, browser=nil)
|
4375
|
+
bx, by, bw, bh = get_browser_coord(browser)
|
4376
|
+
w, h = element.dimensions.to_a
|
4377
|
+
cx = bx + w/2
|
4378
|
+
cy = by + h/2
|
4379
|
+
[cx, cy]
|
4380
|
+
end
|
4381
|
+
|
4382
|
+
def screen_lower_right(element, browser=nil)
|
4383
|
+
bx, by, bw, bh = get_browser_coord(browser)
|
4384
|
+
w, h = element.dimensions.to_a
|
4385
|
+
[bx + w, by + h]
|
4386
|
+
end
|
4387
|
+
|
4388
|
+
#TODO unlikely to work...
|
4389
|
+
def find_me(where, how, what)
|
4390
|
+
me = where.element(how, what)
|
4391
|
+
puts me.inspect
|
4392
|
+
rescue
|
4393
|
+
error_to_log("#{where.inspect} doesn't seem to respond to element() #{$!}")
|
4394
|
+
end
|
4395
|
+
|
4396
|
+
def click_me(element)
|
4397
|
+
element.click
|
4398
|
+
rescue
|
4399
|
+
error_to_log("#{element.inspect} doesn't seem to respond to click() #{$!}")
|
4400
|
+
end
|
4401
|
+
|
4402
|
+
def filter_bailout_from_rescue(err, msg)
|
4403
|
+
if msg =~ /bailing out/i
|
4404
|
+
raise err
|
4405
|
+
else
|
4406
|
+
error_to_log(msg)
|
4407
|
+
end
|
4408
|
+
end
|
4409
|
+
|
4410
|
+
def get_caller_line
|
4411
|
+
last_caller = get_callers[0]
|
4412
|
+
line = last_caller.split(':', 3)[1]
|
4413
|
+
line
|
4414
|
+
end
|
4415
|
+
|
4416
|
+
def get_call_list(depth = 9, dbg = false)
|
4417
|
+
myList = []
|
4418
|
+
call_list = Kernel.caller
|
4419
|
+
puts call_list if dbg
|
4420
|
+
call_list.each_index do |x|
|
4421
|
+
myCaller = call_list[x].to_s
|
4422
|
+
break if x > depth or myCaller =~ /:in .run.$/
|
4423
|
+
myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
|
4424
|
+
myList << "[#{$1.gsub(/eval/, @myName)}] "
|
4425
|
+
end
|
4426
|
+
myList
|
4427
|
+
end
|
4428
|
+
|
4429
|
+
alias get_callers get_call_list
|
4430
|
+
|
4431
|
+
def get_call_list_new(depth = 9, dbg = false)
|
4432
|
+
myList = []
|
4433
|
+
call_list = Kernel.caller
|
4434
|
+
puts call_list if dbg
|
4435
|
+
call_list.each_index do |x|
|
4436
|
+
myCaller = call_list[x].to_s
|
4437
|
+
break if x > depth or myCaller =~ /:in .run.$/
|
4438
|
+
if myCaller.include? @myName
|
4439
|
+
myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
|
4440
|
+
myList << "[#{$1.gsub(/eval/, @myName)}] "
|
4441
|
+
break
|
4442
|
+
end
|
4443
|
+
end
|
4444
|
+
if @projName
|
4445
|
+
call_list.each_index do |x|
|
4446
|
+
myCaller = call_list[x].to_s
|
4447
|
+
break if x > depth or myCaller =~ /:in .run.$/
|
4448
|
+
if myCaller.include? @projName
|
4449
|
+
myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
|
4450
|
+
myList << "[#{$1.gsub(/eval/, @projName)}] "
|
4451
|
+
break
|
4452
|
+
end
|
4453
|
+
end
|
4454
|
+
end
|
4455
|
+
myList
|
4456
|
+
end
|
4457
|
+
|
4458
|
+
def get_call_array(depth = 9)
|
4459
|
+
arr = []
|
4460
|
+
call_list = Kernel.caller
|
4461
|
+
call_list.each_index do |x|
|
4462
|
+
myCaller = call_list[x].to_s
|
4463
|
+
break if x > depth or myCaller =~ /:in .run.$/
|
4464
|
+
myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
|
4465
|
+
arr << $1.gsub(/eval/, @myName)
|
4466
|
+
end
|
4467
|
+
arr
|
4468
|
+
end
|
4469
|
+
|
4470
|
+
def get_debug_list(dbg = false)
|
4471
|
+
calls = get_call_array(10)
|
4472
|
+
puts "#{calls.to_yaml}" if dbg
|
4473
|
+
arr = []
|
4474
|
+
calls.each_index do |ix|
|
4475
|
+
if ix > 1 # skip this method and the logging method
|
4476
|
+
arr << calls[ix]
|
4477
|
+
end
|
4478
|
+
end
|
4479
|
+
puts "#{arr.to_yaml}" if dbg
|
4480
|
+
if arr.length > 0
|
4481
|
+
list = 'TRACE:'
|
4482
|
+
arr.reverse.each { |l| list << "=>#{l}" }
|
4483
|
+
" [[#{list}]]"
|
4484
|
+
else
|
4485
|
+
nil
|
4486
|
+
end
|
4487
|
+
end
|
4488
|
+
|
4489
|
+
def dump_all_tables(browser, to_report = false)
|
4490
|
+
tables = browser.tables
|
4491
|
+
msg = ''
|
4492
|
+
tbl_cnt = 0
|
4493
|
+
tables.each do |tbl|
|
4494
|
+
tbl_cnt += 1
|
4495
|
+
row_cnt = 0
|
4496
|
+
msg <<"\n=================\ntable: #{tbl_cnt}\n=================\n#{tbl}\ntext:\n#{tbl.text}"
|
4497
|
+
tbl.rows.each do |row|
|
4498
|
+
row_cnt += 1
|
4499
|
+
cell_cnt = 0
|
4500
|
+
msg <<"\n=================\ntable: #{tbl_cnt} row: #{row_cnt}\n#{row.inspect}\n#{row}\ntext:'#{row.text}'"
|
4501
|
+
row.each do |cell|
|
4502
|
+
cell_cnt += 1
|
4503
|
+
msg <<"\n==== cell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
|
4504
|
+
end
|
4505
|
+
end
|
4506
|
+
end
|
4507
|
+
if to_report
|
4508
|
+
debug_to_report(msg)
|
4509
|
+
else
|
4510
|
+
debug_to_log(msg)
|
4511
|
+
end
|
4512
|
+
end
|
4513
|
+
|
4514
|
+
def dump_table_and_rows(table, to_report = false)
|
4515
|
+
msg = "\n=================\ntable\n=================\nn#{table}\n#{table.to_yaml}\nrows:"
|
4516
|
+
cnt = 0
|
4517
|
+
table.rows.each do |r|
|
4518
|
+
cnt += 1
|
4519
|
+
msg << "\n#{cnt}: #{r.text}"
|
4520
|
+
end
|
4521
|
+
msg << "\n=================\n================="
|
4522
|
+
if to_report
|
4523
|
+
debug_to_report(msg)
|
4524
|
+
else
|
4525
|
+
debug_to_log(msg)
|
4526
|
+
end
|
4527
|
+
end
|
4528
|
+
|
4529
|
+
def dump_table_rows_and_cells(tbl)
|
4530
|
+
msg = ''
|
4531
|
+
row_cnt = 0
|
4532
|
+
msg <<"\n=================\ntable: #{tbl.inspect}\n=================\n#{tbl}\ntext:\n#{tbl.text}"
|
4533
|
+
tbl.rows.each do |row|
|
4534
|
+
row_cnt += 1
|
4535
|
+
cell_cnt = 0
|
4536
|
+
msg <<"\n=================\nrow: #{row_cnt}\n#{row.inspect}\n#{row}\ntext:'#{row.text}'"
|
4537
|
+
row.each do |cell|
|
4538
|
+
cell_cnt += 1
|
4539
|
+
msg <<"\n==== cell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
|
4540
|
+
end
|
4541
|
+
end
|
4542
|
+
debug_to_log(msg)
|
4543
|
+
end
|
4544
|
+
|
4545
|
+
alias dump_table_rows dump_table_rows_and_cells
|
4546
|
+
|
4547
|
+
def dump_array(arr, space_to_underscore = false)
|
4548
|
+
dump = " #{arr.inspect}\n"
|
4549
|
+
arr.each_index do |x|
|
4550
|
+
value = arr[x].to_s
|
4551
|
+
value.gsub!(/\s/, '_') if space_to_underscore
|
4552
|
+
dump << " #{x.to_s.rjust(5)}>> '#{arr[x].to_s}'\n"
|
4553
|
+
end
|
4554
|
+
dump
|
4555
|
+
end
|
4556
|
+
|
4557
|
+
def dump_ole_methods(ole)
|
4558
|
+
rtrn = ''
|
4559
|
+
ole.ole_methods.each do |m|
|
4560
|
+
prms = ''
|
4561
|
+
m.params.each do |p|
|
4562
|
+
prms << "#{p}, "
|
4563
|
+
end
|
4564
|
+
rtrn << "#{m.name}(#{prms.chop.chop})\n"
|
4565
|
+
end
|
4566
|
+
rtrn
|
4567
|
+
end
|
4568
|
+
|
4569
|
+
def dump_ole_get_methods(ole)
|
4570
|
+
rtrn = ''
|
4571
|
+
ole.ole_get_methods.each do |m|
|
4572
|
+
prms = ''
|
4573
|
+
m.params.each do |p|
|
4574
|
+
prms << "#{p}, "
|
4575
|
+
end
|
4576
|
+
rtrn << "#{m.name}(#{prms.chop.chop})\n"
|
4577
|
+
end
|
4578
|
+
rtrn
|
4579
|
+
end
|
4580
|
+
|
4581
|
+
def dump_ole_help(ole)
|
4582
|
+
rtrn = ''
|
4583
|
+
ole.ole_obj_help.each do |m|
|
4584
|
+
prms = ''
|
4585
|
+
m.params.each do |p|
|
4586
|
+
prms << "#{p}, "
|
4587
|
+
end
|
4588
|
+
rtrn << "#{m.name}(#{prms.chop.chop})\n"
|
4589
|
+
end
|
4590
|
+
rtrn
|
4591
|
+
end
|
4592
|
+
|
4593
|
+
def dump_row_cells(row)
|
4594
|
+
msg = ''
|
4595
|
+
cell_cnt = 0
|
4596
|
+
msg <<"\n=================\nrow: #{row.inspect}\n#{row}\ntext:'#{row.text}'"
|
4597
|
+
row.each do |cell|
|
4598
|
+
cell_cnt += 1
|
4599
|
+
msg <<"\n==== cell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
|
4600
|
+
end
|
4601
|
+
debug_to_log(msg)
|
4602
|
+
end
|
4603
|
+
|
4604
|
+
def dump_select_list_options(element)
|
4605
|
+
msg = "#{element.inspect}"
|
4606
|
+
options = element.options
|
4607
|
+
cnt = 1
|
4608
|
+
options.each do |o|
|
4609
|
+
msg << "\n\t#{cnt}:\t'#{o}"
|
4610
|
+
cnt += 1
|
4611
|
+
end
|
4612
|
+
debug_to_log(msg)
|
4613
|
+
end
|
4614
|
+
|
4615
|
+
end
|