awetestlib 0.0.2-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -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