awetestlib 0.1.13 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
data/lib/awetestlib.rb CHANGED
@@ -20,7 +20,7 @@ module Awetestlib
20
20
 
21
21
  if USING_WINDOWS
22
22
  #require 'win32ole' <-- We'll load this later in Shamisen::AwetestLegacy::Runner. It has to be loaded after watir, see https://www.pivotaltracker.com/story/show/19249981
23
- require 'win32/screenshot'
23
+ require 'win32/screenshot' # triggering segmentation fault 10sep2012 pmn
24
24
  end
25
25
  #require 'active_support/inflector'
26
26
  #require 'active_support/core_ext/object'
@@ -1,10 +1,20 @@
1
1
  module Awetestlib
2
2
  module Logging
3
3
 
4
+ # @deprecated
4
5
  def self.included(mod)
5
6
  # puts "RegressionSupport::Logging extended by #{mod}"
6
7
  end
7
8
 
9
+ # Format log message and write to STDOUT. Write to physical log if indicated.
10
+ # @private
11
+ # @param [Fixnum] severity Severity level of message. Use constants DEBUG, INFO, WARN, ERROR, FATAL, or UNKNOWN
12
+ # @param [String] message The message to be placed in the log.
13
+ # @param [String, Fixnum] tag Indicates the type of message. Valid string values are 'FAIL' and 'PASS'.
14
+ # Valid number values are 0 to 9.
15
+ # @param [Fixnum] lnbr the line number in the calling script
16
+ # @param [Fixnum] addts Obsolete, no longer used.
17
+ # @param [String] exception Obsolete, no longer used.
8
18
  def log_message(severity, message, tag = '', lnbr = nil, addts = 1, exception=nil)
9
19
  # caller = get_caller(lnbr, exception)
10
20
 
@@ -50,6 +60,10 @@ module Logging
50
60
 
51
61
  #private log_message
52
62
 
63
+ # Translates tag value to corresponding value for +pass+ column in database.
64
+ # @private
65
+ # @param [String, Fixnum] tag
66
+ # @return [String] Single character
53
67
  def pass_code_for(tag)
54
68
  case
55
69
  when tag =~ /PASS/
@@ -204,7 +218,7 @@ tags: log, error, fail, reference, tag, report
204
218
  @my_failed_count += 1 if @my_failed_count
205
219
  parse_error_references(message, true)
206
220
  @report_class.add_to_report("#{message}" + " [#{get_caller(lnbr)}]","FAILED")
207
- log_message(WARN, "#{message}" + " (#{lnbr})]", FAIL, lnbr)
221
+ log_message(WARN, "#{message}", FAIL, lnbr)
208
222
  end
209
223
 
210
224
  alias validate_failed_tolog failed_to_log
@@ -302,7 +316,7 @@ tags: log, caller, trace, report
302
316
  end
303
317
  end
304
318
  logger = ActiveSupport::BufferedLogger.new(logFile)
305
- logger.level = Logger::DEBUG
319
+ logger.level = ActiveSupport::BufferedLogger::DEBUG
306
320
  logger.auto_flushing = (true)
307
321
  logger.add(INFO, "#{logFile}\n#{ENV["OS"]}")
308
322
  logger
@@ -408,4 +422,4 @@ tags: error, fail, hits, reference, tag, tallies
408
422
  end
409
423
 
410
424
  end
411
- end
425
+ end
@@ -1,32 +1,28 @@
1
1
  module Awetestlib
2
+ # Awetest DSL for browser based testing.
2
3
  module Regression
4
+ # Methods to manage browser windows: open, close, attach, verify health, and clean up.
3
5
  module Browser
4
6
 
5
- def run #DO WE NEED? Use this method to tell user they need to create a run method?
6
- setup
7
- set_script_variables
8
- run_test
9
- rescue
10
- fatal_to_log("(#{__LINE__}) #{$!}")
11
- browser.close
12
- raise
13
- end
14
-
15
- =begin rdoc
16
- :category: A_rdoc_test
17
- Opens a browser and returns a reference to it. If *url* is specified the browser is
18
- opened to that url, otherwise it is opened to a bland page
19
-
20
- _Parameters_::
21
-
22
- *url* - a string containing the full url. Optional.
23
-
24
- _Example_
25
-
26
- browser = open_browser('www.google.com')
27
-
28
- =end
29
-
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
+ # Open a browser based on the command line parameters that identify the browser and
21
+ # version to use for the test.
22
+ # @example
23
+ # browser = open_browser('www.google.com')
24
+ # @param [String, Regexp] url When provided, the browser will go to this url.
25
+ # @return [Watir::Browser]
30
26
  def open_browser(url = nil)
31
27
  debug_to_log("Opening browser: #{@targetBrowser.name}")
32
28
  case @targetBrowser.abbrev
@@ -34,7 +30,6 @@ _Example_
34
30
  @myBrowser = open_ie
35
31
  if @myBrowser.class.to_s == "Watir::IE"
36
32
  @myHwnd = @myBrowser.hwnd
37
- @waiter = Watir::Waiter.new(WAIT)
38
33
  end
39
34
  when 'FF'
40
35
  @myBrowser = open_ff_for_version
@@ -52,6 +47,11 @@ _Example_
52
47
  @myBrowser
53
48
  end
54
49
 
50
+ # Open IE (Internet Explorer) browser instance.
51
+ # If global variable $watir_script is set to true in the first line of the script,
52
+ # classic Watir will be used to drive the browser,
53
+ # otherwise Watir Webdriver will be used.
54
+ # @return [Watir::Browser]
55
55
  def open_ie
56
56
  if $watir_script
57
57
  browser = Watir::IE.new
@@ -61,6 +61,10 @@ _Example_
61
61
  browser
62
62
  end
63
63
 
64
+ # Open FF (Firefox) browser instance.
65
+ # @param [Fixnum] version A number designating the version of the browser to be opened.
66
+ # @return [Watir::Browser, Firewatir::Browser]
67
+ # Returns Firewatir::Browser if target browser is Firefox version less than 4.0
64
68
  def open_ff_for_version(version = @targetVersion)
65
69
  if version.to_f < 4.0
66
70
  browser = open_ff
@@ -70,25 +74,205 @@ _Example_
70
74
  browser
71
75
  end
72
76
 
77
+ # Open FF (Firefox) browser instance under FireWatir.
78
+ # @return [Firewatir::Browser]
73
79
  def open_ff
74
80
  Watir::Browser.default = 'firefox'
75
81
  browser = Watir::Browser.new
76
82
  end
77
83
 
84
+ # Open GC (Google Chrome) browser instance.
85
+ # @return [Watir::Browser] Browser is Google Chrome.
78
86
  def open_chrome
79
87
  browser = Watir::Browser.new(:chrome)
80
88
  end
81
89
 
82
- def go_to_url(browser, url = nil, redirect = nil)
90
+ # Instruct browser to navigate to a specific URL
91
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
92
+ # @param [String] url When provided, the browser will go to this url.
93
+ # and the instance variable @myURL will be set to this value.
94
+ # @return [Boolean] True when navigation to url succeeds.
95
+ def go_to_url(browser, url = nil)
83
96
  if url
84
97
  @myURL = url
85
98
  end
86
99
  message_tolog("URL: #{@myURL}")
87
100
  browser.goto(@myURL)
101
+ true
88
102
  rescue
89
103
  fatal_to_log("Unable to navigate to '#{@myURL}': '#{$!}'")
90
104
  end
91
105
 
