rwebspec 3.1.4 → 4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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