awetestlib 0.1.29pre4 → 0.1.29

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,1385 +1,1378 @@
1
- module Awetestlib
2
- # Awetest DSL for browser based testing.
3
- module Regression
4
- # Methods to manage browser windows: open, close, attach, verify health, and clean up.
5
- module Browser
6
-
7
- #def run #DO WE NEED? Use this method to tell user they need to create a run method?
8
- ## Not here in any case.
9
- # setup
10
- # set_script_variables
11
- # run_test
12
- #rescue
13
- # fatal_to_log("(#{__LINE__}) #{$!}")
14
- # browser.close
15
- # raise
16
- #end
17
-
18
- # @!group Browser
19
-
20
- # @note webdriver specific - still work in progress
21
- def go_to_wd_url(browser, url)
22
-
23
- Watir::Browser.class_eval do
24
- def goto(uri)
25
- uri = "http://#{uri}" unless uri =~ URI.regexp
26
- @driver.navigate.to uri
27
- run_checkers
28
- end
29
- end
30
- browser.goto(url)
31
-
32
- #in basic_auth1 edit:
33
- #a = Thread.new {
34
- # goto_wd_url(browser, @myURL)
35
- # }
36
-
37
- end
38
-
39
- alias goto_wd_url go_to_wd_url
40
-
41
- # Open a browser based on the command line parameters that identify the browser and
42
- # version to use for the test.
43
- # @note Safari currently supported only on Mac OS X
44
- # @example
45
- # browser = open_browser('www.google.com')
46
- # @param [String, Regexp] url When provided, the browser will go to this url.
47
- # @return [Watir::Browser]
48
- def open_browser(url = nil)
49
- message_to_report("Opening browser: #{@targetBrowser.name}")
50
- case @targetBrowser.abbrev
51
- when 'IE'
52
- @myBrowser = open_ie
53
- if @myBrowser.class.to_s == "Watir::IE"
54
- @myHwnd = @myBrowser.hwnd
55
- end
56
- when 'FF'
57
- @myBrowser = open_ff
58
- when 'S'
59
- if USING_OSX
60
- @myBrowser = open_safari
61
- else
62
- raise "Safari is not supported under this operating system #{RUBY_PLATFORM}"
63
- end
64
- when 'C', 'GC'
65
- @myBrowser = open_chrome
66
- else
67
- raise "Unsupported browser: #{@targetBrowser.name}"
68
- end
69
- if url
70
- go_to_url(@myBrowser, url)
71
- end
72
- @myBrowser
73
- end
74
-
75
- # Open IE (Internet Explorer) browser instance.
76
- # If global variable $watir_script is set to true in the first line of the script,
77
- # classic Watir will be used to drive the browser,
78
- # otherwise Watir Webdriver will be used.
79
- # @return [Watir::Browser]
80
- def open_ie
81
- if $watir_script
82
- browser = Watir::IE.new
83
- else
84
- browser = Watir::Browser.new :ie
85
- end
86
- browser
87
- end
88
-
89
- # Open Safari browser instance.
90
- # @note Safari currently supported only on Mac OS X
91
- # @return [Watir::Browser]
92
- def open_safari
93
- browser = Watir::Browser.new(:remote, :desired_capabilities=>:'safari')
94
- end
95
-
96
- # Open FF (Firefox) browser instance under FireWatir.
97
- # @return [Watir::Browser]
98
- def open_ff
99
- browser = Watir::Browser.new :firefox
100
- end
101
-
102
- # Open GC (Google Chrome) browser instance.
103
- # @return [Watir::Browser] Browser is Google Chrome.
104
- def open_chrome
105
- browser = Watir::Browser.new(:chrome)
106
- end
107
-
108
- # Instruct browser to navigate to a specific URL
109
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
110
- # @param [String] url When provided, the browser will go to this url.
111
- # and the instance variable @myURL will be set to this value.
112
- # @return [Boolean] True when navigation to url succeeds.
113
- def go_to_url(browser, url = nil)
114
- if url
115
- @myURL = url
116
- end
117
- message_to_report("URL: #{@myURL}")
118
- browser.goto(@myURL)
119
- true
120
- rescue
121
- fatal_to_log("Unable to navigate to '#{@myURL}': '#{$!}'")
122
- end
123
-
124
- # Return a reference to a browser window. Used to attach a browser window to a variable
125
- # which can then be passed to methods that require a *browser* parameter.
126
- # @example
127
- # mainwindow = open_browser('www.google.com')
128
- # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
129
- # popup = attach_browser(mainwindow, :url, '[url of new window]') #*or*
130
- # popup = attach_browser(mainwindow, :title, '[title of new window]')
131
- # @todo Update to work with webdriver for IE.
132
- # @param [Watir::Browser] browser A reference to the current browser window.
133
- # @param [Symbol] how The element attribute used to identify the window: *:title* or :url.
134
- # @param [String|Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
135
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
136
- # @return [Watir::Browser] Internet Explorer
137
- def attach_browser(browser, how, what, desc = '')
138
- debug_to_log("Attaching browser window :#{how}=>'#{what}' #{desc}")
139
- uri_decoded_pattern = ::URI.encode(what.to_s.gsub('(?-mix:', '').gsub(')', ''))
140
-
141
- if $watir_script
142
- tmpbrowser = Watir::IE.attach(how, what)
143
- browser.visible = true
144
- if tmpbrowser
145
- tmpbrowser.visible = true
146
- tmpbrowser.speed = :fast
147
- else
148
- raise "Browser window :#{how}=>'#{what}' has at least one doc not in completed ready state."
149
- end
150
- else
151
- browser.driver.switch_to.window(browser.driver.window_handles[0])
152
- browser.window(how, /#{uri_decoded_pattern}/).use
153
- tmpbrowser = browser
154
- end
155
-
156
- # case @browserAbbrev
157
- # when 'IE'
158
- # tmpbrowser = Watir::IE.attach(how, what)
159
- # browser.visible = true
160
- # if tmpbrowser
161
- # tmpbrowser.visible = true
162
- # tmpbrowser.speed = :fast
163
- # else
164
- # raise "Browser window :#{how}=>'#{what}' has at least one doc not in completed ready state."
165
- # end
166
- # when 'FF'
167
- # #TODO: This may be dependent on Firefox version if webdriver doesn't support 3.6.17 and below
168
- # browser.driver.switch_to.window(browser.driver.window_handles[0])
169
- # browser.window(how, /#{uri_decoded_pattern}/).use
170
- # tmpbrowser = browser
171
- # when 'S'
172
- # Watir::Safari.attach(how, what)
173
- # tmpbrowser = browser
174
- # when 'C', 'GC'
175
- # browser.window(how, /#{uri_decoded_pattern}/).use
176
- # tmpbrowser = browser
177
- # end
178
-
179
-
180
- debug_to_log("#{__method__}: tmpbrowser:#{tmpbrowser.inspect}")
181
- tmpbrowser
182
- end
183
-
184
-
185
- # Returns a reference to a new browser window. Used to attach a new browser window to a variable
186
- # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
187
- # @example
188
- # mainwindow = open_browser('www.google.com')
189
- # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
190
- # popup = attach_popup(mainwindow, :url, '[url of new window]') *or*
191
- # popup = attach_popup(mainwindow, :title, '[title of new window]')
192
- # @param [Watir::Browser] browser A reference to the current browser window.
193
- # @param [Symbol] how The element attribute used to identify the window: *:title* or :url.
194
- # @param [String, Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
195
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
196
- # @return [Watir::Browser] The new browser window.
197
- def attach_popup(browser, how, what, desc = '')
198
- msg = "Attach popup :#{how}=>'#{what}'. #{desc}"
199
- popup = attach_browser(browser, how, what, desc)
200
- sleep_for(1)
201
- debug_to_log("#{popup.inspect}")
202
- if is_browser?(popup)
203
- title = popup.title
204
- passed_to_log("#{msg} title='#{title}'")
205
- return popup
206
- else
207
- failed_to_log(msg)
208
- end
209
- rescue
210
- failed_to_log("Unable to attach popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
211
- end
212
-
213
- # Locate and close instances of IE browsers
214
- def find_other_browsers
215
- cnt = 0
216
- if @targetBrowser.abbrev == 'IE'
217
- Watir::IE.each do |ie|
218
- debug_to_log("#{ie.inspect}")
219
- ie.close()
220
- cnt = cnt + 1
221
- end
222
- end
223
- debug_to_log("Found #{cnt} IE browser(s).")
224
- return cnt
225
- rescue
226
- error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}", __LINE__)
227
- return 0
228
- end
229
-
230
- # @!endgroup Browser
231
-
232
- # @!group Login
233
-
234
- # Simple login method
235
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
236
- # @param [String] user Login ID for the user.
237
- # @param [String] password Password for the user.
238
- # @return [Boolean] True if login succeeds.
239
- def login(browser, user, password)
240
- #TODO: Needs to be more flexible about finding login id and password textfields
241
- #TODO: Parameterize url and remove references to environment
242
- myURL = @myAppEnv.url
243
- runenv = @myAppEnv.nodename
244
- message_tolog("URL: #{myURL}") if @myAppEnv
245
- message_tolog("Beginning login: User: #{user} Environment: #{@myAppEnv.nodename}") if @myAppEnv
246
- if validate(browser, @myName, __LINE__)
247
- browser.goto(@myAppEnv.url)
248
- if validate(browser, @myName)
249
- set_textfield_by_name(browser, 'loginId', user)
250
- set_textfield_by_name(browser, 'password', password)
251
- click_button_by_value(browser, 'Login')
252
- if validate(browser, @myName)
253
- passed_to_log("Login successful.")
254
- true
255
- end
256
- else
257
- failed_to_log("Unable to login to application: '#{$!}'")
258
- #screen_capture( "#{@myRoot}/screens/#{myName}_#{@runid}_#{__LINE__.to_s}_#{Time.new.to_f.to_s}.jpg")
259
- end
260
- end
261
- rescue
262
- failed_to_log("Unable to login to application: '#{$!}'")
263
- end
264
-
265
- # Logon to webpage using Basic Authorization type of logon. Uses AutoIt
266
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
267
- # @param [String] user Login ID for the user.
268
- # @param [String] password Password for the user.
269
- # @param [String] url The URL to log on to.
270
- # @param [Boolean] bypass_validate When set to true, the call to validate(),
271
- # which checks the health of the browser, is skipped..
272
- def basic_auth(browser, user, password, url, bypass_validate = false)
273
- mark_testlevel("Basic Authorization Login", 0)
274
-
275
- message_to_report ("Login: #{user}")
276
- message_to_report ("URL: #{url}")
277
- message_to_report ("Password: #{password}")
278
-
279
- @login_title = "Connect to"
280
-
281
- a = Thread.new {
282
- browser.goto(url)
283
- }
284
-
285
- sleep_for(2)
286
- message_to_log("#{@login_title}...")
287
-
288
- if (@ai.WinWait(@login_title, "", 90) > 0)
289
- win_title = @ai.WinGetTitle(@login_title)
290
- debug_to_log("Basic Auth Login window appeared: '#{win_title}'")
291
- @ai.WinActivate(@login_title)
292
- @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", '!u')
293
- @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", user, 1)
294
- @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:3]", password.gsub(/!/, '{!}'), 1)
295
- @ai.ControlClick(@login_title, "", '[CLASS:Button; INSTANCE:1]')
296
- else
297
- debug_to_log("Basic Auth Login window did not appear.")
298
- end
299
- a.join
300
-
301
- validate(browser, @myName) unless bypass_validate
302
-
303
- message_to_report("URL: [#{browser.url}] User: [#{user}]")
304
-
305
- end
306
-
307
- # Provide an authorization token or passcode in a specified text field element identified by its *:id* attribute.
308
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
309
- # @param [String] role Usually a user role designation ('Administrator', 'User', etc.)
310
- # @param [String] token Authentification token required by logon process.
311
- # @param [String/Regexp] id Value of the *:id* attribute of the text field that will receive the *token*.
312
- def token_auth(browser, role, token, id = 'token_pass')
313
- set_textfield_by_id(browser, id, token)
314
- click_button_by_value(browser, 'Continue')
315
- if validate_text(browser, 'The requested page requires authentication\.\s*Please enter your Passcode below', nil, true)
316
- bail_out(browser, __LINE__, "Token authorization failed on '#{token}'")
317
- end
318
- end
319
-
320
- # @!endgroup Logon
321
-
322
- # @!group Error Handling
323
-
324
- # Exit more or less gracefully from script when errors are too severe to continue.
325
- # Normally not called in a test script or project library.
326
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
327
- # @param [Fixnum] lnbr Line number in calling script.
328
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
329
- #
330
- def bail_out(browser, lnbr, desc)
331
- ts = Time.new
332
- msg = "Bailing out at util line #{lnbr} #{ts} " + desc
333
- puts "#{msg}"
334
- fatal_to_log(msg, lnbr)
335
- debug_to_log(dump_caller(lnbr))
336
- if is_browser?(browser)
337
- if @browserAbbrev == 'IE'
338
- hwnd = browser.hwnd
339
- kill_browser(hwnd, lnbr, browser)
340
- raise(RuntimeError, msg, caller)
341
- elsif @browserAbbrev == 'FF'
342
- debug_to_log("#{browser.inspect}")
343
- debug_to_log("#{browser.to_s}")
344
- raise(RuntimeError, msg, caller)
345
- end
346
- end
347
- @status = 'bailout'
348
- raise(RuntimeError, msg, caller)
349
- end
350
-
351
-
352
- # Check for the presence of IE browser instances.
353
- # @return [Fixnum] The number of IE browser instances encountered.
354
- def check_for_other_browsers
355
- cnt1 = find_other_browsers
356
- cnt2 = Watir::Process.count 'iexplore.exe'
357
- debug_to_log("check_for_other_browsers: cnt1: #{cnt1} cnt2: #{cnt2}")
358
- rescue
359
- error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}")
360
- end
361
-
362
- # Check for the presence of IE browser instances and close all that are found.
363
- def check_for_and_clear_other_browsers
364
- if @targetBrowser.abbrev == 'IE'
365
- debug_to_log("#{__method__}:")
366
- cnt1 = find_other_browsers
367
- cnt2 = Watir::IE.process_count
368
- debug_to_log("#{__method__}: cnt1: #{cnt1} cnt2: #{cnt2}")
369
- begin
370
- Watir::IE.each do |ie|
371
- pid = Watir::IE::Process.process_id_from_hwnd(ie.hwnd)
372
- debug_to_log("#{__method__}: Killing browser process: hwnd #{ie.hwnd} pid #{pid} title '#{ie.title}' (#{__LINE__})")
373
- do_taskkill(INFO, pid)
374
- sleep_for(10)
375
- end
376
- #Watir::IE.close_all()
377
- rescue
378
- debug_to_log("#{__method__}: #{$!} (#{__LINE__})")
379
- end
380
- sleep(3)
381
- cnt1 = find_other_browsers
382
- cnt2 = Watir::IE.process_count
383
- if cnt1 > 0 or cnt2 > 0
384
- debug_to_log("#{__method__}:cnt1: #{cnt1} cnt2: #{cnt2}")
385
- begin
386
- Watir::IE.each do |ie|
387
- pid = Watir::IE::Process.process_id_from_hwnd(ie.hwnd)
388
- debug_to_log("#{__method__}: Killing browser process: hwnd #{ie.hwnd} pid #{pid} title '#{ie.title}' (#{__LINE__})")
389
- do_taskkill(INFO, pid)
390
- sleep_for(10)
391
- end
392
- #Watir::IE.close_all()
393
- rescue
394
- debug_to_log("#{__method__}:#{$!} (#{__LINE__})")
395
- end
396
- end
397
- end
398
- rescue
399
- error_to_log("#{__method__}: #{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}")
400
- end
401
-
402
- # Force browser instance to close, one way or the other.
403
- # Instance is identified by *hwnd*, the Windows OS handle for the process.
404
- # @param [String] hwnd The value for the window handle for the browser process.
405
- # @param [Fixnum] lnbr Line number in calling script.
406
- # @param [Watir::Browser] browser A reference to the browser window or container element to be closed.
407
- def kill_browser(hwnd, lnbr, browser = nil, doflag = false)
408
- # TODO Firefox
409
- logit = false
410
- if @browserAbbrev == 'FF'
411
- if is_browser?(browser) # and browser.url.length > 1
412
- logit = true
413
- here = __LINE__
414
- url = browser.url
415
- #capture_screen(browser, Time.new.to_f) if @screenCaptureOn
416
- browser.close if url.length > 0
417
- @status = 'killbrowser'
418
- fatal_to_log("Kill browser called from line #{lnbr}")
419
- end
420
- elsif hwnd
421
- pid = Watir::IE::Process.process_id_from_hwnd(hwnd)
422
- if pid and pid > 0 and pid < 538976288
423
- if browser.exists?
424
- here = __LINE__
425
- logit = true
426
- url = browser.url
427
- #capture_screen(browser, Time.new.to_f) if @screenCaptureOn
428
- browser.close
429
- sleep(2)
430
- if browser.exists?
431
- do_taskkill(FATAL, pid)
432
- end
433
- @status = 'killbrowser'
434
- end
435
- end
436
- if logit
437
- debug_to_log("#{@browserName} window hwnd #{hwnd} pid #{pid} #{url} (#{here})")
438
- fatal_to_log("Kill browser called from line #{lnbr}")
439
- end
440
- end
441
- end
442
-
443
- # @!endgroup Error Handling
444
-
445
- # @!group Browser
446
-
447
- # Use enabled_popup and winclicker to determine if there is an active modal popup.
448
- # Useful only when no wait action has been invoked.
449
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
450
- # @param [String] button The visible name of the button to be clicked to close the popup.
451
- # @return [String] containing the window handle of the closed modal popup.
452
- def modal_exists?(browser, button = nil)
453
- rtrn = nil
454
- if @browserAbbrev == 'IE'
455
- Timeout::timeout(2) do
456
- begin
457
- if browser.enabled_popup
458
- hwnd = browser.enabled_popup(5)
459
- debug_to_log("Modal popup with handle #{hwnd} found. (#{__LINE__})")
460
- wc = WinClicker.new
461
- wc.makeWindowActive(hwnd)
462
- rtrn = wc.getWindowTitle(hwnd)
463
- if button
464
- wc.clickWindowsButton_hWnd(hwnd, button)
465
- end
466
- wc = nil
467
- end
468
- rescue Timeout::Error
469
- debug_to_log("No Modal popup found. (#{__LINE__})")
470
- return rtrn
471
- end
472
- return rtrn
473
- end
474
- rtrn
475
- else
476
- rtrn
477
- end
478
- end
479
-
480
- # Close a browser window identified by its title.
481
- # Uses AutoIt. Windows only.
482
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
483
- # @param [String] title The title of the window to be closed. Matched from beginning of string.
484
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
485
- # @param [String] text (optional) The text of the window to be closed. Matched from beginning of string.
486
- def close_window_by_title(browser, title, desc = '', text = '')
487
- msg = "Window '#{title}':"
488
- if @ai.WinWait(title, text, WAIT) > 0
489
- passed_to_log("#{msg} appeared. #{desc}")
490
- myHandle = @ai.WinGetHandle(title, text)
491
- full_text = @ai.WinGetText(title)
492
- debug_to_log("#{msg} hwnd: #{myHandle.inspect}")
493
- debug_to_log("#{msg} title: '#{title}' text: '#{full_text}'")
494
- if @ai.WinClose(title, text) > 0
495
- passed_to_log("#{msg} closed successfully. #{desc}")
496
- else
497
- failed_to_log("#{msg} close failed. (#{__LINE__}) #{desc}")
498
- end
499
- else
500
- failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__}) #{desc}")
501
- end
502
- rescue
503
- failed_to_log("#{msg}: Unable to close: '#{$!}'. (#{__LINE__}) #{desc}")
504
- end
505
-
506
- # Closes main browser session. Misnamed. Usually used at end of script to shut down browser.
507
- def close_browser(browser, where = @myName, lnbr = __LINE__)
508
- #TODO Firewatir 1.6.5 does not implement .exists for FireWatir::Firefox class
509
- debug_to_log("Logging out in #{where} at line #{lnbr}.", lnbr, true)
510
- debug_to_log("#{__method__}: browser: #{browser.inspect} (#{__LINE__})")
511
-
512
- url = browser.url
513
- title = browser.title
514
-
515
- if ['FF', 'S'].include?(@browserAbbrev) || browser.exists?
516
- case @browserAbbrev
517
- when 'FF'
518
- if is_browser?(browser)
519
- debug_to_log("#{__method__}: Firefox browser url: [#{url}]")
520
- debug_to_log("#{__method__}: Firefox browser title: [#{title}]")
521
- debug_to_log("#{__method__}: Closing browser: #{where} (#{lnbr})")
522
- if url and url.length > 1
523
- browser.close
524
- else
525
- browser = FireWatir::Firefox.attach(:title, title)
526
- browser.close
527
- end
528
-
529
- end
530
- when 'IE'
531
- debug_to_log("#{__method__}: Internet Explorer browser url: [#{url}]")
532
- debug_to_log("#{__method__}: Internet Explorer browser title: [#{title}]")
533
- debug_to_log("#{__method__}: Closing browser: #{where} (#{lnbr})")
534
- if $watir_script
535
- hwnd = browser.hwnd
536
- pid = Watir::IE::Process.process_id_from_hwnd(hwnd)
537
- debug_to_log("#{__method__}: Closing browser: hwnd #{hwnd} pid #{pid} #{where} (#{lnbr}) (#{__LINE__})")
538
- browser.close
539
- if browser.exists? and pid > 0 and pid < 538976288 # value of uninitialized memory location
540
- debug_to_log("Retry close browser: hwnd #{hwnd} pid #{pid} #{where} #{lnbr} (#{__LINE__})")
541
- browser.close
542
- end
543
- if browser.exists? and pid > 0 and pid < 538976288 # value of uninitialized memory location
544
- kill_browser(browser.hwnd, __LINE__, browser)
545
- end
546
- else
547
- browser.close
548
- end
549
- when 'S'
550
- if is_browser?(browser)
551
- url = browser.url
552
- title = browser.title
553
- debug_to_log("Safari browser url: [#{url}]")
554
- debug_to_log("Safari browser title: [#{title}]")
555
- debug_to_log("Closing browser: #{where} (#{lnbr})")
556
- close_modal_s # to close any leftover modal dialogs
557
- browser.close
558
- end
559
- when 'C', 'GC'
560
- if is_browser?(browser)
561
- url = browser.url
562
- title = browser.title
563
- debug_to_log("Chrome browser url: [#{url}]")
564
- debug_to_log("Chrome browser title: [#{title}]")
565
- debug_to_log("Closing browser: #{where} (#{lnbr})")
566
- if url and url.length > 1
567
- browser.close
568
- end
569
-
570
- end
571
- else
572
- raise "Unsupported browser: '#{@browserAbbrev}'"
573
- end
574
- end
575
- rescue
576
- failed_to_log(unable_to)
577
- end
578
-
579
- alias logout close_browser
580
-
581
- # Close a browser popup window. Does not apply to modal popups.
582
- # @param [Watir::Browser] popup Reference to the popup to be closed
583
- def close_new_window_popup(popup)
584
- if is_browser?(popup)
585
- url = popup.url
586
- debug_to_log("Closing popup '#{url}' ")
587
- popup.close
588
-
589
- end
590
- end
591
-
592
- # Close an HTML panel or division by clicking a link within it identified by the *:text* value of the link.
593
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
594
- # @param [Watir::Browser] panel Reference to the panel (usually a div element) to be closed
595
- def close_panel_by_text(browser, panel, what = 'Close')
596
- if validate(browser, @myName, __LINE__)
597
- if @browserAbbrev == 'IE'
598
- panel.link(:text, what).click!
599
- elsif $USE_FIREWATIR
600
- begin
601
- panel.link(:text, what).click
602
- rescue => e
603
- unless rescue_me(e, __method__, rescue_me_command(:link, :id, what, :click), "#{panel.class}")
604
- raise e
605
- end
606
- end
607
- else
608
- panel.link(:text, what).click(:wait => false)
609
- end
610
- sleep_for(1)
611
- if validate(browser, @myName, __LINE__)
612
- passed_to_log("Panel '#{what}' (by :text) closed.")
613
- true
614
- end
615
- else
616
- failed_to_log("Panel '#{strg}' (by :text) still open.")
617
- end
618
- rescue
619
- failed_to_log("Click on '#{strg}'(by :text) failed: '#{$!}' (#{__LINE__})")
620
- end
621
-
622
- #def close_modal_ie(title, button = "OK", text = '', side = 'primary', wait = WAIT, desc = '', quiet = false)
623
- # #TODO needs simplifying and debug code cleaned up
624
- # title = translate_popup_title(title)
625
- # msg = "'#{title}'"
626
- # msg << " with text '#{text}'" if text.length > 0
627
- # msg << " (#{desc})" if desc.length > 0
628
- # @ai.Opt("WinSearchChildren", 1) # Match any substring in the title
629
- # if @ai.WinWait(title, text, wait) > 0
630
- # myHandle = @ai.WinGetHandle(title, text)
631
- # full_text = @ai.WinGetText(title)
632
- # #debug_to_report("Found popup handle:'#{myHandle}', title:'#{title}', text:'#{full_text}'")
633
- # if myHandle.length > 0
634
- # debug_to_log("hwnd: #{myHandle.inspect}")
635
- # passed_to_log("#{msg} appeared.") unless quiet
636
- # sleep_for(0.5)
637
- # @ai.WinActivate(title, text)
638
- # if @ai.WinActive(title, text) # > 0 #Hack to prevent fail when windows session locked
639
- # debug_to_log("#{msg} activated.")
640
- # if @ai.ControlFocus(title, text, button) # > 0
641
- # controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
642
- # if not controlHandle
643
- # button = "&#{button}"
644
- # controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
645
- # end
646
- # debug_to_log("Handle for button '#{button}': [#{controlHandle}]")
647
- # debug_to_log("#{msg} focus gained.")
648
- # # sleep_for(2)
649
- # if @ai.ControlClick(title, text, button, side) # > 0
650
- # # if @ai.ControlClick(title, text, "[Handle:#{controlHandle}]", side) > 0
651
- # # debug_to_log("#{msg} #{side} click on 'Handle:#{controlHandle}'." )
652
- # debug_to_log("#{msg} #{side} click on '#{button}' successful.")
653
- # sleep_for(1)
654
- # if @ai.WinExists(title, text) > 0
655
- # debug_to_log("#{msg} close popup failed on click '#{button}'. Trying WinClose. (#{__LINE__})")
656
- # @ai.WinClose(title, text)
657
- # if @ai.WinExists(title, text) > 0
658
- # debug_to_log("#{msg} close popup failed with WinClose('#{title}','#{text}'). (#{__LINE__})")
659
- # @ai.WinKill(title, text)
660
- # if @ai.WinExists(title, text) > 0
661
- # debug_to_log("#{msg} close popup failed with WinKill('#{title}','#{text}'). (#{__LINE__})")
662
- # else
663
- # debug_to_log("#{msg} closed successfully with WinKill('#{title}','#{text}').")
664
- # end
665
- # else
666
- # debug_to_log("#{msg} closed successfully with WinClose('#{title}','#{text}').")
667
- # end
668
- # else
669
- # passed_to_log("#{msg} closed successfully.") unless quiet
670
- # end
671
- # else
672
- # failed_to_log("#{msg} #{side} click on '#{button}' failed. (#{__LINE__})")
673
- # end
674
- # else
675
- # failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
676
- # end
677
- # else
678
- # failed_to_log("#{msg} Unable to activate (#{__LINE__})")
679
- # end
680
- # else
681
- # failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
682
- # end
683
- # else
684
- # failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
685
- # end
686
- #rescue
687
- # failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
688
- #end
689
-
690
- # Close an browser window (popup) by clicking a link within it identified by the *:text* value of the link.
691
- # @param [Watir::Browser] popup A reference to the browser window or container element to be closed.
692
- # @param [String] what Uniquely identify the *:link* element within the popup by the value in its *:text* attribute.
693
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
694
- def close_popup_by_text(popup, what = 'Close', desc = '')
695
- count = 0
696
- url = popup.url
697
- if validate(popup, @myName, __LINE__)
698
- count = string_count_in_string(popup.text, what)
699
- if count > 0
700
- begin
701
- popup.link(:text, what).click
702
- rescue => e
703
- unless rescue_me(e, __method__, rescue_me_command(:link, :text, what, :click), "#{popup.class}")
704
- raise e
705
- end
706
- end
707
- passed_to_log("Popup #{url} closed by clicking link with text '#{what}'. #{desc}")
708
- true
709
- else
710
- failed_to_log("Link :text=>'#{what}' for popup #{url} not found. #{desc}")
711
- end
712
- end
713
- rescue
714
- failed_to_log("Close popup #{url} with click link :text+>'#{what}' failed: '#{$!}' (#{__LINE__})")
715
- debug_to_log("#{strg} appears #{count} times in popup.text.")
716
- raise
717
- end
718
-
719
- # Close a modal dialog.
720
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
721
- # @param [String] title The title of the window to be closed. Matched from beginning of string.
722
- # @param [String] button The display name of the button to be clicked.
723
- # @param [String] text The text of the window to be closed. Matched from beginning of string in Windows
724
- # with Internet Explorer (regular expressions will fail). Use enough of beginning of the text string, in quotes,
725
- # to assure the correct modal is found. This will give best portability.
726
- # @param [String] side A string identifying which mouse button to click.
727
- # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
728
- def close_modal(browser, title="", button="OK", text='', side = 'primary', wait = WAIT)
729
- case @targetBrowser.abbrev
730
- when 'IE'
731
- close_modal_ie(browser, title, button, text, side, wait)
732
- when 'FF'
733
- close_modal_ff(browser, title, button, text, side)
734
- when 'S'
735
- close_modal_s
736
- when 'C', 'GC'
737
- close_modal_c(browser, title)
738
- end
739
- end
740
-
741
- # TODO: Logging
742
- # Close a Chrome modal popup by :url.
743
- def close_modal_c(browser, url)
744
- browser.window(:url, url).close
745
- end
746
-
747
- # TODO: Logging
748
- # Close a Safari modal popup by closing the frontmost Safari dialog. Mac OSX only.
749
- def close_modal_s
750
- # simply closes the frontmost Safari dialog
751
- Appscript.app("Safari").activate
752
- Appscript.app("System Events").processes["Safari"].key_code(52)
753
- end
754
-
755
- # Close an IE modal popup by its title using AutoItX3. Windows only.
756
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
757
- # @param [String] title The title of the window to be closed. Matched from beginning of string.
758
- # @param [String] button The display name of the button to be clicked.
759
- # @param [String] text The text of the window to be closed. Matched from beginning of string. Do not use regular expression
760
- # @param [String] side A string identifying which mouse button to click.
761
- # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
762
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
763
- # @param [Boolean] quiet If true, fewer messages and pass/fail validations are logged.
764
- def close_modal_ie(browser, title="", button="OK", text='', side = 'primary', wait = WAIT, desc = '', quiet = false)
765
- #TODO needs simplifying, incorporating text verification, and debug code cleaned up
766
- title = translate_popup_title(title)
767
- msg = "Modal window (popup) '#{title}'"
768
- if @ai.WinWait(title, text, wait) > 0
769
- myHandle = @ai.WinGetHandle(title, text)
770
- if myHandle.length > 0
771
- debug_to_log("hwnd: #{myHandle.inspect}")
772
- passed_to_log("#{msg} appeared.") unless quiet
773
- window_handle = "[HANDLE:#{myHandle}]"
774
- sleep_for(0.5)
775
- @ai.WinActivate(window_handle)
776
- if @ai.WinActive(window_handle) > 0
777
- debug_to_log("#{msg} activated.")
778
- controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
779
- if not controlHandle.length > 0
780
- button = "&#{button}"
781
- controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
782
- end
783
- debug_to_log("Handle for button '#{button}': [#{controlHandle}]")
784
- debug_to_log("#{msg} focus gained.")
785
- if @ai.ControlClick(title, '', "[CLASS:Button; TEXT:#{button}]") > 0
786
- passed_to_log("#{msg} #{side} click on '[CLASS:Button; TEXT:#{button}]' successful.")
787
- sleep_for(0.5)
788
- if @ai.WinExists(window_handle) > 0
789
- debug_to_log("#{msg} close popup failed on click '#{button}'. Trying WinClose. (#{__LINE__})")
790
- @ai.WinClose(title, text)
791
- if @ai.WinExists(window_handle) > 0
792
- debug_to_log("#{msg} close popup failed with WinClose(#{window_handle}). (#{__LINE__})")
793
- @ai.WinKill(window_handle)
794
- if @ai.WinExists(window_handle) > 0
795
- debug_to_log("#{msg} close popup failed with WinKill(#{window_handle}). (#{__LINE__})")
796
- else
797
- debug_to_log("#{msg} closed successfully with WinKill(#{window_handle}).")
798
- end
799
- else
800
- debug_to_log("#{msg} closed successfully with WinClose(#{window_handle}).")
801
- end
802
- else
803
- passed_to_log("#{msg} closed successfully.")
804
- end
805
- else
806
- failed_to_log("#{msg} #{side} click on '[CLASS:Button; TEXT:#{button}]' failed. (#{window_handle}) (#{__LINE__})")
807
- end
808
- else
809
- failed_to_log("#{msg} Unable to activate (#{window_handle}) (#{__LINE__})")
810
- end
811
- else
812
- failed_to_log("#{msg} did not appear after #{wait} seconds. (#{window_handle}) (#{__LINE__})")
813
- end
814
- else
815
- failed_to_log("#{msg} did not appear after #{wait} seconds.(#{window_handle}) (#{__LINE__})")
816
- end
817
- rescue
818
- failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
819
- end
820
-
821
- #alias close_popup_validate_text close_modal_ie
822
- #alias close_popup close_modal_ie
823
-
824
- # private :close_modal_ie
825
-
826
- # Close an Internet Explorer modal popup by its title. Calls close_modal_ie. Windows only.
827
- # @deprecated Use close_modal.
828
- # @param [String] title The title of the window to be closed. Matched from beginning of string.
829
- # @param [String] button The display name of the button to be clicked.
830
- # @param [String] text The text of the window to be closed. Matched from beginning of string.
831
- # @param [String] side A string identifying which mouse button to click.
832
- # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
833
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
834
- # @param [Boolean] quiet If true, fewer messages and pass/fail validations are logged.
835
- def close_popup(title = '', button = 'OK', text = '', side = 'primary',
836
- wait = WAIT, desc = '', quiet = false)
837
- debug_to_log("#{__method__} begin")
838
- close_modal_ie(@myBrowser, title, button, text, side, wait, desc, quiet)
839
- end
840
-
841
- alias close_popup_validate_text close_popup
842
-
843
- # Close a Firefox modal popup by its title.
844
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
845
- # @param [String] title The title of the window to be closed. Matched from beginning of string.
846
- # @param [String] button The display name of the button to be clicked.
847
- # @param [String] text The text of the window to be closed. Matched from beginning of string.
848
- # @param [String] side A string identifying which mouse button to click.
849
- # @return [Boolean] True if the modal is successfully closed.
850
- def close_modal_ff(browser, title="", button=nil, text='', side='')
851
- title = translate_popup_title(title)
852
- msg = "Modal dialog (popup): title=#{title} button='#{button}' text='#{text}' side='#{side}':"
853
- modal = browser.modal_dialog(:timeout => WAIT)
854
- if modal.exists?
855
- modal_text = modal.text
856
- if text.length > 0
857
- if modal_text =~ /#{text}/
858
- passed_to_log("#{msg} appeared with match on '#{text}'.")
859
- else
860
- failed_to_log("#{msg} appeared but did not match '#{text}' ('#{modal_text}).")
861
- end
862
- else
863
- passed_to_log("#{msg} appeared.")
864
- end
865
- if button
866
- modal.click_button(button)
867
- else
868
- modal.close
869
- end
870
- if modal.exists?
871
- failed_to_log("#{msg} close failed. (#{__LINE__})")
872
- else
873
- passed_to_log("#{msg} closed successfully.")
874
- true
875
- end
876
- else
877
- failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
878
- end
879
- rescue
880
- failed_to_log("#{msg} Unable to validate modal popup: '#{$!}'. (#{__LINE__})")
881
- end
882
-
883
- # Wait for a modal popup to appear and then close it.
884
- # Used when modal popup in response to browser action is intermittent or unpredictable.
885
- # @param [String] title The title of the window to be closed. Matched from beginning of string.
886
- # @param [String] text The text of the window to be closed. Matched from beginning of string.
887
- # @param [String] button The display name of the button to be clicked.
888
- # @param [String] side A string identifying which mouse button to click.
889
- # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
890
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
891
- # @return [Boolean] True if the modal is successfully closed.
892
- def handle_popup(title, text = '', button= 'OK', side = 'primary', wait = WAIT, desc = '')
893
- title = translate_popup_title(title)
894
- msg = "'#{title}'"
895
- if text.length > 0
896
- msg << " with text '#{text}'"
897
- end
898
- @ai.Opt("WinSearchChildren", 1) # match title from start, forcing default
899
-
900
- if button and button.length > 0
901
- if button =~ /ok|yes/i
902
- id = '1'
903
- else
904
- id = '2'
905
- end
906
- else
907
- id = ''
908
- end
909
-
910
- if @ai.WinWait(title, '', wait) > 0
911
- myHandle = @ai.WinGetHandle(title, '')
912
- window_handle = "[HANDLE:#{myHandle}]"
913
- full_text = @ai.WinGetText(window_handle)
914
- debug_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text:'#{full_text}'")
915
-
916
- controlHandle = @ai.ControlGetHandle(window_handle, '', "[CLASS:Button; TEXT:#{button}]")
917
- if not controlHandle
918
- # button = "&#{button}"
919
- controlHandle = @ai.ControlGetHandle(window_handle, '', "[CLASS:Button; TEXT:&#{button}]")
920
- end
921
-
922
- if text.length > 0
923
- if full_text =~ /#{text}/
924
- passed_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text includes '#{text}'. #{desc}")
925
- else
926
- failed_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text does not include '#{text}'. Closing it. #{desc}")
927
- end
928
- end
929
-
930
- @ai.WinActivate(window_handle, '')
931
- @ai.ControlClick(window_handle, '', id, side)
932
- if @ai.WinExists(title, '') > 0
933
- debug_to_log("#{msg} @ai.ControlClick on '#{button}' (ID:#{id}) with handle '#{window_handle}' failed to close window. Trying title.")
934
- @ai.ControlClick(title, '', id, side)
935
- if @ai.WinExists(title, '') > 0
936
- debug_to_report("#{msg} @ai.ControlClick on '#{button}' (ID:#{id}) with title '#{title}' failed to close window. Forcing closed.")
937
- @ai.WinClose(title, '')
938
- if @ai.WinExists(title, '') > 0
939
- debug_to_report("#{msg} @ai.WinClose on title '#{title}' failed to close window. Killing window.")
940
- @ai.WinKill(title, '')
941
- if @ai.WinExists(title, '') > 0
942
- failed_to_log("#{msg} @ai.WinKill on title '#{title}' failed to close window")
943
- else
944
- passed_to_log("Killed: popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
945
- true
946
- end
947
- else
948
- passed_to_log("Forced closed: popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
949
- true
950
- end
951
- else
952
- passed_to_log("Closed on '#{button}': popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
953
- true
954
- end
955
- else
956
- passed_to_log("Closed on '#{button}': popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
957
- true
958
- end
959
-
960
- else
961
- failed_to_log("#{msg} did not appear after #{wait} seconds. #{desc} (#{__LINE__})")
962
- end
963
- rescue
964
- failed_to_log("Unable to handle popup #{msg}: '#{$!}' #{desc} (#{__LINE__})")
965
-
966
- end
967
-
968
- # Return a reference to an IE browser window based on one of its attributes.
969
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
970
- # @param [Symbol] how The element attribute used to identify the window: :url, :title, or :hwnd.
971
- # @param [String, Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
972
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
973
- # @return [Watir::IE] A reference to the popup.
974
- def find_popup(browser, how, what, desc = '')
975
- msg = "Find popup :#{how}=>'#{what}'. #{desc}"
976
- popup = Watir::IE.find(how, what) # TODO: too browser specific
977
- sleep_for(1)
978
- debug_to_log("#{popup.inspect}")
979
- if is_browser?(popup)
980
- # title = popup.title
981
- passed_to_log(msg)
982
- return popup
983
- else
984
- failed_to_log(msg)
985
- end
986
- rescue
987
- failed_to_log("Unable to find popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
988
- end
989
-
990
- # Confirm that the object passed in *browser* is actually a Browser object.
991
- # @param [Watir::Browser] browser A reference to the window or container element to be tested.
992
- def is_browser?(browser)
993
- myClass = browser.class.to_s
994
- case @targetBrowser.abbrev
995
- when 'IE'
996
- myClass =~ /Watir::IE|Watir::Browser/i
997
- when 'FF'
998
- myClass =~ /Watir::Browser/i
999
- when 'S'
1000
- myClass =~ /Watir::Browser/i
1001
- when 'C'
1002
- myClass =~ /Watir::Browser/i
1003
- end
1004
- end
1005
-
1006
- alias is_browser is_browser?
1007
-
1008
- # Translate window title supplied in *title* to a title appropriate for the targeted browser and version
1009
- # actually being run.
1010
- # Used primarily for handling of modal popups and dialogs.
1011
- # This allows cross-browser compatibility for handling modal popups and other windows accessed by titlt.
1012
- # @param [String] title The title of the window to be closed.
1013
- def translate_popup_title(title)
1014
- new_title = title
1015
- case @browserAbbrev
1016
- when 'IE'
1017
- if @browserVersion
1018
- case @browserVersion
1019
- when '8.0'
1020
- case title
1021
- when "Microsoft Internet Explorer"
1022
- new_title = "Message from webpage"
1023
- when "The page at"
1024
- new_title = "Message from webpage"
1025
- end
1026
- when '7.0'
1027
- case title
1028
- when "Message from webpage"
1029
- new_title = "Microsoft Internet Explorer"
1030
- when "The page at"
1031
- new_title = "Windows Internet Explorer"
1032
- end
1033
- when '6.0'
1034
- case title
1035
- when "Message from webpage"
1036
- new_title = "Microsoft Internet Explorer"
1037
- when "The page at"
1038
- new_title = "Microsoft Internet Explorer"
1039
- end
1040
- else
1041
- case title
1042
- when "Microsoft Internet Explorer"
1043
- new_title = "Message from webpage"
1044
- when "The page at"
1045
- new_title = "Message from webpage"
1046
- end
1047
- end
1048
- else
1049
- case title
1050
- when "Microsoft Internet Explorer"
1051
- new_title = "Message from webpage"
1052
- when "The page at"
1053
- new_title = "Message from webpage"
1054
- end
1055
- end
1056
- when 'FF'
1057
- case title
1058
- when 'File Download'
1059
- new_title = 'Opening'
1060
- when "Microsoft Internet Explorer"
1061
- new_title = 'The page at'
1062
- when "Message from webpage"
1063
- new_title = 'The page at'
1064
- end
1065
- when 'C'
1066
- case title
1067
- when 'File Download'
1068
- new_title = 'Save As'
1069
- when "Microsoft Internet Explorer"
1070
- new_title = 'The page at'
1071
- when "Message from webpage"
1072
- new_title = 'The page at'
1073
- end
1074
- end
1075
- new_title
1076
- end
1077
-
1078
- # Identify the exact version of the Browser currently being executed.
1079
- # @todo Bring up to date with newer browser versions
1080
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
1081
- def get_browser_version(browser)
1082
- debug_to_log("starting get_browser_version")
1083
- case @targetBrowser.abbrev
1084
- when 'IE'
1085
- @browserAbbrev = 'IE'
1086
- @browserName = 'Internet Explorer'
1087
- if $watir_script
1088
- @browserAppInfo = browser.document.invoke('parentWindow').navigator.appVersion
1089
- else
1090
- @browserAppInfo = browser.execute_script("return navigator.userAgent;")
1091
- end
1092
- @browserAppInfo =~ /MSIE\s(.*?);/
1093
- @browserVersion = $1
1094
- when 'FF'
1095
- @browserAbbrev = 'FF'
1096
- @browserName = 'Firefox'
1097
- @browserVersion = '6.01' #TODO: get actual version from browser
1098
- @browserAppInfo = browser.execute_script("return navigator.userAgent;")
1099
- debug_to_log("#{@browserName}, @browserAppInfo: (#{@browserAppInfo})")
1100
- when 'S'
1101
- @browserAbbrev = 'S'
1102
- @browserName = 'Safari'
1103
- @browserVersion = '5.0.4' #TODO: get actual version from browser itself
1104
- @browserAppInfo = browser.execute_script("return navigator.userAgent;")
1105
- debug_to_log("#{@browserName}, @browserAppInfo: (#{@browserAppInfo})")
1106
- when 'C'
1107
- @browserAbbrev = 'C'
1108
- @browserName = 'Chrome'
1109
- @browserVersion = '11.0' #TODO: get actual version from browser
1110
- @browserAppInfo = browser.execute_script("return navigator.userAgent;")
1111
- debug_to_log("#{@browserName}, @browserAppInfo: (#{@browserAppInfo})")
1112
- end
1113
- rescue
1114
- debug_to_log("Unable to determine #{@browserAbbrev} browser version: '#{$!}' (#{__LINE__})")
1115
- ensure
1116
- message_to_log("Browser: [#{@browserAbbrev} #{@browserVersion}]")
1117
- end
1118
-
1119
- protected :get_browser_version
1120
-
1121
- #def filter_bailout_from_rescue(err, msg)
1122
- # if msg =~ /bailing out/i
1123
- # raise err
1124
- # else
1125
- # error_to_log(msg)
1126
- # end
1127
- #end
1128
-
1129
- # @!group Browser
1130
-
1131
- # Open and attach a browser popup window where the link to open it and its title contain the same string.
1132
- # @deprecated
1133
- def open_popup_through_link_title(browser, title, pattern, name)
1134
- click_title(browser, title)
1135
- #TODO need some kind of wait for process here
1136
- sleep_for 2
1137
- attach_popup_by_url(browser, pattern, name)
1138
- rescue
1139
- failed_to_log("Unable to open popup '#{name}': '#{$!}' (#{__LINE__})")
1140
- end
1141
-
1142
- # @!group Error Handling
1143
-
1144
- # Verifies health of the browser. Looks for common http and system errors that are unrecoverable and
1145
- # attempts to gracefully bail out of the script.
1146
- # Calls rescue_me() when trying to capture the text to filter out known false errors
1147
- # and handle container elements that don't respond to the .text method.
1148
- # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
1149
- # @param [String] file_name The file name of the executing script.
1150
- # @param [Fixnum] lnbr Contains a message or description intended to appear in the log and/or report output
1151
- # @param [Boolean] dbg If set to true additional debug messages are written to the log.
1152
- #
1153
- # @return [Boolean] True if no error conditions have been encountered.
1154
- def validate(browser, file_name = @myName, lnbr = "#{__LINE__}", dbg = false)
1155
- debug_to_log("#{__method__} begin") if dbg
1156
- msg = ''
1157
- myOK = true
1158
- if not browser
1159
- msg = "#{file_name}----browser is nil object. (#{lnbr})"
1160
- myOK = false
1161
- elsif not browser.class.to_s =~ /Watir/
1162
- msg = "#{file_name}----not a Watir object. (#{lnbr})"
1163
- debug_to_log(browser.inspect)
1164
- myOK = false
1165
-
1166
- else
1167
- if browser.respond_to?(:url)
1168
- if not browser.url == @currentURL
1169
- @currentURL = browser.url
1170
- debug_to_log("Current URL: [#{@currentURL}]")
1171
- # mark_testlevel( "Current URL: [#{@currentURL}]", 1 )
1172
- end
1173
- end
1174
-
1175
- if @capture_js_errors
1176
- if browser.respond_to?(:status)
1177
- if browser.status.downcase =~ /errors? on page/ and
1178
- not browser.status.downcase.include?('Waiting for')
1179
- capture_js_error(browser)
1180
- end
1181
- end
1182
- end
1183
-
1184
- begin
1185
- browser_text = browser.text.downcase
1186
- rescue => e
1187
- unless rescue_me(e, __method__, "browser.text.downcase", "#{browser.class}", browser)
1188
- debug_to_log("browser.text.downcase in #{__method__} #{browser.class}")
1189
- debug_to_log("#{get_callers}")
1190
- raise e
1191
- else
1192
- return true
1193
- end
1194
- end
1195
-
1196
- if browser_text
1197
- if browser_text.match(/unrecognized error condition has occurred/i)
1198
- msg = "#{file_name}----Unrecognized Exception occurred. (#{lnbr})"
1199
- myOK = false
1200
-
1201
- elsif browser_text.match(/cannot find server or dns error/i)
1202
- msg = "#{file_name}----Cannot find server error or DNS error. (#{lnbr})"
1203
- myOK = false
1204
-
1205
- elsif browser_text.match(/the rpc server is unavailable/i)
1206
- msg = "#{file_name}----RPC server unavailable. (#{lnbr})"
1207
- myOK = false
1208
-
1209
- elsif browser_text.match(/404 not found/i) or
1210
- browser_text.match(/the page you were looking for does\s*n[o']t exist/i)
1211
- msg = "#{file_name}----RFC 2068 HTTP/1.1: 404 URI Not Found. (#{lnbr})"
1212
- myOK = false
1213
-
1214
- elsif browser_text.match(/we're sorry, but something went wrong/i) or
1215
- browser_text.match(/http status 500/i)
1216
- msg = "#{file_name}----RFC 2068 HTTP/1.1: 500 Internal Server Error. (#{lnbr})"
1217
- myOK = false
1218
-
1219
- elsif browser_text.match(/internet explorer cannot display the webpage/i)
1220
- msg = "#{file_name}----Probably RFC 2068 HTTP/1.1: 500 Internal Server Error. (#{lnbr})"
1221
- myOK = false
1222
-
1223
- elsif browser_text.match(/503.*service unavailable/i)
1224
- msg = "#{file_name}----RFC 2068 HTTP/1.1: 503 Service Unavailable. (#{lnbr})"
1225
- myOK = false
1226
-
1227
- elsif browser_text.match(/java.lang.NullPointerException/i)
1228
- msg = "#{file_name}----java.lang.NullPointerException. (#{lnbr})"
1229
- myOK = false
1230
-
1231
- elsif browser_text.match(/due to unscheduled maintenance/i)
1232
- msg = "#{file_name}----Due to unscheduled maintenance. (#{lnbr})"
1233
- myOK = false
1234
-
1235
- elsif browser_text.match(/network\s+error\s*(.+)$/i)
1236
- $1.chomp!
1237
- msg = "#{file_name}----Network Error #{$1}. (#{lnbr})"
1238
- myOK = false
1239
-
1240
- elsif browser_text.match(/warning: page has expired/i)
1241
- msg = "#{file_name}----Page using information from form has expired. Not automatically resubmitted. (#{lnbr})"
1242
- myOK = false
1243
-
1244
- elsif browser_text.match(/no backend server available/i)
1245
- msg = "#{file_name}----Cannot Reach Server (#{lnbr})"
1246
- myOK = false
1247
-
1248
- elsif browser_text.match(/sign on\s+.+\s+unsuccessful/i)
1249
- msg = "#{file_name}----Invalid Id or Password (#{lnbr})"
1250
- myOK = false
1251
-
1252
- elsif browser_text.match(/you are not authorized/i)
1253
- msg = "#{file_name}----Not authorized to view this page. (#{lnbr})"
1254
- myOK = false
1255
-
1256
- elsif browser_text.match(/too many incorrect login attempts have been made/i)
1257
- msg = "#{file_name}----Invalid Id or Password. Too many tries. (#{lnbr})"
1258
- myOK = false
1259
-
1260
- elsif browser_text.match(/system error\.\s+an error has occurred/i)
1261
- msg = "#{file_name}----System Error. An error has occurred. Please try again or call the Help Line for assistance. (#{lnbr})"
1262
- myOK = false
1263
-
1264
- elsif browser_text.match(/Internal Server failure,\s+NSAPI plugin/i)
1265
- msg = "#{file_name}----Internal Server failure, NSAPI plugin. (#{lnbr})"
1266
- myOK = false
1267
-
1268
- elsif browser_text.match(/Error Page/i)
1269
- msg = "#{file_name}----Error Page. (#{lnbr})"
1270
- myOK = false
1271
-
1272
- elsif browser_text.match(/The website cannot display the page/i)
1273
- msg = "#{file_name}----HTTP 500. (#{lnbr})"
1274
- myOK = false
1275
-
1276
- # elsif browser_text.match(/Insufficient Data/i)
1277
- # msg = "#{file_name}----Insufficient Data. (#{lnbr})"
1278
- # myOK = false
1279
-
1280
- elsif browser_text.match(/The timeout period elapsed/i)
1281
- msg = "#{file_name}----Time out period elapsed or server not responding. (#{lnbr})"
1282
- myOK = false
1283
-
1284
- elsif browser_text.match(/Unexpected\s+errors*\s+occur+ed\.\s+(?:-+)\s+(.+)/i)
1285
- msg = "#{file_name}----Unexpected errors occurred. #{$2.slice(0, 120)} (#{lnbr})"
1286
- if not browser_text.match(/close the window and try again/i)
1287
- myOK = false
1288
- else
1289
- debug_to_log("#{msg}")
1290
- end
1291
-
1292
- elsif browser_text.match(/Server Error in (.+) Application\.\s+(?:-+)\s+(.+)/i)
1293
- msg = "#{file_name}----Server Error in #{1} Application. #{$2.slice(0, 100)} (#{lnbr})"
1294
- myOK = false
1295
-
1296
- elsif browser_text.match(/Server Error in (.+) Application\./i)
1297
- msg = "#{file_name}----Server Error in #{1} Application. '#{browser_text.slice(0, 250)}...' (#{lnbr})"
1298
- myOK = false
1299
-
1300
- elsif browser_text.match(/An error has occur+ed\. Please contact support/i)
1301
- msg = "#{file_name}----An error has occurred. Please contact support (#{lnbr})"
1302
- myOK = false
1303
-
1304
- end
1305
- else
1306
- debug_to_log("browser.text returned nil")
1307
- end
1308
- end
1309
-
1310
- if not myOK
1311
- msg << " (#{browser.url})"
1312
- puts msg
1313
- debug_to_log(browser.inspect)
1314
- debug_to_log(browser.text)
1315
- fatal_to_log(msg, lnbr)
1316
- raise(RuntimeError, msg, caller)
1317
- else
1318
- debug_to_log("#{__method__} returning OK") if dbg
1319
- return myOK
1320
- end
1321
-
1322
- rescue
1323
- errmsg = $!
1324
- if errmsg and errmsg.match(msg)
1325
- errmsg = ''
1326
- end
1327
- bail_out(browser, lnbr, "#{msg} #{errmsg}")
1328
- end
1329
-
1330
- alias validate_browser validate
1331
-
1332
- # @!endgroup Error Handling
1333
-
1334
- # @!group Backward compatible usages
1335
-
1336
- # Returns a reference to a browser window using the window's *:url* attribute. Calls attach_browser().
1337
- # @example
1338
- # mainwindow = open_browser('www.google.com')
1339
- # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
1340
- # popup = attach_browser_by_url(mainwindow, '[url of new window]')
1341
- # @param [Watir::Browser] browser A reference to the current browser window.
1342
- # @param [String, Regexp] what The value in the targeted attribute that uniquely identifies the new window
1343
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
1344
- # @return [Watir::Browser]
1345
- def attach_browser_by_url(browser, what, desc = '')
1346
- attach_browser(browser, :url, what, desc)
1347
- end
1348
-
1349
- alias attach_browser_with_url attach_browser_by_url
1350
-
1351
- # Returns a reference to a new browser window identified by its *:title* attribute. Used to attach a new browser window to a variable
1352
- # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
1353
- # @param (see #attach_browser_by_url)
1354
- def attach_popup_by_title(browser, what, desc = '')
1355
- attach_popup(browser, :title, what, desc)
1356
- end
1357
-
1358
- # Returns a reference to a new browser window identified by its *:url* attribute. Used to attach a new browser window to a variable
1359
- # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
1360
- # @param (see #attach_browser_by_url)
1361
- def attach_popup_by_url(browser, what, desc = '')
1362
- attach_popup(browser, :url, what, desc)
1363
- end
1364
-
1365
- alias get_popup_with_url attach_popup_by_url
1366
- alias attach_popup_with_url attach_popup_by_url
1367
- alias attach_iepopup attach_popup_by_url
1368
-
1369
- # Close a popup browser window (non-modal) by clicking on a link with :title *what*.
1370
- # This method does not check to make sure the popup is actually closed.
1371
- # @param [Watir::Browser] popup A reference to the current popup browser window.
1372
- # @param [String, Regexp] what The value in the targeted attribute that uniquely identifies the new window
1373
- # @param [String] desc Contains a message or description intended to appear in the log and/or report output
1374
- # @return [Boolean] True if the click is successful.
1375
- def close_popup_by_button_title(popup, what, desc = '')
1376
- click(popup, :link, :title, what, desc)
1377
- end
1378
-
1379
- # @!endgroup Backward
1380
-
1381
-
1382
- end
1383
- end
1384
- end
1385
-
1
+ module Awetestlib
2
+ # Awetest DSL for browser based testing.
3
+ module Regression
4
+ # Methods to manage browser windows: open, close, attach, verify health, and clean up.
5
+ module Browser
6
+
7
+ #def run #DO WE NEED? Use this method to tell user they need to create a run method?
8
+ ## Not here in any case.
9
+ # setup
10
+ # set_script_variables
11
+ # run_test
12
+ #rescue
13
+ # fatal_to_log("(#{__LINE__}) #{$!}")
14
+ # browser.close
15
+ # raise
16
+ #end
17
+
18
+ # @!group Browser
19
+
20
+ # @note webdriver specific - still work in progress
21
+ def go_to_wd_url(browser, url)
22
+
23
+ Watir::Browser.class_eval do
24
+ def goto(uri)
25
+ uri = "http://#{uri}" unless uri =~ URI.regexp
26
+ @driver.navigate.to uri
27
+ run_checkers
28
+ end
29
+ end
30
+ browser.goto(url)
31
+
32
+ #in basic_auth1 edit:
33
+ #a = Thread.new {
34
+ # goto_wd_url(browser, @myURL)
35
+ # }
36
+
37
+ end
38
+
39
+ alias goto_wd_url go_to_wd_url
40
+
41
+ # Open a browser based on the command line parameters that identify the browser and
42
+ # version to use for the test.
43
+ # @example
44
+ # browser = open_browser('www.google.com')
45
+ # @param [String, Regexp] url When provided, the browser will go to this url.
46
+ # @return [Watir::Browser]
47
+ def open_browser(url = nil)
48
+ message_to_report("Opening browser: #{@targetBrowser.name}")
49
+ case @targetBrowser.abbrev
50
+ when 'IE'
51
+ @myBrowser = open_ie
52
+ if @myBrowser.class.to_s == "Watir::IE"
53
+ @myHwnd = @myBrowser.hwnd
54
+ end
55
+ when 'FF'
56
+ @myBrowser = open_ff_for_version
57
+ when 'S'
58
+ aBrowser = Watir::Browser.new :safari
59
+ @myBrowser = aBrowser
60
+ when 'C', 'GC'
61
+ @myBrowser = open_chrome
62
+ else
63
+ raise "Unsupported browser: #{@targetBrowser.name}"
64
+ end
65
+ if url
66
+ go_to_url(@myBrowser, url)
67
+ end
68
+ @myBrowser
69
+ end
70
+
71
+ # Open IE (Internet Explorer) browser instance.
72
+ # If global variable $watir_script is set to true in the first line of the script,
73
+ # classic Watir will be used to drive the browser,
74
+ # otherwise Watir Webdriver will be used.
75
+ # @return [Watir::Browser]
76
+ def open_ie
77
+ if $watir_script
78
+ browser = Watir::IE.new
79
+ else
80
+ browser = Watir::Browser.new :ie
81
+ end
82
+ browser
83
+ end
84
+
85
+ # Open FF (Firefox) browser instance.
86
+ # @param [Fixnum] version A number designating the version of the browser to be opened.
87
+ # @return [Watir::Browser, Firewatir::Browser]
88
+ # Returns Firewatir::Browser if target browser is Firefox version less than 4.0
89
+ def open_ff_for_version(version = @targetVersion)
90
+ browser = Watir::Browser.new :firefox
91
+ end
92
+
93
+ # Open FF (Firefox) browser instance under FireWatir.
94
+ # @return [Firewatir::Browser]
95
+ def open_ff
96
+ # Watir::Browser.default = 'firefox'
97
+ browser = Watir::Browser.new :firefox
98
+ end
99
+
100
+ # Open GC (Google Chrome) browser instance.
101
+ # @return [Watir::Browser] Browser is Google Chrome.
102
+ def open_chrome
103
+ browser = Watir::Browser.new(:chrome)
104
+ end
105
+
106
+ # Instruct browser to navigate to a specific URL
107
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
108
+ # @param [String] url When provided, the browser will go to this url.
109
+ # and the instance variable @myURL will be set to this value.
110
+ # @return [Boolean] True when navigation to url succeeds.
111
+ def go_to_url(browser, url = nil)
112
+ if url
113
+ @myURL = url
114
+ end
115
+ message_to_report("URL: #{@myURL}")
116
+ browser.goto(@myURL)
117
+ true
118
+ rescue
119
+ fatal_to_log("Unable to navigate to '#{@myURL}': '#{$!}'")
120
+ end
121
+
122
+ # Return a reference to a browser window. Used to attach a browser window to a variable
123
+ # which can then be passed to methods that require a *browser* parameter.
124
+ # @example
125
+ # mainwindow = open_browser('www.google.com')
126
+ # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
127
+ # popup = attach_browser(mainwindow, :url, '[url of new window]') #*or*
128
+ # popup = attach_browser(mainwindow, :title, '[title of new window]')
129
+ # @todo Update to work with webdriver for IE.
130
+ # @param [Watir::Browser] browser A reference to the current browser window.
131
+ # @param [Symbol] how The element attribute used to identify the window: *:title* or :url.
132
+ # @param [String|Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
133
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
134
+ # @return [Watir::Browser] Internet Explorer
135
+ def attach_browser(browser, how, what, desc = '')
136
+ debug_to_log("Attaching browser window :#{how}=>'#{what}' #{desc}")
137
+ uri_decoded_pattern = ::URI.encode(what.to_s.gsub('(?-mix:', '').gsub(')', ''))
138
+
139
+ if $watir_script
140
+ tmpbrowser = Watir::IE.attach(how, what)
141
+ browser.visible = true
142
+ if tmpbrowser
143
+ tmpbrowser.visible = true
144
+ tmpbrowser.speed = :fast
145
+ else
146
+ raise "Browser window :#{how}=>'#{what}' has at least one doc not in completed ready state."
147
+ end
148
+ else
149
+ browser.driver.switch_to.window(browser.driver.window_handles[0])
150
+ browser.window(how, /#{uri_decoded_pattern}/).use
151
+ tmpbrowser = browser
152
+ end
153
+
154
+ # case @browserAbbrev
155
+ # when 'IE'
156
+ # tmpbrowser = Watir::IE.attach(how, what)
157
+ # browser.visible = true
158
+ # if tmpbrowser
159
+ # tmpbrowser.visible = true
160
+ # tmpbrowser.speed = :fast
161
+ # else
162
+ # raise "Browser window :#{how}=>'#{what}' has at least one doc not in completed ready state."
163
+ # end
164
+ # when 'FF'
165
+ # #TODO: This may be dependent on Firefox version if webdriver doesn't support 3.6.17 and below
166
+ # browser.driver.switch_to.window(browser.driver.window_handles[0])
167
+ # browser.window(how, /#{uri_decoded_pattern}/).use
168
+ # tmpbrowser = browser
169
+ # when 'S'
170
+ # Watir::Safari.attach(how, what)
171
+ # tmpbrowser = browser
172
+ # when 'C', 'GC'
173
+ # browser.window(how, /#{uri_decoded_pattern}/).use
174
+ # tmpbrowser = browser
175
+ # end
176
+
177
+
178
+ debug_to_log("#{__method__}: tmpbrowser:#{tmpbrowser.inspect}")
179
+ tmpbrowser
180
+ end
181
+
182
+
183
+ # Returns a reference to a new browser window. Used to attach a new browser window to a variable
184
+ # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
185
+ # @example
186
+ # mainwindow = open_browser('www.google.com')
187
+ # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
188
+ # popup = attach_popup(mainwindow, :url, '[url of new window]') *or*
189
+ # popup = attach_popup(mainwindow, :title, '[title of new window]')
190
+ # @param [Watir::Browser] browser A reference to the current browser window.
191
+ # @param [Symbol] how The element attribute used to identify the window: *:title* or :url.
192
+ # @param [String, Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
193
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
194
+ # @return [Watir::Browser] The new browser window.
195
+ def attach_popup(browser, how, what, desc = '')
196
+ msg = "Attach popup :#{how}=>'#{what}'. #{desc}"
197
+ popup = attach_browser(browser, how, what, desc)
198
+ sleep_for(1)
199
+ debug_to_log("#{popup.inspect}")
200
+ if is_browser?(popup)
201
+ title = popup.title
202
+ passed_to_log("#{msg} title='#{title}'")
203
+ return popup
204
+ else
205
+ failed_to_log(msg)
206
+ end
207
+ rescue
208
+ failed_to_log("Unable to attach popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
209
+ end
210
+
211
+ # Locate and close instances of IE browsers
212
+ def find_other_browsers
213
+ cnt = 0
214
+ if @targetBrowser.abbrev == 'IE'
215
+ Watir::IE.each do |ie|
216
+ debug_to_log("#{ie.inspect}")
217
+ ie.close()
218
+ cnt = cnt + 1
219
+ end
220
+ end
221
+ debug_to_log("Found #{cnt} IE browser(s).")
222
+ return cnt
223
+ rescue
224
+ error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}", __LINE__)
225
+ return 0
226
+ end
227
+
228
+ # @!endgroup Browser
229
+
230
+ # @!group Login
231
+
232
+ # Simple login method
233
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
234
+ # @param [String] user Login ID for the user.
235
+ # @param [String] password Password for the user.
236
+ # @return [Boolean] True if login succeeds.
237
+ def login(browser, user, password)
238
+ #TODO: Needs to be more flexible about finding login id and password textfields
239
+ #TODO: Parameterize url and remove references to environment
240
+ myURL = @myAppEnv.url
241
+ runenv = @myAppEnv.nodename
242
+ message_tolog("URL: #{myURL}") if @myAppEnv
243
+ message_tolog("Beginning login: User: #{user} Environment: #{@myAppEnv.nodename}") if @myAppEnv
244
+ if validate(browser, @myName, __LINE__)
245
+ browser.goto(@myAppEnv.url)
246
+ if validate(browser, @myName)
247
+ set_textfield_by_name(browser, 'loginId', user)
248
+ set_textfield_by_name(browser, 'password', password)
249
+ click_button_by_value(browser, 'Login')
250
+ if validate(browser, @myName)
251
+ passed_to_log("Login successful.")
252
+ true
253
+ end
254
+ else
255
+ failed_to_log("Unable to login to application: '#{$!}'")
256
+ #screen_capture( "#{@myRoot}/screens/#{myName}_#{@runid}_#{__LINE__.to_s}_#{Time.new.to_f.to_s}.jpg")
257
+ end
258
+ end
259
+ rescue
260
+ failed_to_log("Unable to login to application: '#{$!}'")
261
+ end
262
+
263
+ # Logon to webpage using Basic Authorization type of logon. Uses AutoIt
264
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
265
+ # @param [String] user Login ID for the user.
266
+ # @param [String] password Password for the user.
267
+ # @param [String] url The URL to log on to.
268
+ # @param [Boolean] bypass_validate When set to true, the call to validate(),
269
+ # which checks the health of the browser, is skipped..
270
+ def basic_auth(browser, user, password, url, bypass_validate = false)
271
+ mark_testlevel("Basic Authorization Login", 0)
272
+
273
+ message_to_report ("Login: #{user}")
274
+ message_to_report ("URL: #{url}")
275
+ message_to_report ("Password: #{password}")
276
+
277
+ @login_title = "Connect to"
278
+
279
+ a = Thread.new {
280
+ browser.goto(url)
281
+ }
282
+
283
+ sleep_for(2)
284
+ message_to_log("#{@login_title}...")
285
+
286
+ if (@ai.WinWait(@login_title, "", 90) > 0)
287
+ win_title = @ai.WinGetTitle(@login_title)
288
+ debug_to_log("Basic Auth Login window appeared: '#{win_title}'")
289
+ @ai.WinActivate(@login_title)
290
+ @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", '!u')
291
+ @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", user, 1)
292
+ @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:3]", password.gsub(/!/, '{!}'), 1)
293
+ @ai.ControlClick(@login_title, "", '[CLASS:Button; INSTANCE:1]')
294
+ else
295
+ debug_to_log("Basic Auth Login window did not appear.")
296
+ end
297
+ a.join
298
+
299
+ validate(browser, @myName) unless bypass_validate
300
+
301
+ message_to_report("URL: [#{browser.url}] User: [#{user}]")
302
+
303
+ end
304
+
305
+ # Provide an authorization token or passcode in a specified text field element identified by its *:id* attribute.
306
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
307
+ # @param [String] role Usually a user role designation ('Administrator', 'User', etc.)
308
+ # @param [String] token Authentification token required by logon process.
309
+ # @param [String/Regexp] id Value of the *:id* attribute of the text field that will receive the *token*.
310
+ def token_auth(browser, role, token, id = 'token_pass')
311
+ set_textfield_by_id(browser, id, token)
312
+ click_button_by_value(browser, 'Continue')
313
+ if validate_text(browser, 'The requested page requires authentication\.\s*Please enter your Passcode below', nil, true)
314
+ bail_out(browser, __LINE__, "Token authorization failed on '#{token}'")
315
+ end
316
+ end
317
+
318
+ # @!endgroup Logon
319
+
320
+ # @!group Error Handling
321
+
322
+ # Exit more or less gracefully from script when errors are too severe to continue.
323
+ # Normally not called in a test script or project library.
324
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
325
+ # @param [Fixnum] lnbr Line number in calling script.
326
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
327
+ #
328
+ def bail_out(browser, lnbr, desc)
329
+ ts = Time.new
330
+ msg = "Bailing out at util line #{lnbr} #{ts} " + desc
331
+ puts "#{msg}"
332
+ fatal_to_log(msg, lnbr)
333
+ debug_to_log(dump_caller(lnbr))
334
+ if is_browser?(browser)
335
+ if @browserAbbrev == 'IE'
336
+ hwnd = browser.hwnd
337
+ kill_browser(hwnd, lnbr, browser)
338
+ raise(RuntimeError, msg, caller)
339
+ elsif @browserAbbrev == 'FF'
340
+ debug_to_log("#{browser.inspect}")
341
+ debug_to_log("#{browser.to_s}")
342
+ raise(RuntimeError, msg, caller)
343
+ end
344
+ end
345
+ @status = 'bailout'
346
+ raise(RuntimeError, msg, caller)
347
+ end
348
+
349
+
350
+ # Check for the presence of IE browser instances.
351
+ # @return [Fixnum] The number of IE browser instances encountered.
352
+ def check_for_other_browsers
353
+ cnt1 = find_other_browsers
354
+ cnt2 = Watir::Process.count 'iexplore.exe'
355
+ debug_to_log("check_for_other_browsers: cnt1: #{cnt1} cnt2: #{cnt2}")
356
+ rescue
357
+ error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}")
358
+ end
359
+
360
+ # Check for the presence of IE browser instances and close all that are found.
361
+ def check_for_and_clear_other_browsers
362
+ if @targetBrowser.abbrev == 'IE'
363
+ debug_to_log("#{__method__}:")
364
+ cnt1 = find_other_browsers
365
+ cnt2 = Watir::IE.process_count
366
+ debug_to_log("#{__method__}: cnt1: #{cnt1} cnt2: #{cnt2}")
367
+ begin
368
+ Watir::IE.each do |ie|
369
+ pid = Watir::IE::Process.process_id_from_hwnd(ie.hwnd)
370
+ debug_to_log("#{__method__}: Killing browser process: hwnd #{ie.hwnd} pid #{pid} title '#{ie.title}' (#{__LINE__})")
371
+ do_taskkill(INFO, pid)
372
+ sleep_for(10)
373
+ end
374
+ #Watir::IE.close_all()
375
+ rescue
376
+ debug_to_log("#{__method__}: #{$!} (#{__LINE__})")
377
+ end
378
+ sleep(3)
379
+ cnt1 = find_other_browsers
380
+ cnt2 = Watir::IE.process_count
381
+ if cnt1 > 0 or cnt2 > 0
382
+ debug_to_log("#{__method__}:cnt1: #{cnt1} cnt2: #{cnt2}")
383
+ begin
384
+ Watir::IE.each do |ie|
385
+ pid = Watir::IE::Process.process_id_from_hwnd(ie.hwnd)
386
+ debug_to_log("#{__method__}: Killing browser process: hwnd #{ie.hwnd} pid #{pid} title '#{ie.title}' (#{__LINE__})")
387
+ do_taskkill(INFO, pid)
388
+ sleep_for(10)
389
+ end
390
+ #Watir::IE.close_all()
391
+ rescue
392
+ debug_to_log("#{__method__}:#{$!} (#{__LINE__})")
393
+ end
394
+ end
395
+ end
396
+ rescue
397
+ error_to_log("#{__method__}: #{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}")
398
+ end
399
+
400
+ # Force browser instance to close, one way or the other.
401
+ # Instance is identified by *hwnd*, the Windows OS handle for the process.
402
+ # @param [String] hwnd The value for the window handle for the browser process.
403
+ # @param [Fixnum] lnbr Line number in calling script.
404
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be closed.
405
+ def kill_browser(hwnd, lnbr, browser = nil, doflag = false)
406
+ # TODO Firefox
407
+ logit = false
408
+ if @browserAbbrev == 'FF'
409
+ if is_browser?(browser) # and browser.url.length > 1
410
+ logit = true
411
+ here = __LINE__
412
+ url = browser.url
413
+ #capture_screen(browser, Time.new.to_f) if @screenCaptureOn
414
+ browser.close if url.length > 0
415
+ @status = 'killbrowser'
416
+ fatal_to_log("Kill browser called from line #{lnbr}")
417
+ end
418
+ elsif hwnd
419
+ pid = Watir::IE::Process.process_id_from_hwnd(hwnd)
420
+ if pid and pid > 0 and pid < 538976288
421
+ if browser.exists?
422
+ here = __LINE__
423
+ logit = true
424
+ url = browser.url
425
+ #capture_screen(browser, Time.new.to_f) if @screenCaptureOn
426
+ browser.close
427
+ sleep(2)
428
+ if browser.exists?
429
+ do_taskkill(FATAL, pid)
430
+ end
431
+ @status = 'killbrowser'
432
+ end
433
+ end
434
+ if logit
435
+ debug_to_log("#{@browserName} window hwnd #{hwnd} pid #{pid} #{url} (#{here})")
436
+ fatal_to_log("Kill browser called from line #{lnbr}")
437
+ end
438
+ end
439
+ end
440
+
441
+ # @!endgroup Error Handling
442
+
443
+ # @!group Browser
444
+
445
+ # Use enabled_popup and winclicker to determine if there is an active modal popup.
446
+ # Useful only when no wait action has been invoked.
447
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
448
+ # @param [String] button The visible name of the button to be clicked to close the popup.
449
+ # @return [String] containing the window handle of the closed modal popup.
450
+ def modal_exists?(browser, button = nil)
451
+ rtrn = nil
452
+ if @browserAbbrev == 'IE'
453
+ Timeout::timeout(2) do
454
+ begin
455
+ if browser.enabled_popup
456
+ hwnd = browser.enabled_popup(5)
457
+ debug_to_log("Modal popup with handle #{hwnd} found. (#{__LINE__})")
458
+ wc = WinClicker.new
459
+ wc.makeWindowActive(hwnd)
460
+ rtrn = wc.getWindowTitle(hwnd)
461
+ if button
462
+ wc.clickWindowsButton_hWnd(hwnd, button)
463
+ end
464
+ wc = nil
465
+ end
466
+ rescue Timeout::Error
467
+ debug_to_log("No Modal popup found. (#{__LINE__})")
468
+ return rtrn
469
+ end
470
+ return rtrn
471
+ end
472
+ rtrn
473
+ else
474
+ rtrn
475
+ end
476
+ end
477
+
478
+ # Close a browser window identified by its title.
479
+ # Uses AutoIt. Windows only.
480
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
481
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
482
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
483
+ # @param [String] text (optional) The text of the window to be closed. Matched from beginning of string.
484
+ def close_window_by_title(browser, title, desc = '', text = '')
485
+ msg = "Window '#{title}':"
486
+ if @ai.WinWait(title, text, WAIT) > 0
487
+ passed_to_log("#{msg} appeared. #{desc}")
488
+ myHandle = @ai.WinGetHandle(title, text)
489
+ full_text = @ai.WinGetText(title)
490
+ debug_to_log("#{msg} hwnd: #{myHandle.inspect}")
491
+ debug_to_log("#{msg} title: '#{title}' text: '#{full_text}'")
492
+ if @ai.WinClose(title, text) > 0
493
+ passed_to_log("#{msg} closed successfully. #{desc}")
494
+ else
495
+ failed_to_log("#{msg} close failed. (#{__LINE__}) #{desc}")
496
+ end
497
+ else
498
+ failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__}) #{desc}")
499
+ end
500
+ rescue
501
+ failed_to_log("#{msg}: Unable to close: '#{$!}'. (#{__LINE__}) #{desc}")
502
+ end
503
+
504
+ # Closes main browser session. Misnamed. Usually used at end of script to shut down browser.
505
+ def logout(browser, where = @myName, lnbr = __LINE__)
506
+ #TODO Firewatir 1.6.5 does not implement .exists for FireWatir::Firefox class
507
+ debug_to_log("Logging out in #{where} at line #{lnbr}.", lnbr, true)
508
+ debug_to_log("#{__method__}: browser: #{browser.inspect} (#{__LINE__})")
509
+
510
+ if ['FF', 'S'].include?(@browserAbbrev) || browser.exists?
511
+ case @browserAbbrev
512
+ when 'FF'
513
+ if is_browser?(browser)
514
+ url = browser.url
515
+ title = browser.title
516
+ debug_to_log("#{__method__}: Firefox browser url: [#{url}]")
517
+ debug_to_log("#{__method__}: Firefox browser title: [#{title}]")
518
+ debug_to_log("#{__method__}: Closing browser: #{where} (#{lnbr})")
519
+ if url and url.length > 1
520
+ browser.close
521
+ else
522
+ browser = FireWatir::Firefox.attach(:title, title)
523
+ browser.close
524
+ end
525
+
526
+ end
527
+ when 'IE'
528
+ hwnd = browser.hwnd
529
+ pid = Watir::IE::Process.process_id_from_hwnd(hwnd)
530
+ debug_to_log("#{__method__}: Closing browser: hwnd #{hwnd} pid #{pid} #{where} (#{lnbr}) (#{__LINE__})")
531
+ browser.close
532
+ if browser.exists? and pid > 0 and pid < 538976288 # value of uninitialized memory location
533
+ debug_to_log("Retry close browser: hwnd #{hwnd} pid #{pid} #{where} #{lnbr} (#{__LINE__})")
534
+ browser.close
535
+ end
536
+ if browser.exists? and pid > 0 and pid < 538976288 # value of uninitialized memory location
537
+ kill_browser(browser.hwnd, __LINE__, browser)
538
+ end
539
+ when 'S'
540
+ if is_browser?(browser)
541
+ url = browser.url
542
+ title = browser.title
543
+ debug_to_log("Safari browser url: [#{url}]")
544
+ debug_to_log("Safari browser title: [#{title}]")
545
+ debug_to_log("Closing browser: #{where} (#{lnbr})")
546
+ close_modal_s # to close any leftover modal dialogs
547
+ browser.close
548
+ end
549
+ when 'C', 'GC'
550
+ if is_browser?(browser)
551
+ url = browser.url
552
+ title = browser.title
553
+ debug_to_log("Chrome browser url: [#{url}]")
554
+ debug_to_log("Chrome browser title: [#{title}]")
555
+ debug_to_log("Closing browser: #{where} (#{lnbr})")
556
+ if url and url.length > 1
557
+ browser.close
558
+ #else
559
+ #browser = FireWatir::Firefox.attach(:title, title)
560
+ #browser.close
561
+ end
562
+
563
+ end
564
+ else
565
+ raise "Unsupported browser: '#{@browserAbbrev}'"
566
+ end
567
+ end
568
+ # rescue => e
569
+ # if not e.is_a?(Vapir::WindowGoneException)
570
+ # raise e
571
+ # end
572
+ end
573
+
574
+ # Close a browser popup window. Does not apply to modal popups.
575
+ # @param [Watir::Browser] popup Reference to the popup to be closed
576
+ def close_new_window_popup(popup)
577
+ if is_browser?(popup)
578
+ url = popup.url
579
+ debug_to_log("Closing popup '#{url}' ")
580
+ popup.close
581
+
582
+ end
583
+ end
584
+
585
+ # Close an HTML panel or division by clicking a link within it identified by the *:text* value of the link.
586
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
587
+ # @param [Watir::Browser] panel Reference to the panel (usually a div element) to be closed
588
+ def close_panel_by_text(browser, panel, what = 'Close')
589
+ if validate(browser, @myName, __LINE__)
590
+ if @browserAbbrev == 'IE'
591
+ panel.link(:text, what).click!
592
+ elsif $USE_FIREWATIR
593
+ begin
594
+ panel.link(:text, what).click
595
+ rescue => e
596
+ unless rescue_me(e, __method__, rescue_me_command(:link, :id, what, :click), "#{panel.class}")
597
+ raise e
598
+ end
599
+ end
600
+ else
601
+ panel.link(:text, what).click(:wait => false)
602
+ end
603
+ sleep_for(1)
604
+ if validate(browser, @myName, __LINE__)
605
+ passed_to_log("Panel '#{what}' (by :text) closed.")
606
+ true
607
+ end
608
+ else
609
+ failed_to_log("Panel '#{strg}' (by :text) still open.")
610
+ end
611
+ rescue
612
+ failed_to_log("Click on '#{strg}'(by :text) failed: '#{$!}' (#{__LINE__})")
613
+ end
614
+
615
+ #def close_modal_ie(title, button = "OK", text = '', side = 'primary', wait = WAIT, desc = '', quiet = false)
616
+ # #TODO needs simplifying and debug code cleaned up
617
+ # title = translate_popup_title(title)
618
+ # msg = "'#{title}'"
619
+ # msg << " with text '#{text}'" if text.length > 0
620
+ # msg << " (#{desc})" if desc.length > 0
621
+ # @ai.Opt("WinSearchChildren", 1) # Match any substring in the title
622
+ # if @ai.WinWait(title, text, wait) > 0
623
+ # myHandle = @ai.WinGetHandle(title, text)
624
+ # full_text = @ai.WinGetText(title)
625
+ # #debug_to_report("Found popup handle:'#{myHandle}', title:'#{title}', text:'#{full_text}'")
626
+ # if myHandle.length > 0
627
+ # debug_to_log("hwnd: #{myHandle.inspect}")
628
+ # passed_to_log("#{msg} appeared.") unless quiet
629
+ # sleep_for(0.5)
630
+ # @ai.WinActivate(title, text)
631
+ # if @ai.WinActive(title, text) # > 0 #Hack to prevent fail when windows session locked
632
+ # debug_to_log("#{msg} activated.")
633
+ # if @ai.ControlFocus(title, text, button) # > 0
634
+ # controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
635
+ # if not controlHandle
636
+ # button = "&#{button}"
637
+ # controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
638
+ # end
639
+ # debug_to_log("Handle for button '#{button}': [#{controlHandle}]")
640
+ # debug_to_log("#{msg} focus gained.")
641
+ # # sleep_for(2)
642
+ # if @ai.ControlClick(title, text, button, side) # > 0
643
+ # # if @ai.ControlClick(title, text, "[Handle:#{controlHandle}]", side) > 0
644
+ # # debug_to_log("#{msg} #{side} click on 'Handle:#{controlHandle}'." )
645
+ # debug_to_log("#{msg} #{side} click on '#{button}' successful.")
646
+ # sleep_for(1)
647
+ # if @ai.WinExists(title, text) > 0
648
+ # debug_to_log("#{msg} close popup failed on click '#{button}'. Trying WinClose. (#{__LINE__})")
649
+ # @ai.WinClose(title, text)
650
+ # if @ai.WinExists(title, text) > 0
651
+ # debug_to_log("#{msg} close popup failed with WinClose('#{title}','#{text}'). (#{__LINE__})")
652
+ # @ai.WinKill(title, text)
653
+ # if @ai.WinExists(title, text) > 0
654
+ # debug_to_log("#{msg} close popup failed with WinKill('#{title}','#{text}'). (#{__LINE__})")
655
+ # else
656
+ # debug_to_log("#{msg} closed successfully with WinKill('#{title}','#{text}').")
657
+ # end
658
+ # else
659
+ # debug_to_log("#{msg} closed successfully with WinClose('#{title}','#{text}').")
660
+ # end
661
+ # else
662
+ # passed_to_log("#{msg} closed successfully.") unless quiet
663
+ # end
664
+ # else
665
+ # failed_to_log("#{msg} #{side} click on '#{button}' failed. (#{__LINE__})")
666
+ # end
667
+ # else
668
+ # failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
669
+ # end
670
+ # else
671
+ # failed_to_log("#{msg} Unable to activate (#{__LINE__})")
672
+ # end
673
+ # else
674
+ # failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
675
+ # end
676
+ # else
677
+ # failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
678
+ # end
679
+ #rescue
680
+ # failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
681
+ #end
682
+
683
+ # Close an browser window (popup) by clicking a link within it identified by the *:text* value of the link.
684
+ # @param [Watir::Browser] popup A reference to the browser window or container element to be closed.
685
+ # @param [String] what Uniquely identify the *:link* element within the popup by the value in its *:text* attribute.
686
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
687
+ def close_popup_by_text(popup, what = 'Close', desc = '')
688
+ count = 0
689
+ url = popup.url
690
+ if validate(popup, @myName, __LINE__)
691
+ count = string_count_in_string(popup.text, what)
692
+ if count > 0
693
+ begin
694
+ popup.link(:text, what).click
695
+ rescue => e
696
+ unless rescue_me(e, __method__, rescue_me_command(:link, :text, what, :click), "#{popup.class}")
697
+ raise e
698
+ end
699
+ end
700
+ passed_to_log("Popup #{url} closed by clicking link with text '#{what}'. #{desc}")
701
+ true
702
+ else
703
+ failed_to_log("Link :text=>'#{what}' for popup #{url} not found. #{desc}")
704
+ end
705
+ end
706
+ rescue
707
+ failed_to_log("Close popup #{url} with click link :text+>'#{what}' failed: '#{$!}' (#{__LINE__})")
708
+ debug_to_log("#{strg} appears #{count} times in popup.text.")
709
+ raise
710
+ end
711
+
712
+ # Close a modal dialog.
713
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
714
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
715
+ # @param [String] button The display name of the button to be clicked.
716
+ # @param [String] text The text of the window to be closed. Matched from beginning of string in Windows
717
+ # with Internet Explorer (regular expressions will fail). Use enough of beginning of the text string, in quotes,
718
+ # to assure the correct modal is found. This will give best portability.
719
+ # @param [String] side A string identifying which mouse button to click.
720
+ # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
721
+ def close_modal(browser, title="", button="OK", text='', side = 'primary', wait = WAIT)
722
+ case @targetBrowser.abbrev
723
+ when 'IE'
724
+ close_modal_ie(browser, title, button, text, side, wait)
725
+ when 'FF'
726
+ close_modal_ff(browser, title, button, text, side)
727
+ when 'S'
728
+ close_modal_s
729
+ when 'C', 'GC'
730
+ close_modal_c(browser, title)
731
+ end
732
+ end
733
+
734
+ # TODO: Logging
735
+ # Close a Chrome modal popup by :url.
736
+ def close_modal_c(browser, url)
737
+ browser.window(:url, url).close
738
+ end
739
+
740
+ # TODO: Logging
741
+ # Close a Safari modal popup by closing the frontmost Safari dialog. Mac OSX only.
742
+ def close_modal_s
743
+ # simply closes the frontmost Safari dialog
744
+ Appscript.app("Safari").activate
745
+ Appscript.app("System Events").processes["Safari"].key_code(52)
746
+ end
747
+
748
+ # Close an IE modal popup by its title using AutoItX3. Windows only.
749
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
750
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
751
+ # @param [String] button The display name of the button to be clicked.
752
+ # @param [String] text The text of the window to be closed. Matched from beginning of string. Do not use regular expression
753
+ # @param [String] side A string identifying which mouse button to click.
754
+ # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
755
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
756
+ # @param [Boolean] quiet If true, fewer messages and pass/fail validations are logged.
757
+ def close_modal_ie(browser, title="", button="OK", text='', side = 'primary', wait = WAIT, desc = '', quiet = false)
758
+ #TODO needs simplifying, incorporating text verification, and debug code cleaned up
759
+ title = translate_popup_title(title)
760
+ msg = "Modal window (popup) '#{title}'"
761
+ if @ai.WinWait(title, text, wait) > 0
762
+ myHandle = @ai.WinGetHandle(title, text)
763
+ if myHandle.length > 0
764
+ debug_to_log("hwnd: #{myHandle.inspect}")
765
+ passed_to_log("#{msg} appeared.") unless quiet
766
+ window_handle = "[HANDLE:#{myHandle}]"
767
+ sleep_for(0.5)
768
+ @ai.WinActivate(window_handle)
769
+ if @ai.WinActive(window_handle) > 0
770
+ debug_to_log("#{msg} activated.")
771
+ controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
772
+ if not controlHandle.length > 0
773
+ button = "&#{button}"
774
+ controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
775
+ end
776
+ debug_to_log("Handle for button '#{button}': [#{controlHandle}]")
777
+ debug_to_log("#{msg} focus gained.")
778
+ if @ai.ControlClick(title, '', "[CLASS:Button; TEXT:#{button}]") > 0
779
+ passed_to_log("#{msg} #{side} click on '[CLASS:Button; TEXT:#{button}]' successful.")
780
+ sleep_for(0.5)
781
+ if @ai.WinExists(window_handle) > 0
782
+ debug_to_log("#{msg} close popup failed on click '#{button}'. Trying WinClose. (#{__LINE__})")
783
+ @ai.WinClose(title, text)
784
+ if @ai.WinExists(window_handle) > 0
785
+ debug_to_log("#{msg} close popup failed with WinClose(#{window_handle}). (#{__LINE__})")
786
+ @ai.WinKill(window_handle)
787
+ if @ai.WinExists(window_handle) > 0
788
+ debug_to_log("#{msg} close popup failed with WinKill(#{window_handle}). (#{__LINE__})")
789
+ else
790
+ debug_to_log("#{msg} closed successfully with WinKill(#{window_handle}).")
791
+ end
792
+ else
793
+ debug_to_log("#{msg} closed successfully with WinClose(#{window_handle}).")
794
+ end
795
+ else
796
+ passed_to_log("#{msg} closed successfully.")
797
+ end
798
+ else
799
+ failed_to_log("#{msg} #{side} click on '[CLASS:Button; TEXT:#{button}]' failed. (#{window_handle}) (#{__LINE__})")
800
+ end
801
+ else
802
+ failed_to_log("#{msg} Unable to activate (#{window_handle}) (#{__LINE__})")
803
+ end
804
+ else
805
+ failed_to_log("#{msg} did not appear after #{wait} seconds. (#{window_handle}) (#{__LINE__})")
806
+ end
807
+ else
808
+ failed_to_log("#{msg} did not appear after #{wait} seconds.(#{window_handle}) (#{__LINE__})")
809
+ end
810
+ rescue
811
+ failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
812
+ end
813
+
814
+ #alias close_popup_validate_text close_modal_ie
815
+ #alias close_popup close_modal_ie
816
+
817
+ # private :close_modal_ie
818
+
819
+ # Close an Internet Explorer modal popup by its title. Calls close_modal_ie. Windows only.
820
+ # @deprecated Use close_modal.
821
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
822
+ # @param [String] button The display name of the button to be clicked.
823
+ # @param [String] text The text of the window to be closed. Matched from beginning of string.
824
+ # @param [String] side A string identifying which mouse button to click.
825
+ # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
826
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
827
+ # @param [Boolean] quiet If true, fewer messages and pass/fail validations are logged.
828
+ def close_popup(title = '', button = 'OK', text = '', side = 'primary',
829
+ wait = WAIT, desc = '', quiet = false)
830
+ debug_to_log("#{__method__} begin")
831
+ close_modal_ie(@myBrowser, title, button, text, side, wait, desc, quiet)
832
+ end
833
+
834
+ alias close_popup_validate_text close_popup
835
+
836
+ # Close a Firefox modal popup by its title.
837
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
838
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
839
+ # @param [String] button The display name of the button to be clicked.
840
+ # @param [String] text The text of the window to be closed. Matched from beginning of string.
841
+ # @param [String] side A string identifying which mouse button to click.
842
+ # @return [Boolean] True if the modal is successfully closed.
843
+ def close_modal_ff(browser, title="", button=nil, text='', side='')
844
+ title = translate_popup_title(title)
845
+ msg = "Modal dialog (popup): title=#{title} button='#{button}' text='#{text}' side='#{side}':"
846
+ modal = browser.modal_dialog(:timeout => WAIT)
847
+ if modal.exists?
848
+ modal_text = modal.text
849
+ if text.length > 0
850
+ if modal_text =~ /#{text}/
851
+ passed_to_log("#{msg} appeared with match on '#{text}'.")
852
+ else
853
+ failed_to_log("#{msg} appeared but did not match '#{text}' ('#{modal_text}).")
854
+ end
855
+ else
856
+ passed_to_log("#{msg} appeared.")
857
+ end
858
+ if button
859
+ modal.click_button(button)
860
+ else
861
+ modal.close
862
+ end
863
+ if modal.exists?
864
+ failed_to_log("#{msg} close failed. (#{__LINE__})")
865
+ else
866
+ passed_to_log("#{msg} closed successfully.")
867
+ true
868
+ end
869
+ else
870
+ failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
871
+ end
872
+ rescue
873
+ failed_to_log("#{msg} Unable to validate modal popup: '#{$!}'. (#{__LINE__})")
874
+ end
875
+
876
+ # Wait for a modal popup to appear and then close it.
877
+ # Used when modal popup in response to browser action is intermittent or unpredictable.
878
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
879
+ # @param [String] text The text of the window to be closed. Matched from beginning of string.
880
+ # @param [String] button The display name of the button to be clicked.
881
+ # @param [String] side A string identifying which mouse button to click.
882
+ # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
883
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
884
+ # @return [Boolean] True if the modal is successfully closed.
885
+ def handle_popup(title, text = '', button= 'OK', side = 'primary', wait = WAIT, desc = '')
886
+ title = translate_popup_title(title)
887
+ msg = "'#{title}'"
888
+ if text.length > 0
889
+ msg << " with text '#{text}'"
890
+ end
891
+ @ai.Opt("WinSearchChildren", 1) # match title from start, forcing default
892
+
893
+ if button and button.length > 0
894
+ if button =~ /ok|yes/i
895
+ id = '1'
896
+ else
897
+ id = '2'
898
+ end
899
+ else
900
+ id = ''
901
+ end
902
+
903
+ if @ai.WinWait(title, '', wait) > 0
904
+ myHandle = @ai.WinGetHandle(title, '')
905
+ window_handle = "[HANDLE:#{myHandle}]"
906
+ full_text = @ai.WinGetText(window_handle)
907
+ debug_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text:'#{full_text}'")
908
+
909
+ controlHandle = @ai.ControlGetHandle(window_handle, '', "[CLASS:Button; TEXT:#{button}]")
910
+ if not controlHandle
911
+ # button = "&#{button}"
912
+ controlHandle = @ai.ControlGetHandle(window_handle, '', "[CLASS:Button; TEXT:&#{button}]")
913
+ end
914
+
915
+ if text.length > 0
916
+ if full_text =~ /#{text}/
917
+ passed_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text includes '#{text}'. #{desc}")
918
+ else
919
+ failed_to_log("Found popup handle:'#{myHandle}', title:'#{title}', text does not include '#{text}'. Closing it. #{desc}")
920
+ end
921
+ end
922
+
923
+ @ai.WinActivate(window_handle, '')
924
+ @ai.ControlClick(window_handle, '', id, side)
925
+ if @ai.WinExists(title, '') > 0
926
+ debug_to_log("#{msg} @ai.ControlClick on '#{button}' (ID:#{id}) with handle '#{window_handle}' failed to close window. Trying title.")
927
+ @ai.ControlClick(title, '', id, side)
928
+ if @ai.WinExists(title, '') > 0
929
+ debug_to_report("#{msg} @ai.ControlClick on '#{button}' (ID:#{id}) with title '#{title}' failed to close window. Forcing closed.")
930
+ @ai.WinClose(title, '')
931
+ if @ai.WinExists(title, '') > 0
932
+ debug_to_report("#{msg} @ai.WinClose on title '#{title}' failed to close window. Killing window.")
933
+ @ai.WinKill(title, '')
934
+ if @ai.WinExists(title, '') > 0
935
+ failed_to_log("#{msg} @ai.WinKill on title '#{title}' failed to close window")
936
+ else
937
+ passed_to_log("Killed: popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
938
+ true
939
+ end
940
+ else
941
+ passed_to_log("Forced closed: popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
942
+ true
943
+ end
944
+ else
945
+ passed_to_log("Closed on '#{button}': popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
946
+ true
947
+ end
948
+ else
949
+ passed_to_log("Closed on '#{button}': popup handle:'#{myHandle}', title:'#{title}'. #{desc}")
950
+ true
951
+ end
952
+
953
+ else
954
+ failed_to_log("#{msg} did not appear after #{wait} seconds. #{desc} (#{__LINE__})")
955
+ end
956
+ rescue
957
+ failed_to_log("Unable to handle popup #{msg}: '#{$!}' #{desc} (#{__LINE__})")
958
+
959
+ end
960
+
961
+ # Return a reference to an IE browser window based on one of its attributes.
962
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
963
+ # @param [Symbol] how The element attribute used to identify the window: :url, :title, or :hwnd.
964
+ # @param [String, Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
965
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
966
+ # @return [Watir::IE] A reference to the popup.
967
+ def find_popup(browser, how, what, desc = '')
968
+ msg = "Find popup :#{how}=>'#{what}'. #{desc}"
969
+ popup = Watir::IE.find(how, what) # TODO: too browser specific
970
+ sleep_for(1)
971
+ debug_to_log("#{popup.inspect}")
972
+ if is_browser?(popup)
973
+ # title = popup.title
974
+ passed_to_log(msg)
975
+ return popup
976
+ else
977
+ failed_to_log(msg)
978
+ end
979
+ rescue
980
+ failed_to_log("Unable to find popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
981
+ end
982
+
983
+ # Confirm that the object passed in *browser* is actually a Browser object.
984
+ # @param [Watir::Browser] browser A reference to the window or container element to be tested.
985
+ def is_browser?(browser)
986
+ myClass = browser.class.to_s
987
+ case @targetBrowser.abbrev
988
+ when 'IE'
989
+ myClass =~ /Watir::IE|Watir::Browser/i
990
+ when 'FF'
991
+ myClass =~ /Watir::Browser/i
992
+ when 'S'
993
+ myClass =~ /Watir::Browser/i
994
+ when 'C'
995
+ myClass =~ /Watir::Browser/i
996
+ end
997
+ end
998
+
999
+ alias is_browser is_browser?
1000
+
1001
+ # Translate window title supplied in *title* to a title appropriate for the targeted browser and version
1002
+ # actually being run.
1003
+ # Used primarily for handling of modal popups and dialogs.
1004
+ # This allows cross-browser compatibility for handling modal popups and other windows accessed by titlt.
1005
+ # @param [String] title The title of the window to be closed.
1006
+ def translate_popup_title(title)
1007
+ new_title = title
1008
+ case @browserAbbrev
1009
+ when 'IE'
1010
+ if @browserVersion
1011
+ case @browserVersion
1012
+ when '8.0'
1013
+ case title
1014
+ when "Microsoft Internet Explorer"
1015
+ new_title = "Message from webpage"
1016
+ when "The page at"
1017
+ new_title = "Message from webpage"
1018
+ end
1019
+ when '7.0'
1020
+ case title
1021
+ when "Message from webpage"
1022
+ new_title = "Microsoft Internet Explorer"
1023
+ when "The page at"
1024
+ new_title = "Windows Internet Explorer"
1025
+ end
1026
+ when '6.0'
1027
+ case title
1028
+ when "Message from webpage"
1029
+ new_title = "Microsoft Internet Explorer"
1030
+ when "The page at"
1031
+ new_title = "Microsoft Internet Explorer"
1032
+ end
1033
+ else
1034
+ case title
1035
+ when "Microsoft Internet Explorer"
1036
+ new_title = "Message from webpage"
1037
+ when "The page at"
1038
+ new_title = "Message from webpage"
1039
+ end
1040
+ end
1041
+ else
1042
+ case title
1043
+ when "Microsoft Internet Explorer"
1044
+ new_title = "Message from webpage"
1045
+ when "The page at"
1046
+ new_title = "Message from webpage"
1047
+ end
1048
+ end
1049
+ when 'FF'
1050
+ case title
1051
+ when 'File Download'
1052
+ new_title = 'Opening'
1053
+ when "Microsoft Internet Explorer"
1054
+ new_title = 'The page at'
1055
+ when "Message from webpage"
1056
+ new_title = 'The page at'
1057
+ end
1058
+ when 'C'
1059
+ case title
1060
+ when 'File Download'
1061
+ new_title = 'Save As'
1062
+ when "Microsoft Internet Explorer"
1063
+ new_title = 'The page at'
1064
+ when "Message from webpage"
1065
+ new_title = 'The page at'
1066
+ end
1067
+ end
1068
+ new_title
1069
+ end
1070
+
1071
+ # Identify the exact version of the Browser currently being executed.
1072
+ # @todo Bring up to date with newer browser versions
1073
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
1074
+ def get_browser_version(browser)
1075
+ debug_to_log("starting get_browser_version")
1076
+ case @targetBrowser.abbrev
1077
+ when 'IE'
1078
+ @browserAbbrev = 'IE'
1079
+ @browserName = 'Internet Explorer'
1080
+ if $watir_script
1081
+ @browserAppInfo = browser.document.invoke('parentWindow').navigator.appVersion
1082
+ else
1083
+ @browserAppInfo = browser.execute_script("return navigator.userAgent;")
1084
+ end
1085
+ @browserAppInfo =~ /MSIE\s(.*?);/
1086
+ @browserVersion = $1
1087
+ when 'FF'
1088
+ @browserAbbrev = 'FF'
1089
+ @browserName = 'Firefox'
1090
+ @browserVersion = '6.01' #TODO: get actual version from browser
1091
+ @browserAppInfo = browser.execute_script("return navigator.userAgent;")
1092
+ debug_to_log("#{@browserName}, @browserAppInfo: (#{@browserAppInfo})")
1093
+ when 'S'
1094
+ @browserAbbrev = 'S'
1095
+ @browserName = 'Safari'
1096
+ @browserVersion = '5.0.4' #TODO: get actual version from browser itself
1097
+ @browserAppInfo = browser.execute_script("return navigator.userAgent;")
1098
+ debug_to_log("#{@browserName}, @browserAppInfo: (#{@browserAppInfo})")
1099
+ when 'C'
1100
+ @browserAbbrev = 'C'
1101
+ @browserName = 'Chrome'
1102
+ @browserVersion = '11.0' #TODO: get actual version from browser
1103
+ @browserAppInfo = browser.execute_script("return navigator.userAgent;")
1104
+ debug_to_log("#{@browserName}, @browserAppInfo: (#{@browserAppInfo})")
1105
+ end
1106
+ rescue
1107
+ debug_to_log("Unable to determine #{@browserAbbrev} browser version: '#{$!}' (#{__LINE__})")
1108
+ ensure
1109
+ message_to_log("Browser: [#{@browserAbbrev} #{@browserVersion}]")
1110
+ end
1111
+
1112
+ protected :get_browser_version
1113
+
1114
+ #def filter_bailout_from_rescue(err, msg)
1115
+ # if msg =~ /bailing out/i
1116
+ # raise err
1117
+ # else
1118
+ # error_to_log(msg)
1119
+ # end
1120
+ #end
1121
+
1122
+ # @!group Browser
1123
+
1124
+ # Open and attach a browser popup window where the link to open it and its title contain the same string.
1125
+ # @deprecated
1126
+ def open_popup_through_link_title(browser, title, pattern, name)
1127
+ click_title(browser, title)
1128
+ #TODO need some kind of wait for process here
1129
+ sleep_for 2
1130
+ attach_popup_by_url(browser, pattern, name)
1131
+ rescue
1132
+ failed_to_log("Unable to open popup '#{name}': '#{$!}' (#{__LINE__})")
1133
+ end
1134
+
1135
+ # @!group Error Handling
1136
+
1137
+ # Verifies health of the browser. Looks for common http and system errors that are unrecoverable and
1138
+ # attempts to gracefully bail out of the script.
1139
+ # Calls rescue_me() when trying to capture the text to filter out known false errors
1140
+ # and handle container elements that don't respond to the .text method.
1141
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
1142
+ # @param [String] file_name The file name of the executing script.
1143
+ # @param [Fixnum] lnbr Contains a message or description intended to appear in the log and/or report output
1144
+ # @param [Boolean] dbg If set to true additional debug messages are written to the log.
1145
+ #
1146
+ # @return [Boolean] True if no error conditions have been encountered.
1147
+ def validate(browser, file_name = @myName, lnbr = "#{__LINE__}", dbg = false)
1148
+ debug_to_log("#{__method__} begin") if dbg
1149
+ msg = ''
1150
+ myOK = true
1151
+ if not browser
1152
+ msg = "#{file_name}----browser is nil object. (#{lnbr})"
1153
+ myOK = false
1154
+ elsif not browser.class.to_s =~ /Watir/
1155
+ msg = "#{file_name}----not a Watir object. (#{lnbr})"
1156
+ debug_to_log(browser.inspect)
1157
+ myOK = false
1158
+
1159
+ else
1160
+ if browser.respond_to?(:url)
1161
+ if not browser.url == @currentURL
1162
+ @currentURL = browser.url
1163
+ debug_to_log("Current URL: [#{@currentURL}]")
1164
+ # mark_testlevel( "Current URL: [#{@currentURL}]", 1 )
1165
+ end
1166
+ end
1167
+
1168
+ if @capture_js_errors
1169
+ if browser.respond_to?(:status)
1170
+ if browser.status.downcase =~ /errors? on page/ and
1171
+ not browser.status.downcase.include?('Waiting for')
1172
+ capture_js_error(browser)
1173
+ end
1174
+ end
1175
+ end
1176
+
1177
+ begin
1178
+ browser_text = browser.text.downcase
1179
+ rescue => e
1180
+ unless rescue_me(e, __method__, "browser.text.downcase", "#{browser.class}", browser)
1181
+ debug_to_log("browser.text.downcase in #{__method__} #{browser.class}")
1182
+ debug_to_log("#{get_callers}")
1183
+ raise e
1184
+ else
1185
+ return true
1186
+ end
1187
+ end
1188
+
1189
+ if browser_text
1190
+ if browser_text.match(/unrecognized error condition has occurred/i)
1191
+ msg = "#{file_name}----Unrecognized Exception occurred. (#{lnbr})"
1192
+ myOK = false
1193
+
1194
+ elsif browser_text.match(/cannot find server or dns error/i)
1195
+ msg = "#{file_name}----Cannot find server error or DNS error. (#{lnbr})"
1196
+ myOK = false
1197
+
1198
+ elsif browser_text.match(/the rpc server is unavailable/i)
1199
+ msg = "#{file_name}----RPC server unavailable. (#{lnbr})"
1200
+ myOK = false
1201
+
1202
+ elsif browser_text.match(/404 not found/i) or
1203
+ browser_text.match(/the page you were looking for does\s*n[o']t exist/i)
1204
+ msg = "#{file_name}----RFC 2068 HTTP/1.1: 404 URI Not Found. (#{lnbr})"
1205
+ myOK = false
1206
+
1207
+ elsif browser_text.match(/we're sorry, but something went wrong/i) or
1208
+ browser_text.match(/http status 500/i)
1209
+ msg = "#{file_name}----RFC 2068 HTTP/1.1: 500 Internal Server Error. (#{lnbr})"
1210
+ myOK = false
1211
+
1212
+ elsif browser_text.match(/internet explorer cannot display the webpage/i)
1213
+ msg = "#{file_name}----Probably RFC 2068 HTTP/1.1: 500 Internal Server Error. (#{lnbr})"
1214
+ myOK = false
1215
+
1216
+ elsif browser_text.match(/503.*service unavailable/i)
1217
+ msg = "#{file_name}----RFC 2068 HTTP/1.1: 503 Service Unavailable. (#{lnbr})"
1218
+ myOK = false
1219
+
1220
+ elsif browser_text.match(/java.lang.NullPointerException/i)
1221
+ msg = "#{file_name}----java.lang.NullPointerException. (#{lnbr})"
1222
+ myOK = false
1223
+
1224
+ elsif browser_text.match(/due to unscheduled maintenance/i)
1225
+ msg = "#{file_name}----Due to unscheduled maintenance. (#{lnbr})"
1226
+ myOK = false
1227
+
1228
+ elsif browser_text.match(/network\s+error\s*(.+)$/i)
1229
+ $1.chomp!
1230
+ msg = "#{file_name}----Network Error #{$1}. (#{lnbr})"
1231
+ myOK = false
1232
+
1233
+ elsif browser_text.match(/warning: page has expired/i)
1234
+ msg = "#{file_name}----Page using information from form has expired. Not automatically resubmitted. (#{lnbr})"
1235
+ myOK = false
1236
+
1237
+ elsif browser_text.match(/no backend server available/i)
1238
+ msg = "#{file_name}----Cannot Reach Server (#{lnbr})"
1239
+ myOK = false
1240
+
1241
+ elsif browser_text.match(/sign on\s+.+\s+unsuccessful/i)
1242
+ msg = "#{file_name}----Invalid Id or Password (#{lnbr})"
1243
+ myOK = false
1244
+
1245
+ elsif browser_text.match(/you are not authorized/i)
1246
+ msg = "#{file_name}----Not authorized to view this page. (#{lnbr})"
1247
+ myOK = false
1248
+
1249
+ elsif browser_text.match(/too many incorrect login attempts have been made/i)
1250
+ msg = "#{file_name}----Invalid Id or Password. Too many tries. (#{lnbr})"
1251
+ myOK = false
1252
+
1253
+ elsif browser_text.match(/system error\.\s+an error has occurred/i)
1254
+ msg = "#{file_name}----System Error. An error has occurred. Please try again or call the Help Line for assistance. (#{lnbr})"
1255
+ myOK = false
1256
+
1257
+ elsif browser_text.match(/Internal Server failure,\s+NSAPI plugin/i)
1258
+ msg = "#{file_name}----Internal Server failure, NSAPI plugin. (#{lnbr})"
1259
+ myOK = false
1260
+
1261
+ elsif browser_text.match(/Error Page/i)
1262
+ msg = "#{file_name}----Error Page. (#{lnbr})"
1263
+ myOK = false
1264
+
1265
+ elsif browser_text.match(/The website cannot display the page/i)
1266
+ msg = "#{file_name}----HTTP 500. (#{lnbr})"
1267
+ myOK = false
1268
+
1269
+ # elsif browser_text.match(/Insufficient Data/i)
1270
+ # msg = "#{file_name}----Insufficient Data. (#{lnbr})"
1271
+ # myOK = false
1272
+
1273
+ elsif browser_text.match(/The timeout period elapsed/i)
1274
+ msg = "#{file_name}----Time out period elapsed or server not responding. (#{lnbr})"
1275
+ myOK = false
1276
+
1277
+ elsif browser_text.match(/Unexpected\s+errors*\s+occur+ed\.\s+(?:-+)\s+(.+)/i)
1278
+ msg = "#{file_name}----Unexpected errors occurred. #{$2.slice(0, 120)} (#{lnbr})"
1279
+ if not browser_text.match(/close the window and try again/i)
1280
+ myOK = false
1281
+ else
1282
+ debug_to_log("#{msg}")
1283
+ end
1284
+
1285
+ elsif browser_text.match(/Server Error in (.+) Application\.\s+(?:-+)\s+(.+)/i)
1286
+ msg = "#{file_name}----Server Error in #{1} Application. #{$2.slice(0, 100)} (#{lnbr})"
1287
+ myOK = false
1288
+
1289
+ elsif browser_text.match(/Server Error in (.+) Application\./i)
1290
+ msg = "#{file_name}----Server Error in #{1} Application. '#{browser_text.slice(0, 250)}...' (#{lnbr})"
1291
+ myOK = false
1292
+
1293
+ elsif browser_text.match(/An error has occur+ed\. Please contact support/i)
1294
+ msg = "#{file_name}----An error has occurred. Please contact support (#{lnbr})"
1295
+ myOK = false
1296
+
1297
+ end
1298
+ else
1299
+ debug_to_log("browser.text returned nil")
1300
+ end
1301
+ end
1302
+
1303
+ if not myOK
1304
+ msg << " (#{browser.url})"
1305
+ puts msg
1306
+ debug_to_log(browser.inspect)
1307
+ debug_to_log(browser.text)
1308
+ fatal_to_log(msg, lnbr)
1309
+ raise(RuntimeError, msg, caller)
1310
+ else
1311
+ debug_to_log("#{__method__} returning OK") if dbg
1312
+ return myOK
1313
+ end
1314
+
1315
+ rescue
1316
+ errmsg = $!
1317
+ if errmsg and errmsg.match(msg)
1318
+ errmsg = ''
1319
+ end
1320
+ bail_out(browser, lnbr, "#{msg} #{errmsg}")
1321
+ end
1322
+
1323
+ alias validate_browser validate
1324
+
1325
+ # @!endgroup Error Handling
1326
+
1327
+ # @!group Backward compatible usages
1328
+
1329
+ # Returns a reference to a browser window using the window's *:url* attribute. Calls attach_browser().
1330
+ # @example
1331
+ # mainwindow = open_browser('www.google.com')
1332
+ # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
1333
+ # popup = attach_browser_by_url(mainwindow, '[url of new window]')
1334
+ # @param [Watir::Browser] browser A reference to the current browser window.
1335
+ # @param [String, Regexp] what The value in the targeted attribute that uniquely identifies the new window
1336
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
1337
+ # @return [Watir::Browser]
1338
+ def attach_browser_by_url(browser, what, desc = '')
1339
+ attach_browser(browser, :url, what, desc)
1340
+ end
1341
+
1342
+ alias attach_browser_with_url attach_browser_by_url
1343
+
1344
+ # Returns a reference to a new browser window identified by its *:title* attribute. Used to attach a new browser window to a variable
1345
+ # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
1346
+ # @param (see #attach_browser_by_url)
1347
+ def attach_popup_by_title(browser, what, desc = '')
1348
+ attach_popup(browser, :title, what, desc)
1349
+ end
1350
+
1351
+ # Returns a reference to a new browser window identified by its *:url* attribute. Used to attach a new browser window to a variable
1352
+ # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
1353
+ # @param (see #attach_browser_by_url)
1354
+ def attach_popup_by_url(browser, what, desc = '')
1355
+ attach_popup(browser, :url, what, desc)
1356
+ end
1357
+
1358
+ alias get_popup_with_url attach_popup_by_url
1359
+ alias attach_popup_with_url attach_popup_by_url
1360
+ alias attach_iepopup attach_popup_by_url
1361
+
1362
+ # Close a popup browser window (non-modal) by clicking on a link with :title *what*.
1363
+ # This method does not check to make sure the popup is actually closed.
1364
+ # @param [Watir::Browser] popup A reference to the current popup browser window.
1365
+ # @param [String, Regexp] what The value in the targeted attribute that uniquely identifies the new window
1366
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
1367
+ # @return [Boolean] True if the click is successful.
1368
+ def close_popup_by_button_title(popup, what, desc = '')
1369
+ click(popup, :link, :title, what, desc)
1370
+ end
1371
+
1372
+ # @!endgroup Backward
1373
+
1374
+
1375
+ end
1376
+ end
1377
+ end
1378
+