106
+ # Return a reference to a browser window. Used to attach a browser window to a variable
107
+ # which can then be passed to methods that require a *browser* parameter.
108
+ # @example
109
+ # mainwindow = open_browser('www.google.com')
110
+ # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
111
+ # popup = attach_browser(mainwindow, :url, '[url of new window]') #*or*
112
+ # popup = attach_browser(mainwindow, :title, '[title of new window]')
113
+ # @todo Update to work with webdriver for IE.
114
+ # @param [Watir::Browser] browser A reference to the current browser window.
115
+ # @param [Symbol] how The element attribute used to identify the window: *:title* or :url.
116
+ # @param [String|Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
117
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
118
+ # @return [Watir::Browser] Internet Explorer
119
+ def attach_browser(browser, how, what, desc = '')
120
+ debug_to_log("Attaching browser window :#{how}=>'#{what}' #{desc}")
121
+ uri_decoded_pattern = ::URI.encode(what.to_s.gsub('(?-mix:', '').gsub(')', ''))
122
+ case @browserAbbrev
123
+ when 'IE'
124
+ tmpbrowser = Watir::IE.attach(how, what)
125
+ browser.visible = true
126
+ if tmpbrowser
127
+ tmpbrowser.visible = true
128
+ tmpbrowser.speed = :fast
129
+ else
130
+ raise "Browser window :#{how}=>'#{what}' has at least one doc not in completed ready state."
131
+ end
132
+ when 'FF'
133
+ #TODO: This may be dependent on Firefox version if webdriver doesn't support 3.6.17 and below
134
+ browser.driver.switch_to.window(browser.driver.window_handles[0])
135
+ browser.window(how, /#{uri_decoded_pattern}/).use
136
+ tmpbrowser = browser
137
+ when 'S'
138
+ Watir::Safari.attach(how, what)
139
+ tmpbrowser = browser
140
+ when 'C'
141
+ browser.window(how, /#{uri_decoded_pattern}/).use
142
+ tmpbrowser = browser
143
+ end
144
+ debug_to_log("#{__method__}: tmpbrowser:#{tmpbrowser.inspect}")
145
+ tmpbrowser
146
+ end
147
+
148
+
149
+ # Returns a reference to a new browser window. Used to attach a new browser window to a variable
150
+ # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
151
+ # @example
152
+ # mainwindow = open_browser('www.google.com')
153
+ # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
154
+ # popup = attach_popup(mainwindow, :url, '[url of new window]') *or*
155
+ # popup = attach_popup(mainwindow, :title, '[title of new window]')
156
+ # @param [Watir::Browser] browser A reference to the current browser window.
157
+ # @param [Symbol] how The element attribute used to identify the window: *:title* or :url.
158
+ # @param [String, Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
159
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
160
+ # @return [Watir::Browser] The new browser window.
161
+ def attach_popup(browser, how, what, desc = '')
162
+ msg = "Attach popup :#{how}=>'#{what}'. #{desc}"
163
+ popup = attach_browser(browser, how, what, desc)
164
+ sleep_for(1)
165
+ debug_to_log("#{popup.inspect}")
166
+ if is_browser?(popup)
167
+ title = popup.title
168
+ passed_to_log("#{msg} title='#{title}'")
169
+ return popup
170
+ else
171
+ failed_to_log(msg)
172
+ end
173
+ rescue
174
+ failed_to_log("Unable to attach popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
175
+ end
176
+
177
+ # Locate and close instances of IE browsers
178
+ def find_other_browsers
179
+ cnt = 0
180
+ if @targetBrowser.abbrev == 'IE'
181
+ Watir::IE.each do |ie|
182
+ debug_to_log("#{ie.inspect}")
183
+ ie.close()
184
+ cnt = cnt + 1
185
+ end
186
+ end
187
+ debug_to_log("Found #{cnt} IE browser(s).")
188
+ return cnt
189
+ rescue
190
+ error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}", __LINE__)
191
+ return 0
192
+ end
193
+
194
+ # @!endgroup Browser
195
+
196
+ # @!group Login
197
+
198
+ # Simple login method
199
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
200
+ # @param [String] user Login ID for the user.
201
+ # @param [String] password Password for the user.
202
+ # @return [Boolean] True if login succeeds.
203
+ def login(browser, user, password)
204
+ #TODO: Needs to be more flexible about finding login id and password textfields
205
+ #TODO: Parameterize url and remove references to environment
206
+ myURL = @myAppEnv.url
207
+ runenv = @myAppEnv.nodename
208
+ message_tolog("URL: #{myURL}") if @myAppEnv
209
+ message_tolog("Beginning login: User: #{user} Environment: #{@myAppEnv.nodename}") if @myAppEnv
210
+ if validate(browser, @myName, __LINE__)
211
+ browser.goto(@myAppEnv.url)
212
+ if validate(browser, @myName)
213
+ set_textfield_by_name(browser, 'loginId', user)
214
+ set_textfield_by_name(browser, 'password', password)
215
+ click_button_by_value(browser, 'Login')
216
+ if validate(browser, @myName)
217
+ passed_to_log("Login successful.")
218
+ true
219
+ end
220
+ else
221
+ failed_to_log("Unable to login to application: '#{$!}'")
222
+ #screen_capture( "#{@myRoot}/screens/#{myName}_#{@runid}_#{__LINE__.to_s}_#{Time.new.to_f.to_s}.jpg")
223
+ end
224
+ end
225
+ rescue
226
+ failed_to_log("Unable to login to application: '#{$!}'")
227
+ end
228
+
229
+ # Logon to webpage using Basic Authorization type of logon. Uses AutoIt
230
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
231
+ # @param [String] user Login ID for the user.
232
+ # @param [String] password Password for the user.
233
+ # @param [String] url The URL to log on to.
234
+ # @param [Boolean] bypass_validate When set to true, the call to validate(),
235
+ # which checks the health of the browser, is skipped..
236
+ def basic_auth(browser, user, password, url, bypass_validate = false)
237
+ mark_testlevel("Basic Authorization Login", 0)
238
+
239
+ message_to_report ("Login: #{user}")
240
+ message_to_report ("URL: #{url}")
241
+ message_to_report ("Password: #{password}")
242
+
243
+ @login_title = "Connect to"
244
+
245
+ a = Thread.new {
246
+ browser.goto(url)
247
+ }
248
+
249
+ sleep_for(2)
250
+ message_to_log("#{@login_title}...")
251
+
252
+ if (@ai.WinWait(@login_title, "", 90) > 0)
253
+ win_title = @ai.WinGetTitle(@login_title)
254
+ debug_to_log("Basic Auth Login window appeared: '#{win_title}'")
255
+ @ai.WinActivate(@login_title)
256
+ @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", '!u')
257
+ @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", user, 1)
258
+ @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:3]", password.gsub(/!/, '{!}'), 1)
259
+ @ai.ControlClick(@login_title, "", '[CLASS:Button; INSTANCE:1]')
260
+ else
261
+ debug_to_log("Basic Auth Login window did not appear.")
262
+ end
263
+ a.join
264
+
265
+ validate(browser, @myName) unless bypass_validate
266
+
267
+ message_to_report("URL: [#{browser.url}] User: [#{user}]")
268
+
269
+ end
270
+
271
+ # Provide an authorization token or passcode in a specified text field element identified by its *:id* attribute.
272
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
273
+ # @param [String] role Usually a user role designation ('Administrator', 'User', etc.)
274
+ # @param [String] token Authentification token required by logon process.
275
+ # @param [String/Regexp] id Value of the *:id* attribute of the text field that will receive the *token*.
92
276
  def token_auth(browser, role, token, id = 'token_pass')
93
277
  set_textfield_by_id(browser, id, token)
94
278
  click_button_by_value(browser, 'Continue')
@@ -97,9 +281,19 @@ _Example_
97
281
  end
98
282
  end
99
283
 
100
- def bail_out(browser, lnbr, msg)
284
+ # @!endgroup Logon
285
+
286
+ # @!group Error Handling
287
+
288
+ # Exit more or less gracefully from script when errors are too severe to continue.
289
+ # Normally not called in a test script or project library.
290
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
291
+ # @param [Fixnum] lnbr Line number in calling script.
292
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
293
+ #
294
+ def bail_out(browser, lnbr, desc)
101
295
  ts = Time.new
102
- msg = "Bailing out at util line #{lnbr} #{ts} " + msg
296
+ msg = "Bailing out at util line #{lnbr} #{ts} " + desc
103
297
  puts "#{msg}"
104
298
  fatal_to_log(msg, nil, 1, lnbr)
105
299
  debug_to_log(dump_caller(lnbr))
@@ -118,15 +312,9 @@ _Example_
118
312
  raise(RuntimeError, msg, caller)
119
313
  end
120
314
 
121
- def do_taskkill(severity, pid)
122
- if pid and pid > 0 and pid < 538976288
123
- info_to_log("Executing taskkill for pid #{pid}")
124
- log_message(severity, %x[taskkill /t /f /pid #{pid}])
125
- end
126
- rescue
127
- error_to_log("#{$!} (#{__LINE__})")
128
- end
129
315
 
316
+ # Check for the presence of IE browser instances.
317
+ # @return [Fixnum] The number of IE browser instances encountered.
130
318
  def check_for_other_browsers
131
319
  cnt1 = find_other_browsers
132
320
  cnt2 = Watir::Process.count 'iexplore.exe'
@@ -135,6 +323,7 @@ _Example_
135
323
  error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}")
136
324
  end
137
325
 
326
+ # Check for the presence of IE browser instances and close all that are found.
138
327
  def check_for_and_clear_other_browsers
139
328
  if @targetBrowser.abbrev == 'IE'
140
329
  debug_to_log("#{__method__}:")
@@ -174,7 +363,12 @@ _Example_
174
363
  error_to_log("#{__method__}: #{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}")
175
364
  end
176
365
 
177
- def kill_browser(hwnd, lnbr, browser = nil, doflag = false)
366
+ # Force browser instance to close, one way or the other.
367
+ # Instance is identified by *hwnd*, the Windows OS handle for the process.
368
+ # @param [String] hwnd The value for the window handle for the browser process.
369
+ # @param [Fixnum] lnbr Line number in calling script.
370
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be closed.
371
+ def kill_browser(hwnd, lnbr, browser = nil)
178
372
  # TODO Firefox
179
373
  logit = false
180
374
  if @browserAbbrev == 'FF'
@@ -182,7 +376,7 @@ _Example_
182
376
  logit = true
183
377
  here = __LINE__
184
378
  url = browser.url
185
- capture_screen(browser, Time.new.to_f) if @screenCaptureOn
379
+ #capture_screen(browser, Time.new.to_f) if @screenCaptureOn
186
380
  browser.close if url.length > 0
187
381
  @status = 'killbrowser'
188
382
  fatal_to_log("Kill browser called from line #{lnbr}")
@@ -194,7 +388,7 @@ _Example_
194
388
  here = __LINE__
195
389
  logit = true
196
390
  url = browser.url
197
- capture_screen(browser, Time.new.to_f) if @screenCaptureOn
391
+ #capture_screen(browser, Time.new.to_f) if @screenCaptureOn
198
392
  browser.close
199
393
  sleep(2)
200
394
  if browser.exists?
@@ -210,159 +404,49 @@ _Example_
210
404
  end
211
405
  end
212
406
 
213
- =begin rdoc
214
- :category: A_rdoc_test
215
-
216
- Returns a reference to a browser window. Used to attach a browser window to a variable
217
- which can then be passed to methods that require a *browser* parameter.
218
-
219
- _Parameters_::
220
-
221
- *browser* - a reference to the browser window to be tested
222
-
223
- *how* - the browser attribute used to identify the window: either :url or :title
224
-
225
- *what* - a string or a regular expression in the url or title
226
-
227
- *desc* - a string containing a message or description intended to appear in the log and/or report output
407
+ # @!endgroup Error Handling
228
408
 
409
+ # @!group Browser
229
410
 
230
- *_Example_*
231
-
232
- mainwindow = open_browser('www.myapp.com') # open a browser to www.google.com
233
- click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
234
- popup = attach_browser(mainwindow, :url, '[url of new window]') #*or*
235
- popup = attach_browser(mainwindow, :title, '[title of new window]')
236
-
237
- =end
238
-
239
- def attach_browser(browser, how, what, desc = '')
240
- debug_to_log("Attaching browser window :#{how}=>'#{what}' #{desc}")
241
- uri_decoded_pattern = URI.encode(what.to_s.gsub('(?-mix:', '').gsub(')', ''))
242
- case @browserAbbrev
243
- when 'IE'
244
- tmpbrowser = Watir::IE.attach(how, what)
245
- browser.visible = true
246
- if tmpbrowser
247
- tmpbrowser.visible = true
248
- tmpbrowser.speed = :fast
249
- else
250
- raise "Browser window :#{how}=>'#{what}' has at least one doc not in completed ready state."
411
+ # Use enabled_popup and winclicker to determine if there is an active modal popup.
412
+ # Useful only when no wait action has been invoked.
413
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
414
+ # @param [String] button The visible name of the button to be clicked to close the popup.
415
+ # @return [String] containing the window handle of the closed modal popup.
416
+ def modal_exists?(browser, button = nil)
417
+ rtrn = nil
418
+ if @browserAbbrev == 'IE'
419
+ Timeout::timeout(2) do
420
+ begin
421
+ if browser.enabled_popup
422
+ hwnd = browser.enabled_popup(5)
423
+ debug_to_log("Modal popup with handle #{hwnd} found. (#{__LINE__})")
424
+ wc = WinClicker.new
425
+ wc.makeWindowActive(hwnd)
426
+ rtrn = wc.getWindowTitle(hwnd)
427
+ if button
428
+ wc.clickWindowsButton_hWnd(hwnd, button)
429
+ end
430
+ wc = nil
431
+ end
432
+ rescue Timeout::Error
433
+ debug_to_log("No Modal popup found. (#{__LINE__})")
434
+ return rtrn
251
435
  end
252
- when 'FF'
253
- #TODO: This may be dependent on Firefox version if webdriver doesn't support 3.6.17 and below
254
- browser.driver.switch_to.window(browser.driver.window_handles[0])
255
- browser.window(how, /#{uri_decoded_pattern}/).use
256
- tmpbrowser = browser
257
- when 'S'
258
- browser.driver.switch_to.window(browser.driver.window_handles[0])
259
- sleep 1
260
- browser.window(how, /#{uri_decoded_pattern}/).use
261
- tmpbrowser = browser
262
- when 'C'
263
- browser.window(how, /#{uri_decoded_pattern}/).use
264
- tmpbrowser = browser
265
- end
266
- debug_to_log("#{__method__}: tmpbrowser:#{tmpbrowser.inspect}")
267
- tmpbrowser
268
- end
269
-
270
- =begin rdoc
271
- :category: A_rdoc_test
272
- Returns a reference to a browser window using the window's url. Calls attach_browser().
273
-
274
- _Parameters_::
275
-
276
- *browser* - a reference to the browser window to be tested
277
-
278
- *pattern* - a string with the complete url or a regular expression containing part of the url
279
- that uniquely identifies it in the context of the test.
280
-
281
- *desc* - a string containing a message or description intended to appear in the log and/or report output
282
-
283
-
284
- _Example_
285
-
286
- mainwindow = open_browser('www.myapp.com') # open a browser to www.google.com
287
- click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
288
- popup = attach_browser_by_url(mainwindow, '[url of new window]')
289
-
290
- =end
291
-
292
- def attach_browser_by_url(browser, pattern, desc = '')
293
- attach_browser(browser, :url, pattern, desc)
294
- end
295
-
296
- alias attach_browser_with_url attach_browser_by_url
297
-
298
- =begin rdoc
299
- :category: A_rdoc_test
300
- Returns a reference to a new browser window. Used to attach a new browser window to a variable
301
- which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
302
-
303
- _Parameters_::
304
-
305
- *browser* - a reference to the browser window to be tested
306
-
307
- *how* - the browser attribute used to identify the window: either :url or :title
308
-
309
- *what* - a string or a regular expression in the url or title
310
-
311
- *desc* - a string containing a message or description intended to appear in the log and/or report output
312
-
313
-
314
- _Example_
315
-
316
- mainwindow = open_browser('www.myapp.com') # open a browser to www.google.com
317
- click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
318
- popup = attach_popup(mainwindow, :url, '[url of new window]') *or*
319
- popup = attach_popup(mainwindow, :title, '[title of new window]')
320
-
321
- =end
322
- def attach_popup(browser, how, what, desc = '')
323
- msg = "Attach popup :#{how}=>'#{what}'. #{desc}"
324
- popup = attach_browser(browser, how, what, desc)
325
- sleep_for(1)
326
- debug_to_log("#{popup.inspect}")
327
- if is_browser?(popup)
328
- title = popup.title
329
- passed_to_log("#{msg} title='#{title}'")
330
- return popup
331
- else
332
- failed_to_log(msg)
333
- end
334
- rescue
335
- failed_to_log("Unable to attach popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
336
- end
337
-
338
- def attach_popup_by_title(browser, strg, desc = '')
339
- attach_popup(browser, :title, strg, desc)
340
- end
341
-
342
- def attach_popup_by_url(browser, pattern, desc = '')
343
- attach_popup(browser, :url, pattern, desc)
344
- end
345
-
346
- alias get_popup_with_url attach_popup_by_url
347
- alias attach_popup_with_url attach_popup_by_url
348
- alias attach_iepopup attach_popup_by_url
349
-
350
- def find_other_browsers
351
- cnt = 0
352
- if @targetBrowser.abbrev == 'IE'
353
- Watir::IE.each do |ie|
354
- debug_to_log("#{ie.inspect}")
355
- ie.close()
356
- cnt = cnt + 1
436
+ return rtrn
357
437
  end
438
+ rtrn
439
+ else
440
+ rtrn
358
441
  end
359
- debug_to_log("Found #{cnt} IE browser(s).")
360
- return cnt
361
- rescue
362
- error_to_log("#{$!} (#{__LINE__})\n#{Kernel.caller.to_yaml}", __LINE__)
363
- return 0
364
442
  end
365
443
 
444
+ # Close a browser window identified by its title.
445
+ # Uses AutoIt. Windows only.
446
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
447
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
448
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
449
+ # @param [String] text (optional) The text of the window to be closed. Matched from beginning of string.
366
450
  def close_window_by_title(browser, title, desc = '', text = '')
367
451
  msg = "Window '#{title}':"
368
452
  if @ai.WinWait(title, text, WAIT) > 0
@@ -383,74 +467,7 @@ _Example_
383
467
  failed_to_log("#{msg}: Unable to close: '#{$!}'. (#{__LINE__}) #{desc}")
384
468
  end
385
469
 
386
- =begin rdoc
387
- :category: Basic
388
- :tags:logon, login, user, password, url
389
- TODO: Needs to be more flexible about finding login id and password textfields
390
- TODO: Parameterize url and remove references to environment
391
- =end
392
- def login(browser, user, password)
393
- myURL = @myAppEnv.url
394
- runenv = @myAppEnv.nodename
395
- message_tolog("URL: #{myURL}")
396
- message_tolog("Beginning login: User: #{user} Environment: #{runenv}")
397
- if validate(browser, @myName, __LINE__)
398
- browser.goto(myURL)
399
- if validate(browser, @myName)
400
- set_textfield_by_name(browser, 'loginId', user)
401
- set_textfield_by_name(browser, 'password', password)
402
- click_button_by_value(browser, 'Login')
403
- if validate(browser, @myName)
404
- passed_to_log("Login successful.")
405
- end
406
- else
407
- failed_to_log("Unable to login to application: '#{$!}'")
408
- # screen_capture( "#{@myRoot}/screens/#{myName}_#{@runid}_#{__LINE__.to_s}_#{Time.new.to_f.to_s}.jpg")
409
- end
410
- end
411
- rescue
412
- failed_to_log("Unable to login to application: '#{$!}'")
413
- end
414
-
415
- =begin rdoc
416
- category: Logon
417
- :tags:logon, login, user, password, url, basic authorization
418
- =end
419
- def basic_auth(browser, user, pswd, url, bypass_validate = false)
420
- mark_testlevel("Basic Authorization Login", 0)
421
-
422
- message_to_report ("Login: #{user}")
423
- message_to_report ("URL: #{url}")
424
- message_to_report ("Password: #{pswd}")
425
-
426
- @login_title = "Connect to"
427
-
428
- a = Thread.new {
429
- browser.goto(url)
430
- }
431
-
432
- sleep_for(2)
433
- message_to_log("#{@login_title}...")
434
-
435
- if (@ai.WinWait(@login_title, "", 90) > 0)
436
- win_title = @ai.WinGetTitle(@login_title)
437
- debug_to_log("Basic Auth Login window appeared: '#{win_title}'")
438
- @ai.WinActivate(@login_title)
439
- @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", '!u')
440
- @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:2]", user, 1)
441
- @ai.ControlSend(@login_title, '', "[CLASS:Edit; INSTANCE:3]", pswd.gsub(/!/, '{!}'), 1)
442
- @ai.ControlClick(@login_title, "", '[CLASS:Button; INSTANCE:1]')
443
- else
444
- debug_to_log("Basic Auth Login window did not appear.")
445
- end
446
- a.join
447
-
448
- validate(browser, @myName) unless bypass_validate
449
-
450
- message_to_report("URL: [#{browser.url}] User: [#{user}]")
451
-
452
- end
453
-
470
+ # Closes main browser session. Misnamed. Usually used at end of script to shut down browser.
454
471
  def logout(browser, where = @myName, lnbr = __LINE__)
455
472
  #TODO Firewatir 1.6.5 does not implement .exists for FireWatir::Firefox class
456
473
  debug_to_log("Logging out in #{where} at line #{lnbr}.", lnbr, true)
@@ -483,7 +500,7 @@ category: Logon
483
500
  browser.close
484
501
  end
485
502
  if browser.exists? and pid > 0 and pid < 538976288 # value of uninitialized memory location
486
- kill_browser(browser.hwnd, __LINE__, browser, true)
503
+ kill_browser(browser.hwnd, __LINE__, browser)
487
504
  end
488
505
  when 'S'
489
506
  if is_browser?(browser)
@@ -520,7 +537,8 @@ category: Logon
520
537
  # end
521
538
  end
522
539
 
523
- #close popup in new window
540
+ # Close a browser popup window. Does not apply to modal popups.
541
+ # @param [Watir::Browser] popup Reference to the popup to be closed
524
542
  def close_new_window_popup(popup)
525
543
  if is_browser?(popup)
526
544
  url = popup.url
@@ -530,24 +548,27 @@ category: Logon
530
548
  end
531
549
  end
532
550
 
533
- def close_panel_by_text(browser, panel, strg = 'Close')
551
+ # Close an HTML panel or division by clicking a link within it identified by the *:text* value of the link.
552
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
553
+ # @param [Watir::Browser] panel Reference to the panel (usually a div element) to be closed
554
+ def close_panel_by_text(browser, panel, what = 'Close')
534
555
  if validate(browser, @myName, __LINE__)
535
556
  if @browserAbbrev == 'IE'
536
- panel.link(:text, strg).click!
557
+ panel.link(:text, what).click!
537
558
  elsif $USE_FIREWATIR
538
559
  begin
539
- panel.link(:text, strg).click
560
+ panel.link(:text, what).click
540
561
  rescue => e
541
- if not rescue_me(e, __method__, "link(:text,'#{strg}').click", "#{panel.class}")
562
+ if not rescue_me(e, __method__, "link(:text,'#{what}').click", "#{panel.class}")
542
563
  raise e
543
564
  end
544
565
  end
545
566
  else
546
- panel.link(:text, strg).click(:wait => false)
567
+ panel.link(:text, what).click(:wait => false)
547
568
  end
548
569
  sleep_for(1)
549
570
  if validate(browser, @myName, __LINE__)
550
- passed_to_log("Panel '#{strg}' (by :text) closed.")
571
+ passed_to_log("Panel '#{what}' (by :text) closed.")
551
572
  true
552
573
  end
553
574
  else
@@ -557,104 +578,110 @@ category: Logon
557
578
  failed_to_log("Click on '#{strg}'(by :text) failed: '#{$!}' (#{__LINE__})")
558
579
  end
559
580
 
560
- # def close_modal_ie(title="", button="OK", text='', side = 'primary', wait = WAIT)
561
- def close_popup(title, button = "OK", text = '', side = 'primary', wait = WAIT, desc = '', quiet = false)
562
- #TODO needs simplifying and debug code cleaned up
563
- title = translate_popup_title(title)
564
- msg = "'#{title}'"
565
- msg << " with text '#{text}'" if text.length > 0
566
- msg << " (#{desc})" if desc.length > 0
567
- @ai.Opt("WinSearchChildren", 1) # Match any substring in the title
568
- if @ai.WinWait(title, text, wait) > 0
569
- myHandle = @ai.WinGetHandle(title, text)
570
- full_text = @ai.WinGetText(title)
571
- #debug_to_report("Found popup handle:'#{myHandle}', title:'#{title}', text:'#{full_text}'")
572
- if myHandle.length > 0
573
- debug_to_log("hwnd: #{myHandle.inspect}")
574
- passed_to_log("#{msg} appeared.") unless quiet
575
- sleep_for(0.5)
576
- @ai.WinActivate(title, text)
577
- if @ai.WinActive(title, text) # > 0 #Hack to prevent fail when windows session locked
578
- debug_to_log("#{msg} activated.")
579
- if @ai.ControlFocus(title, text, button) # > 0
580
- controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
581
- if not controlHandle
582
- button = "&#{button}"
583
- controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
584
- end
585
- debug_to_log("Handle for button '#{button}': [#{controlHandle}]")
586
- debug_to_log("#{msg} focus gained.")
587
- # sleep_for(2)
588
- if @ai.ControlClick(title, text, button, side) # > 0
589
- # if @ai.ControlClick(title, text, "[Handle:#{controlHandle}]", side) > 0
590
- # debug_to_log("#{msg} #{side} click on 'Handle:#{controlHandle}'." )
591
- debug_to_log("#{msg} #{side} click on '#{button}' successful.")
592
- sleep_for(1)
593
- if @ai.WinExists(title, text) > 0
594
- debug_to_log("#{msg} close popup failed on click '#{button}'. Trying WinClose. (#{__LINE__})")
595
- @ai.WinClose(title, text)
596
- if @ai.WinExists(title, text) > 0
597
- debug_to_log("#{msg} close popup failed with WinClose('#{title}','#{text}'). (#{__LINE__})")
598
- @ai.WinKill(title, text)
599
- if @ai.WinExists(title, text) > 0
600
- debug_to_log("#{msg} close popup failed with WinKill('#{title}','#{text}'). (#{__LINE__})")
601
- else
602
- debug_to_log("#{msg} closed successfully with WinKill('#{title}','#{text}').")
603
- end
604
- else
605
- debug_to_log("#{msg} closed successfully with WinClose('#{title}','#{text}').")
606
- end
607
- else
608
- passed_to_log("#{msg} closed successfully.") unless quiet
609
- end
610
- else
611
- failed_to_log("#{msg} #{side} click on '#{button}' failed. (#{__LINE__})")
612
- end
613
- else
614
- failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
615
- end
616
- else
617
- failed_to_log("#{msg} Unable to activate (#{__LINE__})")
618
- end
619
- else
620
- failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
621
- end
622
- else
623
- failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
624
- end
625
- rescue
626
- failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
627
- end
628
-
629
- alias close_popup_validate_text close_popup
630
-
631
- def close_popup_by_text(popup, strg = 'Close', desc = '')
581
+ #def close_modal_ie(title, button = "OK", text = '', side = 'primary', wait = WAIT, desc = '', quiet = false)
582
+ # #TODO needs simplifying and debug code cleaned up
583
+ # title = translate_popup_title(title)
584
+ # msg = "'#{title}'"
585
+ # msg << " with text '#{text}'" if text.length > 0
586
+ # msg << " (#{desc})" if desc.length > 0
587
+ # @ai.Opt("WinSearchChildren", 1) # Match any substring in the title
588
+ # if @ai.WinWait(title, text, wait) > 0
589
+ # myHandle = @ai.WinGetHandle(title, text)
590
+ # full_text = @ai.WinGetText(title)
591
+ # #debug_to_report("Found popup handle:'#{myHandle}', title:'#{title}', text:'#{full_text}'")
592
+ # if myHandle.length > 0
593
+ # debug_to_log("hwnd: #{myHandle.inspect}")
594
+ # passed_to_log("#{msg} appeared.") unless quiet
595
+ # sleep_for(0.5)
596
+ # @ai.WinActivate(title, text)
597
+ # if @ai.WinActive(title, text) # > 0 #Hack to prevent fail when windows session locked
598
+ # debug_to_log("#{msg} activated.")
599
+ # if @ai.ControlFocus(title, text, button) # > 0
600
+ # controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
601
+ # if not controlHandle
602
+ # button = "&#{button}"
603
+ # controlHandle = @ai.ControlGetHandle(title, '', "[CLASS:Button; TEXT:#{button}]")
604
+ # end
605
+ # debug_to_log("Handle for button '#{button}': [#{controlHandle}]")
606
+ # debug_to_log("#{msg} focus gained.")
607
+ # # sleep_for(2)
608
+ # if @ai.ControlClick(title, text, button, side) # > 0
609
+ # # if @ai.ControlClick(title, text, "[Handle:#{controlHandle}]", side) > 0
610
+ # # debug_to_log("#{msg} #{side} click on 'Handle:#{controlHandle}'." )
611
+ # debug_to_log("#{msg} #{side} click on '#{button}' successful.")
612
+ # sleep_for(1)
613
+ # if @ai.WinExists(title, text) > 0
614
+ # debug_to_log("#{msg} close popup failed on click '#{button}'. Trying WinClose. (#{__LINE__})")
615
+ # @ai.WinClose(title, text)
616
+ # if @ai.WinExists(title, text) > 0
617
+ # debug_to_log("#{msg} close popup failed with WinClose('#{title}','#{text}'). (#{__LINE__})")
618
+ # @ai.WinKill(title, text)
619
+ # if @ai.WinExists(title, text) > 0
620
+ # debug_to_log("#{msg} close popup failed with WinKill('#{title}','#{text}'). (#{__LINE__})")
621
+ # else
622
+ # debug_to_log("#{msg} closed successfully with WinKill('#{title}','#{text}').")
623
+ # end
624
+ # else
625
+ # debug_to_log("#{msg} closed successfully with WinClose('#{title}','#{text}').")
626
+ # end
627
+ # else
628
+ # passed_to_log("#{msg} closed successfully.") unless quiet
629
+ # end
630
+ # else
631
+ # failed_to_log("#{msg} #{side} click on '#{button}' failed. (#{__LINE__})")
632
+ # end
633
+ # else
634
+ # failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
635
+ # end
636
+ # else
637
+ # failed_to_log("#{msg} Unable to activate (#{__LINE__})")
638
+ # end
639
+ # else
640
+ # failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
641
+ # end
642
+ # else
643
+ # failed_to_log("#{msg} did not appear after #{wait} seconds. (#{__LINE__})")
644
+ # end
645
+ #rescue
646
+ # failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
647
+ #end
648
+
649
+ # Close an browser window (popup) by clicking a link within it identified by the *:text* value of the link.
650
+ # @param [Watir::Browser] popup A reference to the browser window or container element to be closed.
651
+ # @param [String] what Uniquely identify the *:link* element within the popup by the value in its *:text* attribute.
652
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
653
+ def close_popup_by_text(popup, what = 'Close', desc = '')
632
654
  count = 0
633
655
  url = popup.url
634
656
  if validate(popup, @myName, __LINE__)
635
- count = string_count_in_string(popup.text, strg)
657
+ count = string_count_in_string(popup.text, what)
636
658
  if count > 0
637
- # @waiter.wait_until( browser.link(:text, strg).exists? ) if @waiter
638
659
  begin
639
- popup.link(:text, strg).click
660
+ popup.link(:text, what).click
640
661
  rescue => e
641
- if not rescue_me(e, __method__, "link(:text,'#{strg}')", "#{popup.class}")
662
+ if not rescue_me(e, __method__, "link(:text,'#{what}')", "#{popup.class}")
642
663
  raise e
643
664
  end
644
665
  end
645
- passed_to_log("Popup #{url} closed by clicking link with text '#{strg}'. #{desc}")
666
+ passed_to_log("Popup #{url} closed by clicking link with text '#{what}'. #{desc}")
646
667
  true
647
668
  else
648
- failed_to_log("Link :text=>'#{strg}' for popup #{url} not found. #{desc}")
669
+ failed_to_log("Link :text=>'#{what}' for popup #{url} not found. #{desc}")
649
670
  end
650
671
  end
651
672
  rescue
652
- failed_to_log("Close popup #{url} with click link :text+>'#{strg}' failed: '#{$!}' (#{__LINE__})")
673
+ failed_to_log("Close popup #{url} with click link :text+>'#{what}' failed: '#{$!}' (#{__LINE__})")
653
674
  debug_to_log("#{strg} appears #{count} times in popup.text.")
654
675
  raise
655
676
  end
656
677
 
657
- # #close a modal dialog
678
+ # Close a modal dialog.
679
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
680
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
681
+ # @param [String] button The display name of the button to be clicked.
682
+ # @param [String] text The text of the window to be closed. Matched from beginning of string.
683
+ # @param [String] side A string identifying which mouse button to click.
684
+ # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
658
685
  def close_modal(browser, title="", button="OK", text='', side = 'primary', wait = WAIT)
659
686
  case @targetBrowser.abbrev
660
687
  when 'IE'
@@ -669,16 +696,27 @@ category: Logon
669
696
  end
670
697
 
671
698
  # TODO: Logging
672
- def close_modal_c(browser, title)
673
- browser.window(:url, title).close
699
+ # Close a Chrome modal popup by :url.
700
+ def close_modal_c(browser, url)
701
+ browser.window(:url, url).close
674
702
  end
675
703
 
676
704
  # TODO: Logging
705
+ # Close a Safari modal popup by closing the frontmost Safari dialog. MacOS only
677
706
  def close_modal_s
678
707
  # simply closes the frontmost Safari dialog
679
708
  Appscript.app("Safari").activate; Appscript.app("System Events").processes["Safari"].key_code(52)
680
709
  end
681
710
 
711
+ # Close an IE modal popup by its title.
712
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
713
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
714
+ # @param [String] button The display name of the button to be clicked.
715
+ # @param [String] text The text of the window to be closed. Matched from beginning of string.
716
+ # @param [String] side A string identifying which mouse button to click.
717
+ # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
718
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
719
+ # @param [Boolean] quiet If true, fewer messages and pass/fail validations are logged.
682
720
  def close_modal_ie(browser, title="", button="OK", text='', side = 'primary', wait = WAIT, desc = '', quiet = false)
683
721
  #TODO needs simplifying, incorporating text verification, and debug code cleaned up
684
722
  title = translate_popup_title(title)
@@ -736,9 +774,19 @@ category: Logon
736
774
  failed_to_log("Close popup title=#{title} failed: '#{$!}' (#{__LINE__})")
737
775
  end
738
776
 
777
+ alias close_popup_validate_text close_modal_ie
778
+ alias close_popup close_modal_ie
779
+
739
780
  # private :close_modal_ie
740
781
 
741
- def close_modal_ff(browser, title="", button=nil, text="", side='')
782
+ # Close a Firefox modal popup by its title.
783
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
784
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
785
+ # @param [String] button The display name of the button to be clicked.
786
+ # @param [String] text The text of the window to be closed. Matched from beginning of string.
787
+ # @param [String] side A string identifying which mouse button to click.
788
+ # @return [Boolean] True if the modal is successfully closed.
789
+ def close_modal_ff(browser, title="", button=nil, text='', side='')
742
790
  title = translate_popup_title(title)
743
791
  msg = "Modal dialog (popup): title=#{title} button='#{button}' text='#{text}' side='#{side}':"
744
792
  modal = browser.modal_dialog(:timeout => WAIT)
@@ -762,6 +810,7 @@ category: Logon
762
810
  failed_to_log("#{msg} close failed. (#{__LINE__})")
763
811
  else
764
812
  passed_to_log("#{msg} closed successfully.")
813
+ true
765
814
  end
766
815
  else
767
816
  failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
@@ -770,6 +819,15 @@ category: Logon
770
819
  failed_to_log("#{msg} Unable to validate modal popup: '#{$!}'. (#{__LINE__})")
771
820
  end
772
821
 
822
+ # Wait for a modal popup to appear and then close it.
823
+ # Used when modal popup in response to browser action is intermittent or unpredictable.
824
+ # @param [String] title The title of the window to be closed. Matched from beginning of string.
825
+ # @param [String] text The text of the window to be closed. Matched from beginning of string.
826
+ # @param [String] button The display name of the button to be clicked.
827
+ # @param [String] side A string identifying which mouse button to click.
828
+ # @param [Fixnum] wait Number of seconds to wait for the popup to be seen.
829
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
830
+ # @return [Boolean] True if the modal is successfully closed.
773
831
  def handle_popup(title, text = '', button= 'OK', side = 'primary', wait = WAIT, desc = '')
774
832
  title = translate_popup_title(title)
775
833
  msg = "'#{title}'"
@@ -846,6 +904,12 @@ category: Logon
846
904
 
847
905
  end
848
906
 
907
+ # Return a reference to an IE browser window based on one of its attributes.
908
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
909
+ # @param [Symbol] how The element attribute used to identify the window: :url, :title, or :hwnd.
910
+ # @param [String, Regexp] what A string or a regular expression to be found in the *how* attribute that uniquely identifies the element.
911
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
912
+ # @return [Watir::IE] A reference to the popup.
849
913
  def find_popup(browser, how, what, desc = '')
850
914
  msg = "Find popup :#{how}=>'#{what}'. #{desc}"
851
915
  popup = Watir::IE.find(how, what) # TODO: too browser specific
@@ -862,11 +926,13 @@ category: Logon
862
926
  failed_to_log("Unable to find popup :#{how}=>'#{what}'. #{desc} '#{$!}' (#{__LINE__})")
863
927
  end
864
928
 
929
+ # Confirm that the object passed in *browser* is actually a Browser object.
930
+ # @param [Watir::Browser] browser A reference to the window or container element to be tested.
865
931
  def is_browser?(browser)
866
932
  myClass = browser.class.to_s
867
933
  case @targetBrowser.abbrev
868
934
  when 'IE'
869
- myClass =~ /Watir::/i # TODO: should this be /Watir::IE/i ?
935
+ myClass =~ /Watir::IE|Watir::Browser/i
870
936
  when 'FF'
871
937
  myClass =~ /Watir::Browser/i
872
938
  when 'S'
@@ -878,6 +944,11 @@ category: Logon
878
944
 
879
945
  alias is_browser is_browser?
880
946
 
947
+ # Translate window title supplied in *title* to a title appropriate for the targeted browser and version
948
+ # actually being run.
949
+ # Used primarily for handling of modal popups and dialogs.
950
+ # This allows cross-browser compatibility for handling modal popups and other windows accessed by titlt.
951
+ # @param [String] title The title of the window to be closed.
881
952
  def translate_popup_title(title)
882
953
  new_title = title
883
954
  case @browserAbbrev
@@ -943,6 +1014,9 @@ category: Logon
943
1014
  new_title
944
1015
  end
945
1016
 
1017
+ # Identify the exact version of the Browser currently being executed.
1018
+ # @todo Bring up to date with newer browser versions
1019
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
946
1020
  def get_browser_version(browser)
947
1021
  debug_to_log("starting get_browser_version")
948
1022
  case @targetBrowser.abbrev
@@ -1020,45 +1094,48 @@ category: Logon
1020
1094
 
1021
1095
  protected :get_browser_version
1022
1096
 
1023
- def close_popup_by_button_title(popup, strg, desc = '')
1024
- click(popup, :link, :title, strg, desc)
1025
- end
1097
+ #def filter_bailout_from_rescue(err, msg)
1098
+ # if msg =~ /bailing out/i
1099
+ # raise err
1100
+ # else
1101
+ # error_to_log(msg)
1102
+ # end
1103
+ #end
1026
1104
 
1027
- def filter_bailout_from_rescue(err, msg)
1028
- if msg =~ /bailing out/i
1029
- raise err
1030
- else
1031
- error_to_log(msg)
1032
- end
1033
- end
1105
+ # @!group Browser
1034
1106
 
1107
+ # Open and attach a browser popup window where the link to open it and its title contain the same string.
1108
+ # @deprecated
1035
1109
  def open_popup_through_link_title(browser, title, pattern, name)
1036
1110
  click_title(browser, title)
1037
1111
  #TODO need some kind of wait for process here
1038
1112
  sleep_for 2
1039
- attach_iepopup(browser, pattern, name)
1113
+ attach_popup_by_url(browser, pattern, name)
1040
1114
  rescue
1041
1115
  failed_to_log("Unable to open popup '#{name}': '#{$!}' (#{__LINE__})")
1042
1116
  end
1043
1117
 
1044
- =begin rdoc
1045
- Verifies health of the browser. Looks for common http and system errors that are unrecoverable and
1046
- attempts to gracefully bail out of the script. Calls rescue_me() when trying to capture the text to filter out
1047
- known false errors and handle container elements that don't respond to the .text method.
1048
- category: bullet-proofing
1049
- tags: system, http, fatal, error
1050
- example: See click()
1051
- related methods: rescue_me()
1052
- =end
1053
- def validate(browser, fileName = '', lnbr = __LINE__, dbg = false)
1118
+ # @!group Error Handling
1119
+
1120
+ # Verifies health of the browser. Looks for common http and system errors that are unrecoverable and
1121
+ # attempts to gracefully bail out of the script.
1122
+ # Calls rescue_me() when trying to capture the text to filter out known false errors
1123
+ # and handle container elements that don't respond to the .text method.
1124
+ # @param [Watir::Browser] browser A reference to the browser window or container element to be tested.
1125
+ # @param [String] file_name The file name of the executing script.
1126
+ # @param [Fixnum] lnbr Contains a message or description intended to appear in the log and/or report output
1127
+ # @param [Boolean] dbg If set to true additional debug messages are written to the log.
1128
+ #
1129
+ # @return [Boolean] True if no error conditions have been encountered.
1130
+ def validate(browser, file_name = '', lnbr = "#{__LINE__}", dbg = false)
1054
1131
  debug_to_log("#{__method__} begin") if dbg
1055
1132
  msg = ''
1056
1133
  myOK = true
1057
1134
  if not browser
1058
- msg = "#{fileName}----browser is nil object. (#{lnbr})"
1135
+ msg = "#{file_name}----browser is nil object. (#{lnbr})"
1059
1136
  myOK = false
1060
1137
  elsif not is_browser?(browser)
1061
- msg = "#{fileName}----not a browser. (#{lnbr})"
1138
+ msg = "#{file_name}----not a browser. (#{lnbr})"
1062
1139
  debug_to_log(browser.inspect)
1063
1140
  myOK = false
1064
1141
 
@@ -1094,94 +1171,94 @@ related methods: rescue_me()
1094
1171
 
1095
1172
  if browser_text
1096
1173
  if browser_text.match(/unrecognized error condition has occurred/i)
1097
- msg = "#{fileName}----Unrecognized Exception occurred. (#{lnbr})"
1174
+ msg = "#{file_name}----Unrecognized Exception occurred. (#{lnbr})"
1098
1175
  myOK = false
1099
1176
 
1100
1177
  elsif browser_text.match(/cannot find server or dns error/i)
1101
- msg = "#{fileName}----Cannot find server error or DNS error. (#{lnbr})"
1178
+ msg = "#{file_name}----Cannot find server error or DNS error. (#{lnbr})"
1102
1179
  myOK = false
1103
1180
 
1104
1181
  elsif browser_text.match(/the rpc server is unavailable/i)
1105
- msg = "#{fileName}----RPC server unavailable. (#{lnbr})"
1182
+ msg = "#{file_name}----RPC server unavailable. (#{lnbr})"
1106
1183
  myOK = false
1107
1184
 
1108
1185
  elsif browser_text.match(/404 not found/i) or
1109
1186
  browser_text.match(/the page you were looking for does\s*n[o']t exist/i)
1110
- msg = "#{fileName}----RFC 2068 HTTP/1.1: 404 URI Not Found. (#{lnbr})"
1187
+ msg = "#{file_name}----RFC 2068 HTTP/1.1: 404 URI Not Found. (#{lnbr})"
1111
1188
  myOK = false
1112
1189
 
1113
1190
  elsif browser_text.match(/we're sorry, but something went wrong/i) or
1114
1191
  browser_text.match(/http status 500/i)
1115
- msg = "#{fileName}----RFC 2068 HTTP/1.1: 500 Internal Server Error. (#{lnbr})"
1192
+ msg = "#{file_name}----RFC 2068 HTTP/1.1: 500 Internal Server Error. (#{lnbr})"
1116
1193
  myOK = false
1117
1194
 
1118
1195
  elsif browser_text.match(/internet explorer cannot display the webpage/i)
1119
- msg = "#{fileName}----Probably RFC 2068 HTTP/1.1: 500 Internal Server Error. (#{lnbr})"
1196
+ msg = "#{file_name}----Probably RFC 2068 HTTP/1.1: 500 Internal Server Error. (#{lnbr})"
1120
1197
  myOK = false
1121
1198
 
1122
1199
  elsif browser_text.match(/503.*service unavailable/i)
1123
- msg = "#{fileName}----RFC 2068 HTTP/1.1: 503 Service Unavailable. (#{lnbr})"
1200
+ msg = "#{file_name}----RFC 2068 HTTP/1.1: 503 Service Unavailable. (#{lnbr})"
1124
1201
  myOK = false
1125
1202
 
1126
1203
  elsif browser_text.match(/java.lang.NullPointerException/i)
1127
- msg = "#{fileName}----java.lang.NullPointerException. (#{lnbr})"
1204
+ msg = "#{file_name}----java.lang.NullPointerException. (#{lnbr})"
1128
1205
  myOK = false
1129
1206
 
1130
1207
  elsif browser_text.match(/due to unscheduled maintenance/i)
1131
- msg = "#{fileName}----Due to unscheduled maintenance. (#{lnbr})"
1208
+ msg = "#{file_name}----Due to unscheduled maintenance. (#{lnbr})"
1132
1209
  myOK = false
1133
1210
 
1134
1211
  elsif browser_text.match(/network\s+error\s*(.+)$/i)
1135
1212
  $1.chomp!
1136
- msg = "#{fileName}----Network Error #{$1}. (#{lnbr})"
1213
+ msg = "#{file_name}----Network Error #{$1}. (#{lnbr})"
1137
1214
  myOK = false
1138
1215
 
1139
1216
  elsif browser_text.match(/warning: page has expired/i)
1140
- msg = "#{fileName}----Page using information from form has expired. Not automatically resubmitted. (#{lnbr})"
1217
+ msg = "#{file_name}----Page using information from form has expired. Not automatically resubmitted. (#{lnbr})"
1141
1218
  myOK = false
1142
1219
 
1143
1220
  elsif browser_text.match(/no backend server available/i)
1144
- msg = "#{fileName}----Cannot Reach Server (#{lnbr})"
1221
+ msg = "#{file_name}----Cannot Reach Server (#{lnbr})"
1145
1222
  myOK = false
1146
1223
 
1147
1224
  elsif browser_text.match(/sign on\s+.+\s+unsuccessful/i)
1148
- msg = "#{fileName}----Invalid Id or Password (#{lnbr})"
1225
+ msg = "#{file_name}----Invalid Id or Password (#{lnbr})"
1149
1226
  myOK = false
1150
1227
 
1151
1228
  elsif browser_text.match(/you are not authorized/i)
1152
- msg = "#{fileName}----Not authorized to view this page. (#{lnbr})"
1229
+ msg = "#{file_name}----Not authorized to view this page. (#{lnbr})"
1153
1230
  myOK = false
1154
1231
 
1155
1232
  elsif browser_text.match(/too many incorrect login attempts have been made/i)
1156
- msg = "#{fileName}----Invalid Id or Password. Too many tries. (#{lnbr})"
1233
+ msg = "#{file_name}----Invalid Id or Password. Too many tries. (#{lnbr})"
1157
1234
  myOK = false
1158
1235
 
1159
1236
  elsif browser_text.match(/system error\.\s+an error has occurred/i)
1160
- msg = "#{fileName}----System Error. An error has occurred. Please try again or call the Help Line for assistance. (#{lnbr})"
1237
+ msg = "#{file_name}----System Error. An error has occurred. Please try again or call the Help Line for assistance. (#{lnbr})"
1161
1238
  myOK = false
1162
1239
 
1163
1240
  elsif browser_text.match(/Internal Server failure,\s+NSAPI plugin/i)
1164
- msg = "#{fileName}----Internal Server failure, NSAPI plugin. (#{lnbr})"
1241
+ msg = "#{file_name}----Internal Server failure, NSAPI plugin. (#{lnbr})"
1165
1242
  myOK = false
1166
1243
 
1167
1244
  elsif browser_text.match(/Error Page/i)
1168
- msg = "#{fileName}----Error Page. (#{lnbr})"
1245
+ msg = "#{file_name}----Error Page. (#{lnbr})"
1169
1246
  myOK = false
1170
1247
 
1171
1248
  elsif browser_text.match(/The website cannot display the page/i)
1172
- msg = "#{fileName}----HTTP 500. (#{lnbr})"
1249
+ msg = "#{file_name}----HTTP 500. (#{lnbr})"
1173
1250
  myOK = false
1174
1251
 
1175
1252
  # elsif browser_text.match(/Insufficient Data/i)
1176
- # msg = "#{fileName}----Insufficient Data. (#{lnbr})"
1253
+ # msg = "#{file_name}----Insufficient Data. (#{lnbr})"
1177
1254
  # myOK = false
1178
1255
 
1179
1256
  elsif browser_text.match(/The timeout period elapsed/i)
1180
- msg = "#{fileName}----Time out period elapsed or server not responding. (#{lnbr})"
1257
+ msg = "#{file_name}----Time out period elapsed or server not responding. (#{lnbr})"
1181
1258
  myOK = false
1182
1259
 
1183
1260
  elsif browser_text.match(/Unexpected\s+errors*\s+occur+ed\.\s+(?:-+)\s+(.+)/i)
1184
- msg = "#{fileName}----Unexpected errors occurred. #{$2.slice(0, 120)} (#{lnbr})"
1261
+ msg = "#{file_name}----Unexpected errors occurred. #{$2.slice(0, 120)} (#{lnbr})"
1185
1262
  if not browser_text.match(/close the window and try again/i)
1186
1263
  myOK = false
1187
1264
  else
@@ -1189,15 +1266,15 @@ related methods: rescue_me()
1189
1266
  end
1190
1267
 
1191
1268
  elsif browser_text.match(/Server Error in (.+) Application\.\s+(?:-+)\s+(.+)/i)
1192
- msg = "#{fileName}----Server Error in #{1} Application. #{$2.slice(0, 100)} (#{lnbr})"
1269
+ msg = "#{file_name}----Server Error in #{1} Application. #{$2.slice(0, 100)} (#{lnbr})"
1193
1270
  myOK = false
1194
1271
 
1195
1272
  elsif browser_text.match(/Server Error in (.+) Application\./i)
1196
- msg = "#{fileName}----Server Error in #{1} Application. '#{browser_text.slice(0, 250)}...' (#{lnbr})"
1273
+ msg = "#{file_name}----Server Error in #{1} Application. '#{browser_text.slice(0, 250)}...' (#{lnbr})"
1197
1274
  myOK = false
1198
1275
 
1199
1276
  elsif browser_text.match(/An error has occur+ed\. Please contact support/i)
1200
- msg = "#{fileName}----An error has occurred. Please contact support (#{lnbr})"
1277
+ msg = "#{file_name}----An error has occurred. Please contact support (#{lnbr})"
1201
1278
  myOK = false
1202
1279
 
1203
1280
  end
@@ -1228,6 +1305,55 @@ related methods: rescue_me()
1228
1305
 
1229
1306
  alias validate_browser validate
1230
1307
 
1308
+ # @!endgroup Error Handling
1309
+
1310
+ # @!group Backward compatible usages
1311
+
1312
+ # Returns a reference to a browser window using the window's *:url* attribute. Calls attach_browser().
1313
+ # @example
1314
+ # mainwindow = open_browser('www.google.com')
1315
+ # click(mainwindow, :button, :id, 'an id string') # click a button that opens another browser window
1316
+ # popup = attach_browser_by_url(mainwindow, '[url of new window]')
1317
+ # @param [Watir::Browser] browser A reference to the current browser window.
1318
+ # @param [String, Regexp] what The value in the targeted attribute that uniquely identifies the new window
1319
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
1320
+ # @return [Watir::Browser]
1321
+ def attach_browser_by_url(browser, what, desc = '')
1322
+ attach_browser(browser, :url, what, desc)
1323
+ end
1324
+
1325
+ alias attach_browser_with_url attach_browser_by_url
1326
+
1327
+ # Returns a reference to a new browser window identified by its *:title* attribute. Used to attach a new browser window to a variable
1328
+ # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
1329
+ # @param (see #attach_browser_by_url)
1330
+ def attach_popup_by_title(browser, what, desc = '')
1331
+ attach_popup(browser, :title, what, desc)
1332
+ end
1333
+
1334
+ # Returns a reference to a new browser window identified by its *:url* attribute. Used to attach a new browser window to a variable
1335
+ # which can then be passed to methods that require a *browser* parameter. Calls attach_browser().
1336
+ # @param (see #attach_browser_by_url)
1337
+ def attach_popup_by_url(browser, what, desc = '')
1338
+ attach_popup(browser, :url, what, desc)
1339
+ end
1340
+
1341
+ alias get_popup_with_url attach_popup_by_url
1342
+ alias attach_popup_with_url attach_popup_by_url
1343
+ alias attach_iepopup attach_popup_by_url
1344
+
1345
+ # Close a popup browser window (non-modal) by clicking on a link with :title *what*.
1346
+ # This method does not check to make sure the popup is actually closed.
1347
+ # @param [Watir::Browser] popup A reference to the current popup browser window.
1348
+ # @param [String, Regexp] what The value in the targeted attribute that uniquely identifies the new window
1349
+ # @param [String] desc Contains a message or description intended to appear in the log and/or report output
1350
+ # @return [Boolean] True if the click is successful.
1351
+ def close_popup_by_button_title(popup, what, desc = '')
1352
+ click(popup, :link, :title, what, desc)
1353
+ end
1354
+
1355
+ # @!endgroup Backward
1356
+
1231
1357
 
1232
1358
  end
1233
1359
  end