rwebspec 3.1.4 → 4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,745 @@
1
+ # convenient methods to drive the browser.
2
+ #
3
+ # Instead of
4
+ # browser.click_button("submit")
5
+ # You can just use
6
+ # click_button("submit")
7
+ #
8
+ require File.join(File.dirname(__FILE__), '..', 'rwebspec-common', 'popup')
9
+ require File.join(File.dirname(__FILE__), '..', 'rwebspec-common', 'matchers', "contains_text.rb")
10
+
11
+ require 'timeout'
12
+ require 'uri'
13
+
14
+ module RWebSpec
15
+ module Driver
16
+ include RWebSpec::TestWisePlugin
17
+ include RWebSpec::Popup
18
+
19
+ # open a browser, and set base_url via hash, but does not acually
20
+ #
21
+ # example:
22
+ # open_browser :base_url => http://localhost:8080
23
+ #
24
+ # There are 3 ways to set base url
25
+ # 1. pass as first argument
26
+ # 2. If running using TestWise, used as confiured
27
+ # 3. Use default value set
28
+ #
29
+ #
30
+ # New Options:
31
+ # :browser => :ie | :firefox | :chrome
32
+ def open_browser(base_url = nil, options = {})
33
+ # puts "[DEBUG] [SeleniumDriver] Callling open_browser #{base_url}"
34
+ begin
35
+ support_unicode
36
+ rescue => e
37
+ puts "Unicode may not work in IE, #{e}"
38
+ end
39
+
40
+ base_url ||= $TESTWISE_PROJECT_BASE_URL
41
+ base_url ||= $BASE_URL
42
+ raise "base_url must be set" if base_url.nil?
43
+
44
+ default_options = {:speed => "fast",
45
+ :visible => true,
46
+ :highlight_colour => 'yellow',
47
+ :close_others => true,
48
+ :start_new => true, # start a new browser always
49
+ :go => true }
50
+
51
+ options = default_options.merge options
52
+
53
+ if $TESTWISE_BROWSER
54
+ options[:browser] = $TESTWISE_BROWSER.downcase
55
+ end
56
+
57
+ if options[:firefox] && options[:browser].nil? then
58
+ options[:browser] = "firefox" # legacy
59
+ end
60
+
61
+ if base_url =~ /^file:/
62
+ uri_base = base_url
63
+ else
64
+ uri = URI.parse(base_url)
65
+ uri_base = "#{uri.scheme}://#{uri.host}:#{uri.port}"
66
+ end
67
+
68
+ if options[:start_new]
69
+ # puts "[DEBUG] [SeleniumBrowser] creating a new browser"
70
+ @web_browser = WebBrowser.new(uri_base, nil, options)
71
+ # puts "[DEBUG] [SeleniumBrowser] browser: #{@web_browser.inspect}"
72
+ else
73
+ @web_browser = WebBrowser.reuse(uri_base, options) # Reuse existing browser
74
+ end
75
+
76
+ if base_url =~ /^file:/
77
+ goto_url(base_url) # for files, no base url
78
+ else
79
+ (uri.path.length == 0) ? begin_at(base_url) : begin_at(uri.path) if options[:go]
80
+ end
81
+
82
+ # remembering browser handle for debugging need
83
+ $browser = @web_browser
84
+ return @web_browser
85
+ end
86
+
87
+ alias open_browser_with open_browser
88
+
89
+ # return the underlying RWebSpec::WebDriver::Browser object
90
+ def browser
91
+ @web_browser
92
+ end
93
+
94
+
95
+ def quit
96
+ @web_browser.quit
97
+ end
98
+
99
+ def find_element(how, what)
100
+ @web_browser.find_element(how, what)
101
+ end
102
+
103
+ def find_elements(how, what)
104
+ @web_browser.find_elements(how, what)
105
+ end
106
+
107
+ # Close the current browser window (started by the script). If no browser started, then close
108
+ # all browser windows.
109
+ #
110
+ def close_browser
111
+ if @web_browser
112
+ # Old TestWise version
113
+ # @web_browser.close_browser unless $TESTWISE_LEAVE_BROWSER_OPEN_AFTER_RUN
114
+ @web_browser.close_browser
115
+ else
116
+ WebBrowser.close_all_browsers
117
+ end
118
+ end
119
+ alias close_ie close_browser
120
+
121
+
122
+ # Close all opening browser windows
123
+ #
124
+ def close_all_browsers
125
+ #TODO
126
+ close_browser
127
+ end
128
+
129
+ # Verify the next page following an operation.
130
+ #
131
+ # Typical usage:
132
+ # login_page.click_login
133
+ # expect_page HomePage
134
+ def expect_page(page_clazz, argument = nil)
135
+ if argument
136
+ @web_browser.expect_page(page_clazz, argument)
137
+ else
138
+ @web_browser.expect_page(page_clazz)
139
+ end
140
+ end
141
+
142
+ def context
143
+ @web_browser.context
144
+ end
145
+
146
+ # Starting browser with a URL
147
+ #
148
+ # Example:
149
+ # begin_at("http://www.itest2.com")
150
+ def begin_at(url)
151
+ # puts "[DEBUG] [SeleniumBrowser] begin_at #{url}"
152
+ dump_caller_stack
153
+ @web_browser.begin_at(url)
154
+ end
155
+
156
+ # Return the Watir::IE instance
157
+ #
158
+ def ie
159
+ @web_browser.ie
160
+ end
161
+
162
+ # Return the FireWatir::Firefox instance
163
+ #
164
+ def firefox
165
+ @web_browser.firefox
166
+ end
167
+
168
+ def is_firefox?
169
+ @web_browser.is_firefox? if @web_browser
170
+ end
171
+
172
+ def is_ie?
173
+ @web_browser.is_ie? if @web_browser
174
+ end
175
+
176
+ def is_htmlunit?
177
+ RUBY_PLATFORM =~ /java/ && @web_browser
178
+ end
179
+
180
+ # Go to another page on the testing site.
181
+ #
182
+ # open_browser("http://www.itest2.com")
183
+ # goto_page("/demo") # visit page http://www.itest2.com/demo
184
+ #
185
+ def goto_page(page)
186
+ perform_operation {
187
+ @web_browser.goto_page(page) if @web_browser
188
+ }
189
+ end
190
+ alias visit goto_page
191
+
192
+ # Go to another web site, normally different site being tested on
193
+ #
194
+ # open_browser("http://www.itest2.com")
195
+ # goto_url("http://myorganized.info")
196
+ def goto_url(url)
197
+ puts "Calling web_browser goto: #{@web_browser.inspect}"
198
+ @web_browser.goto_url url
199
+ end
200
+
201
+ # Attach to existinb browser window
202
+ #
203
+ # attach_browser(:title, )
204
+ def attach_browser(how, what, options = {})
205
+ #TODO
206
+ options.merge!(:browser => is_firefox? ? "Firefox" : "IE") unless options[:browser]
207
+ begin
208
+ options.merge!(:base_url => browser.context.base_url)
209
+ rescue => e
210
+ puts "failed to set base_url, ignore : #{e}"
211
+ end
212
+ WebBrowser.attach_browser(how, what, options)
213
+ end
214
+
215
+ # Reuse current an opened browser window instead of opening a new one
216
+ # example:
217
+ # use_current_browser(:title, /.*/) # use what ever browser window
218
+ # use_current_browser(:title, "TestWise") # use browser window with title "TestWise"
219
+ def use_current_browser(how = :title, what = /.*/)
220
+ @web_browser = $browser || WebBrowser.attach_browser(how, what)
221
+ end
222
+
223
+ [:back, :forward, :refresh].each do |method|
224
+ define_method(method) do
225
+ perform_operation { @web_browser.send(method) if @web_browser }
226
+ end
227
+ end
228
+ alias refresh_page refresh
229
+ alias go_back back
230
+ alias go_forward forward
231
+
232
+ ##
233
+ # Delegate to WebTester
234
+ #
235
+ # Note:
236
+ # label(:id, "abc") # OK
237
+ # label(:id, :abc) # Error
238
+ #
239
+ # Depends on which object type, you can use following attribute
240
+ # More details: http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
241
+ #
242
+ # :id Used to find an element that has an "id=" attribute. Since each id should be unique, according to the XHTML specification, this is recommended as the most reliable method to find an object. *
243
+ # :name Used to find an element that has a "name=" attribute. This is useful for older versions of HTML, but "name" is deprecated in XHTML. *
244
+ # :value Used to find a text field with a given default value, or a button with a given caption, or a text field
245
+ # :text Used for links, spans, divs and other element that contain text.
246
+ # :index Used to find the nth element of the specified type on a page. For example, button(:index, 2) finds the second button. Current versions of WATIR use 1-based indexing, but future versions will use 0-based indexing.
247
+ # :class Used for an element that has a "class=" attribute.
248
+ # :title Used for an element that has a "title=" attribute.
249
+ # :xpath Finds the item using xpath query.
250
+ # :method Used only for forms, the method attribute of a form is either GET or POST.
251
+ # :action Used only for form elements, specifies the URL where the form is to be submitted.
252
+ # :href Used to identify a link by its "href=" attribute.
253
+ # :src Used to identify an image by its URL.
254
+ #
255
+
256
+ # area <area> tags
257
+ # button <input> tags with type=button, submit, image or reset
258
+ # check_box <input> tags with type=checkbox
259
+ # div <div> tags
260
+ # form <form> tags
261
+ # frame frames, including both the <frame> elements and the corresponding pages
262
+ # h1 - h6 <h1>, <h2>, <h3>, <h4>, <h5>, <h6> tags
263
+ # hidden <input> tags with type=hidden
264
+ # image <img> tags
265
+ # label <label> tags (including "for" attribute)
266
+ # li <li> tags
267
+ # link <a> (anchor) tags
268
+ # map <map> tags
269
+ # radio <input> tags with the type=radio; known as radio buttons
270
+ # select_list <select> tags, known as drop-downs or drop-down lists
271
+ # span <span> tags
272
+ # table <table> tags, including row and cell methods for accessing nested elements
273
+ # text_field <input> tags with the type=text (single-line), type=textarea (multi-line), and type=password
274
+ # p <p> (paragraph) tags, because
275
+ [:area, :button, :cell, :checkbox, :div, :form, :frame, :h1, :h2, :h3, :h4, :h5, :h6, :hidden, :image, :li, :link, :map, :pre, :row, :radio, :select_list, :span, :table, :text_field, :paragraph, :file_field, :label].each do |method|
276
+ define_method method do |* args|
277
+ perform_operation { @web_browser.send(method, * args) if @web_browser }
278
+ end
279
+ end
280
+ alias td cell
281
+ alias check_box checkbox # seems watir doc is wrong, checkbox not check_box
282
+ alias tr row
283
+
284
+
285
+ [:images, :links, :buttons, :select_lists, :checkboxes, :radios, :text_fields].each do |method|
286
+ define_method method do
287
+ perform_operation { @web_browser.send(method) if @web_browser }
288
+ end
289
+ end
290
+
291
+ # Check one or more checkboxes with same name, can accept a string or an array of string as values checkbox, pass array as values will try to set mulitple checkboxes.
292
+ #
293
+ # page.check_checkbox('bad_ones', 'Chicken Little')
294
+ # page.check_checkbox('good_ones', ['Cars', 'Toy Story'])
295
+ #
296
+ [:set_form_element, :click_link_with_text, :click_link_with_id, :submit, :click_button_with_id, :click_button_with_name, :click_button_with_caption, :click_button_with_value, :click_radio_option, :clear_radio_option, :check_checkbox, :uncheck_checkbox, :select_option].each do |method|
297
+ define_method method do |* args|
298
+ perform_operation { @web_browser.send(method, * args) if @web_browser }
299
+ end
300
+ end
301
+
302
+ alias enter_text set_form_element
303
+ alias set_hidden_field set_form_element
304
+ alias click_link click_link_with_text
305
+ alias click_button_with_text click_button_with_caption
306
+ alias click_button click_button_with_caption
307
+ alias click_radio_button click_radio_option
308
+ alias clear_radio_button clear_radio_option
309
+
310
+ # for text field can be easier to be identified by attribute "id" instead of "name", not recommended though
311
+ def enter_text_with_id(textfield_id, value)
312
+ perform_operation {
313
+ elements = find_elements(:id, textfield_id)
314
+ if elements.size == 1 then
315
+ elements[0].send_keys(value)
316
+ else
317
+ smaller_set = elements.select {|x| x.tag_name == "textarea" || (x.tag_name == "input" && x.attribute("text")) }
318
+ smaller_set[0].send_keys(value)
319
+ end
320
+ }
321
+ end
322
+
323
+ def perform_operation(& block)
324
+ begin
325
+ dump_caller_stack
326
+ operation_delay
327
+ check_for_pause
328
+ yield
329
+ rescue RuntimeError => re
330
+ puts "[DEBUG] operation error: #{re}"
331
+ raise re
332
+ # ensure
333
+ # puts "[DEBUG] ensure #{perform_ok}" unless perform_ok
334
+ end
335
+ end
336
+
337
+ def contains_text(text)
338
+ @web_browser.contains_text(text)
339
+ end
340
+
341
+ # In pages, can't use include, text.should include("abc") won't work
342
+ # Instead,
343
+ # text.should contains("abc"
344
+ def contains(str)
345
+ ContainsText.new(str)
346
+ end
347
+
348
+ alias contain contains
349
+
350
+ # Click image buttion with image source name
351
+ #
352
+ # For an image submit button <input name="submit" type="image" src="/images/search_button.gif">
353
+ # click_button_with_image("search_button.gif")
354
+ def click_button_with_image_src_contains(image_filename)
355
+ perform_operation {
356
+ @web_browser.click_button_with_image_src_contains(image_filename)
357
+ }
358
+ end
359
+
360
+ alias click_button_with_image click_button_with_image_src_contains
361
+
362
+ def new_popup_window(options)
363
+ @web_browser.new_popup_window(options)
364
+ end
365
+
366
+
367
+ # Warning: this does not work well with Firefox yet.
368
+ def element_text(elem_id)
369
+ @web_browser.element_value(elem_id)
370
+ end
371
+
372
+ # Identify DOM element by ID
373
+ # Warning: it is only supported on IE
374
+ def element_by_id(elem_id)
375
+ @web_browser.element_by_id(elem_id)
376
+ end
377
+
378
+ # ---
379
+ # For debugging
380
+ # ---
381
+ def dump_response(stream = nil)
382
+ @web_browser.dump_response(stream)
383
+ end
384
+
385
+ def default_dump_dir
386
+ if $TESTWISE_RUNNING_SPEC_ID && $TESTWISE_WORKING_DIR
387
+
388
+ $TESTWISE_DUMP_DIR = File.join($TESTWISE_WORKING_DIR, "dump")
389
+ FileUtils.mkdir($TESTWISE_DUMP_DIR) unless File.exists?($TESTWISE_DUMP_DIR)
390
+
391
+ spec_run_id = $TESTWISE_RUNNING_SPEC_ID
392
+ spec_run_dir_name = spec_run_id.to_s.rjust(4, "0") unless spec_run_id == "unknown"
393
+ to_dir = File.join($TESTWISE_DUMP_DIR, spec_run_dir_name)
394
+ else
395
+ to_dir = ENV['TEMP_DIR'] || (is_windows? ? "C:\\temp" : "/tmp")
396
+ end
397
+ end
398
+
399
+ # For current page souce to a file in specified folder for inspection
400
+ #
401
+ # save_current_page(:dir => "C:\\mysite", filename => "abc", :replacement => true)
402
+ def save_current_page(options = {})
403
+ default_options = {:replacement => true}
404
+ options = default_options.merge(options)
405
+ to_dir = options[:dir] || default_dump_dir
406
+
407
+ if options[:filename]
408
+ file_name = options[:filename]
409
+ else
410
+ file_name = Time.now.strftime("%m%d%H%M%S") + ".html"
411
+ end
412
+
413
+ Dir.mkdir(to_dir) unless File.exists?(to_dir)
414
+ file = File.join(to_dir, file_name)
415
+
416
+ content = page_source
417
+ base_url = @web_browser.context.base_url
418
+ current_url = @web_browser.url
419
+ current_url =~ /(.*\/).*$/
420
+ current_url_parent = $1
421
+ if options[:replacement] && base_url =~ /^http:/
422
+ File.new(file, "w").puts absolutize_page_hpricot(content, base_url, current_url_parent)
423
+ else
424
+ File.new(file, "w").puts content
425
+ end
426
+
427
+ end
428
+
429
+
430
+ # <link rel="stylesheet" type="text/css" href="/stylesheets/default.css" />
431
+ # '<script type="text/javascript" src="http://www.jeroenwijering.com/embed/swfobject.js"></script>'
432
+ # <script type="text/javascript" src="/javascripts/prototype.js"></script>
433
+ # <script type="text/javascript" src="/javascripts/scriptaculous.js?load=effects,builder"></script>
434
+ # <script type="text/javascript" src="/javascripts/extensions/gallery/lightbox.js"></script>
435
+ # <link href="/stylesheets/extensions/gallery/lightbox.css" rel="stylesheet" type="text/css" />
436
+ # <img src="images/mission_48.png" />
437
+ def absolutize_page(content, base_url, current_url_parent)
438
+ modified_content = ""
439
+ content.each_line do |line|
440
+ if line =~ /<script\s+.*src=["'']?(.*)["'].*/i then
441
+ script_src = $1
442
+ substitute_relative_path_in_src_line(line, script_src, base_url, current_url_parent)
443
+ elsif line =~ /<link\s+.*href=["'']?(.*)["'].*/i then
444
+ link_href = $1
445
+ substitute_relative_path_in_src_line(line, link_href, base_url, current_url_parent)
446
+ elsif line =~ /<img\s+.*src=["'']?(.*)["'].*/i then
447
+ img_src = $1
448
+ substitute_relative_path_in_src_line(line, img_src, base_url, current_url_parent)
449
+ end
450
+
451
+ modified_content += line
452
+ end
453
+ return modified_content
454
+ end
455
+
456
+ # absolutize_page referencs using hpricot
457
+ #
458
+ def absolutize_page_hpricot(content, base_url, parent_url)
459
+ return absolutize_page(content, base_url, parent_url) if RUBY_PLATFORM == 'java'
460
+ begin
461
+ require 'nokogiri'
462
+ doc = Nokogiri::HTML(content)
463
+ base_url.slice!(-1) if ends_with?(base_url, "/")
464
+ (doc/'link').each { |e| e['href'] = absolutify_url(e['href'], base_url, parent_url) || "" }
465
+ (doc/'img').each { |e| e['src'] = absolutify_url(e['src'], base_url, parent_url) || "" }
466
+ (doc/'script').each { |e| e['src'] = absolutify_url(e['src'], base_url, parent_url) || "" }
467
+ return doc.to_html
468
+ rescue => e
469
+ absolutize_page(content, base_url, parent_url)
470
+ end
471
+ end
472
+
473
+ ##
474
+ # change
475
+ # <script type="text/javascript" src="/javascripts/prototype.js"></script>
476
+ # to
477
+ # <script type="text/javascript" src="http://itest2.com/javascripts/prototype.js"></script>
478
+ def absolutify_url(src, base_url, parent_url)
479
+ if src.nil? || src.empty? || src == "//:" || src =~ /\s*http:\/\//i
480
+ return src
481
+ end
482
+
483
+ return "#{base_url}#{src}" if src =~ /^\s*\//
484
+ return "#{parent_url}#{src}" if parent_url
485
+ return src
486
+ end
487
+
488
+ # substut
489
+ def substitute_relative_path_in_src_line(line, script_src, host_url, page_parent_url)
490
+ unless script_src =~ /^["']?http:/
491
+ host_url.slice!(-1) if ends_with?(host_url, "/")
492
+ if script_src =~ /^\s*\// # absolute_path
493
+ line.gsub!(script_src, "#{host_url}#{script_src}")
494
+ else #relative_path
495
+ line.gsub!(script_src, "#{page_parent_url}#{script_src}")
496
+ end
497
+ end
498
+ end
499
+
500
+ def ends_with?(str, suffix)
501
+ suffix = suffix.to_s
502
+ str[-suffix.length, suffix.length] == suffix
503
+ end
504
+
505
+ # current web page title
506
+ def page_title
507
+ @web_browser.page_title
508
+ end
509
+
510
+ # current page source (in HTML)
511
+ def page_source
512
+ @web_browser.page_source
513
+ end
514
+
515
+ # return plain text view of page
516
+ def page_text
517
+ @web_browser.text
518
+ end
519
+
520
+ # return the text of specific (identified by attribute "id") label tag
521
+ # For page containing
522
+ # <label id="preferred_ide">TestWise</label>
523
+ # label_with_id("preferred_ids") # => TestWise
524
+ # label_with_id("preferred_ids", :index => 2) # => TestWise
525
+ def label_with_id(label_id, options = {})
526
+ if options && options[:index] then
527
+ elements = find_elements(:id, label_id.to_s)
528
+ elements[options[:index].to_i - 1].text
529
+ # label(:id => label_id.to_s, :index => options[:index]).text
530
+ else
531
+ find_element(:id, label_id.to_s).text
532
+ end
533
+ end
534
+
535
+ # return the text of specific (identified by attribute "id") span tag
536
+ # For page containing
537
+ # <span id="preferred_recorder">iTest2/Watir Recorder</span>
538
+ # span_with_id("preferred_recorder") # => iTest2/Watir Recorder
539
+ def span_with_id(span_id, options = {})
540
+ if options && options[:index] then
541
+ elements = find_elements(:id, span_id.to_s)
542
+ elements[options[:index].to_i - 1].text
543
+ else
544
+ find_element(:id, span_id.to_s).text
545
+ end
546
+ end
547
+
548
+ # return the text of specific (identified by attribute "id") ta tag
549
+ # For page containing
550
+ # <td id="preferred_recorder">iTest2/Watir Recorder</span>
551
+ # td_with_id("preferred_recorder") # => iTest2/Watir Recorder
552
+ def cell_with_id(cell_id, options = {})
553
+ if options && options[:index] then
554
+ elements = find_elements(:id, cell_id.to_s)
555
+ elements[options[:index].to_i - 1].text
556
+ else
557
+ find_element(:id, cell_id.to_s).text
558
+ end
559
+ end
560
+ alias table_data_with_id cell_with_id
561
+
562
+
563
+ def is_mac?
564
+ RUBY_PLATFORM.downcase.include?("darwin")
565
+ end
566
+
567
+ def is_windows?
568
+ RUBY_PLATFORM.downcase.include?("mswin") or RUBY_PLATFORM.downcase.include?("mingw")
569
+ end
570
+
571
+ def is_linux?
572
+ RUBY_PLATFORM.downcase.include?("linux")
573
+ end
574
+
575
+ # Support browser (IE) operations using unicode
576
+ # Example:
577
+ # click_button("Google 搜索")
578
+ # Reference: http://jira.openqa.org/browse/WTR-219
579
+ def support_utf8
580
+ if is_windows?
581
+ require 'win32ole'
582
+ WIN32OLE.codepage = WIN32OLE::CP_UTF8
583
+ end
584
+ end
585
+
586
+ alias support_unicode support_utf8
587
+
588
+ #= Convenient functions
589
+ #
590
+
591
+
592
+ # Execute the provided block until either (1) it returns true, or
593
+ # (2) the timeout (in seconds) has been reached. If the timeout is reached,
594
+ # a TimeOutException will be raised. The block will always
595
+ # execute at least once.
596
+ #
597
+ # This does not handle error, if the given block raise error, the statement finish with error
598
+ # Examples:
599
+ # wait_until {puts 'hello'}
600
+ # wait_until { div(:id, :receipt_date).exists? }
601
+ #
602
+ def wait_until(timeout = $testwise_polling_timeout || 30, polling_interval = $testwise_polling_interval || 1, & block)
603
+ end_time = ::Time.now + timeout
604
+
605
+ until ::Time.now > end_time
606
+ result = nil
607
+ begin
608
+ result = yield(self)
609
+ return result if result
610
+ rescue => e
611
+ end
612
+ sleep polling_interval
613
+ end
614
+
615
+ raise TimeoutError, "timed out after #{timeout} seconds"
616
+ end
617
+
618
+ # Wait for specific seconds for an Ajax update finish.
619
+ # Trick: In your Rails application,
620
+ # :loading => "Element.show('search_indicator');
621
+ # :complete => "Element.hide('search_indicator');
622
+ #
623
+ # <%= image_tag("indicator.gif", :id => 'search_indicator', :style => 'display:none') %>
624
+ #
625
+ # Typical usage:
626
+ # ajax_wait_for_element("search_indicator", 30)
627
+ # ajax_wait_for_element("search_indicator", 30, "show")
628
+ # ajax_wait_for_element("search_indicator", 30, "hide")
629
+ # ajax_wait_for_element("search_indicator", 30, "show", 5) # check every 5 seconds
630
+ #
631
+ # Warning: this method has not been fully tested, if you are not using Rails, change your parameter accordingly.
632
+ #
633
+ def ajax_wait_for_element(element_id, seconds, status='show', check_interval = $testwise_polling_interval)
634
+ count = 0
635
+ check_interval = 1 if check_interval < 1 or check_interval > seconds
636
+ while count < (seconds / check_interval) do
637
+ search_indicator = @web_browser.element_by_id(element_id)
638
+ search_indicator_outer_html = search_indicator.outerHtml if search_indicator
639
+ if status == 'hide'
640
+ return true if search_indicator_outer_html and !search_indicator_outer_html.include?('style="DISPLAY: none"')
641
+ else
642
+ return true if search_indicator_outer_html and search_indicator_outer_html.include?('style="DISPLAY: none"')
643
+ end
644
+ sleep check_interval if check_interval > 0 and check_interval < 5 * 60 # wait max 5 minutes
645
+ count += 1
646
+ end
647
+ return false
648
+ end
649
+
650
+ #Wait the element with given id to be present in web page
651
+ #
652
+ # Warning: this not working in Firefox, try use wait_util or try instead
653
+ def wait_for_element(element_id, timeout = $testwise_polling_timeout, interval = $testwise_polling_interval)
654
+ start_time = Time.now
655
+ #TODO might not work with Firefox
656
+ until @web_browser.element_by_id(element_id) do
657
+ sleep(interval)
658
+ if (Time.now - start_time) > timeout
659
+ raise RuntimeError, "failed to find element: #{element_id} for max #{timeout}"
660
+ end
661
+ end
662
+ end
663
+
664
+ # Clear popup windows such as 'Security Alert' or 'Security Information' popup window,
665
+ #
666
+ # Screenshot see http://kb2.adobe.com/cps/165/tn_16588.html
667
+ #
668
+ # You can also by pass security alerts by change IE setting, http://kb.iu.edu/data/amuj.html
669
+ #
670
+ # Example
671
+ # clear_popup("Security Information", 5, true) # check for Security Information for 5 seconds, click Yes
672
+ def clear_popup(popup_win_title, seconds = 10, yes = true)
673
+ # commonly "Security Alert", "Security Information"
674
+ if is_windows?
675
+ sleep 1
676
+ autoit = WIN32OLE.new('AutoItX3.Control')
677
+ # Look for window with given title. Give up after 1 second.
678
+ ret = autoit.WinWait(popup_win_title, '', seconds)
679
+ #
680
+ # If window found, send appropriate keystroke (e.g. {enter}, {Y}, {N}).
681
+ if ret == 1 then
682
+ puts "about to send click Yes" if debugging?
683
+ button_id = yes ? "Button1" : "Button2" # Yes or No
684
+ autoit.ControlClick(popup_win_title, '', button_id)
685
+ end
686
+ sleep(0.5)
687
+ else
688
+ raise "Currently supported only on Windows"
689
+ end
690
+ end
691
+
692
+ def select_file_for_upload(file_field_name, file_path)
693
+ @web_browser.select_file_for_upload(file_field_name, file_path)
694
+ end
695
+
696
+ def check_ie_version
697
+ if is_windows? && @ie_version.nil?
698
+ begin
699
+ cmd = 'reg query "HKLM\SOFTWARE\Microsoft\Internet Explorer" /v Version';
700
+ result = `#{cmd}`
701
+ version_line = nil
702
+ result.each do |line|
703
+ if (line =~ /Version\s+REG_SZ\s+([\d\.]+)/)
704
+ version_line = $1
705
+ end
706
+ end
707
+
708
+ if version_line =~ /^\s*(\d+)\./
709
+ @ie_version = $1.to_i
710
+ end
711
+ rescue => e
712
+ end
713
+ end
714
+ end
715
+
716
+ # Use AutoIT3 to send password
717
+ # title starts with "Connect to ..."
718
+ def basic_authentication_ie(title, username, password, options = {})
719
+ default_options = {:textctrl_username => "Edit2",
720
+ :textctrl_password => "Edit3",
721
+ :button_ok => 'Button1'
722
+ }
723
+
724
+ options = default_options.merge(options)
725
+
726
+ title ||= ""
727
+ if title =~ /^Connect\sto/
728
+ full_title = title
729
+ else
730
+ full_title = "Connect to #{title}"
731
+ end
732
+ require 'rformspec'
733
+ login_win = RFormSpec::Window.new(full_title)
734
+ login_win.send_control_text(options[:textctrl_username], username)
735
+ login_win.send_control_text(options[:textctrl_password], password)
736
+ login_win.click_button("OK")
737
+ end
738
+
739
+ # Deprecated, using BuildWise Agent instead
740
+ def basic_authentication(username, password, options = {})
741
+ basic_authentication_ie(options[:title], username, password, options)
742
+ end
743
+
744
+ end
745
+ end