rwebspec-webdriver 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/Rakefile +11 -12
  2. data/lib/rwebspec-webdriver/assert.rb +445 -0
  3. data/lib/{rwebspec → rwebspec-webdriver}/clickJSDialog.rb +0 -0
  4. data/lib/{rwebspec → rwebspec-webdriver}/context.rb +13 -11
  5. data/lib/rwebspec-webdriver/database_checker.rb +76 -0
  6. data/lib/rwebspec-webdriver/driver.rb +1011 -0
  7. data/lib/rwebspec-webdriver/element_locator.rb +89 -0
  8. data/lib/rwebspec-webdriver/load_test_helper.rb +174 -0
  9. data/lib/{rwebspec → rwebspec-webdriver}/matchers/contains_text.rb +0 -0
  10. data/lib/rwebspec-webdriver/popup.rb +149 -0
  11. data/lib/rwebspec-webdriver/rspec_helper.rb +101 -0
  12. data/lib/rwebspec-webdriver/test_script.rb +10 -0
  13. data/lib/rwebspec-webdriver/test_utils.rb +219 -0
  14. data/lib/rwebspec-webdriver/testwise_plugin.rb +85 -0
  15. data/lib/rwebspec-webdriver/using_pages.rb +51 -0
  16. data/lib/rwebspec-webdriver/web_browser.rb +744 -0
  17. data/lib/rwebspec-webdriver/web_page.rb +110 -0
  18. data/lib/rwebspec-webdriver/web_testcase.rb +40 -0
  19. data/lib/rwebspec-webdriver.rb +12 -12
  20. metadata +22 -22
  21. data/lib/rwebspec/assert.rb +0 -443
  22. data/lib/rwebspec/database_checker.rb +0 -74
  23. data/lib/rwebspec/driver.rb +0 -1009
  24. data/lib/rwebspec/element_locator.rb +0 -87
  25. data/lib/rwebspec/load_test_helper.rb +0 -172
  26. data/lib/rwebspec/popup.rb +0 -147
  27. data/lib/rwebspec/rspec_helper.rb +0 -99
  28. data/lib/rwebspec/test_script.rb +0 -8
  29. data/lib/rwebspec/test_utils.rb +0 -217
  30. data/lib/rwebspec/testwise_plugin.rb +0 -83
  31. data/lib/rwebspec/using_pages.rb +0 -49
  32. data/lib/rwebspec/web_browser.rb +0 -742
  33. data/lib/rwebspec/web_page.rb +0 -108
  34. data/lib/rwebspec/web_testcase.rb +0 -38
@@ -1,8 +0,0 @@
1
- module RWebSpec
2
- module TestScript
3
- include RWebSpec::Driver
4
- include RWebSpec::Utils
5
- include RWebSpec::Assert
6
-
7
- end
8
- end
@@ -1,217 +0,0 @@
1
- #***********************************************************
2
- #* Copyright (c) 2006, Zhimin Zhan.
3
- #* Distributed open-source, see full license in MIT-LICENSE
4
- #***********************************************************
5
-
6
- class Array
7
-
8
- def average
9
- inject(0.0) { |sum, e| sum + e } / length
10
- end
11
-
12
- # NOTE might cause issues
13
- # why it is removed total
14
- def sum
15
- inject(0.0) { |sum, e| sum + e }
16
- end
17
- end
18
-
19
- # useful hekoer methods for testing
20
- #
21
- module RWebSpec
22
- module Utils
23
-
24
- # default date format returned is 29/12/2007.
25
- # if supplied parameter is not '%m/%d/%Y' -> 12/29/2007
26
- # Otherwise, "2007-12-29", which is most approiate date format
27
- #
28
- # %a - The abbreviated weekday name (``Sun'')
29
- # %A - The full weekday name (``Sunday'')
30
- # %b - The abbreviated month name (``Jan'')
31
- # %B - The full month name (``January'')
32
- # %c - The preferred local date and time representation
33
- # %d - Day of the month (01..31)
34
- # %H - Hour of the day, 24-hour clock (00..23)
35
- # %I - Hour of the day, 12-hour clock (01..12)
36
- # %j - Day of the year (001..366)
37
- # %m - Month of the year (01..12)
38
- # %M - Minute of the hour (00..59)
39
- # %p - Meridian indicator (``AM'' or ``PM'')
40
- # %S - Second of the minute (00..60)
41
- # %U - Week number of the current year,
42
- # starting with the first Sunday as the first
43
- # day of the first week (00..53)
44
- # %W - Week number of the current year,
45
- # starting with the first Monday as the first
46
- # day of the first week (00..53)
47
- # %w - Day of the week (Sunday is 0, 0..6)
48
- # %x - Preferred representation for the date alone, no time
49
- # %X - Preferred representation for the time alone, no date
50
- # %y - Year without a century (00..99)
51
- # %Y - Year with century
52
- # %Z - Time zone name
53
- # %% - Literal ``%'' character
54
-
55
- def today(format = nil)
56
- format_date(Time.now, date_format(format))
57
- end
58
- alias getToday_AU today
59
- alias getToday_US today
60
- alias getToday today
61
-
62
-
63
- def days_before(days, format = nil)
64
- return nil if !(days.instance_of?(Fixnum))
65
- format_date(Time.now - days * 24 * 3600, date_format(format))
66
- end
67
-
68
- def yesterday(format = nil)
69
- days_before(1, date_format(format))
70
- end
71
-
72
- def days_from_now(days, format = nil)
73
- return nil if !(days.instance_of?(Fixnum))
74
- format_date(Time.now + days * 24 * 3600, date_format(format))
75
- end
76
- alias days_after days_from_now
77
-
78
- def tomorrow(format = nil)
79
- days_from_now(1, date_format(format))
80
- end
81
-
82
-
83
- # return a random number >= min, but <= max
84
- def random_number(min, max)
85
- rand(max-min+1)+min
86
- end
87
-
88
- def random_boolean
89
- return random_number(0, 1) == 1
90
- end
91
-
92
- def random_char(lowercase = true)
93
- if lowercase
94
- sprintf("%c", random_number(97, 122))
95
- else
96
- sprintf("%c", random_number(65, 90))
97
- end
98
- end
99
-
100
- def random_digit()
101
- sprintf("%c", random_number(48, 57))
102
- end
103
-
104
- def random_str(length, lowercase = true)
105
- randomStr = ""
106
- length.times {
107
- randomStr += random_char(lowercase)
108
- }
109
- randomStr
110
- end
111
-
112
- # Return a random string in a rangeof pre-defined strings
113
- def random_string_in(arr)
114
- return nil if arr.empty?
115
- index = random_number(0, arr.length-1)
116
- arr[index]
117
- end
118
- alias random_string_in_collection random_string_in
119
-
120
-
121
- WORDS = %w(alias consequatur aut perferendis sit voluptatem accusantium doloremque aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo aspernatur aut odit aut fugit sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt neque dolorem ipsum quia dolor sit amet consectetur adipisci velit sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem ut enim ad minima veniam quis nostrum exercitationem ullam corporis nemo enim ipsam voluptatem quia voluptas sit suscipit laboriosam nisi ut aliquid ex ea commodi consequatur quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae et iusto odio dignissimos ducimus qui blanditiis praesentium laudantium totam rem voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident sed ut perspiciatis unde omnis iste natus error similique sunt in culpa qui officia deserunt mollitia animi id est laborum et dolorum fuga et harum quidem rerum facilis est et expedita distinctio nam libero tempore cum soluta nobis est eligendi optio cumque nihil impedit quo porro quisquam est qui minus id quod maxime placeat facere possimus omnis voluptas assumenda est omnis dolor repellendus temporibus autem quibusdam et aut consequatur vel illum qui dolorem eum fugiat quo voluptas nulla pariatur at vero eos et accusamus officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae itaque earum rerum hic tenetur a sapiente delectus ut aut reiciendis voluptatibus maiores doloribus asperiores repellat)
122
-
123
- # Pick a random value out of a given range.
124
- def value_in_range(range)
125
- case range.first
126
- when Integer then number_in_range(range)
127
- when Time then time_in_range(range)
128
- when Date then date_in_range(range)
129
- else range.to_a.rand
130
- end
131
- end
132
-
133
- # Generate a given number of words. If a range is passed, it will generate
134
- # a random number of words within that range.
135
- def words(total)
136
- (1..interpret_value(total)).map { WORDS[random_number(0, total)] }.join(' ')
137
- end
138
-
139
- # Generate a given number of sentences. If a range is passed, it will generate
140
- # a random number of sentences within that range.
141
- def sentences(total)
142
- (1..interpret_value(total)).map do
143
- words(5..20).capitalize
144
- end.join('. ')
145
- end
146
-
147
- # Generate a given number of paragraphs. If a range is passed, it will generate
148
- # a random number of paragraphs within that range.
149
- def paragraphs(total)
150
- (1..interpret_value(total)).map do
151
- sentences(3..8).capitalize
152
- end.join("\n\n")
153
- end
154
-
155
- # If an array or range is passed, a random value will be selected to match.
156
- # All other values are simply returned.
157
- def interpret_value(value)
158
- case value
159
- when Array then value.rand
160
- when Range then value_in_range(value)
161
- else value
162
- end
163
- end
164
-
165
- private
166
-
167
- def time_in_range(range)
168
- Time.at number_in_range(Range.new(range.first.to_i, range.last.to_i, rangee.exclude_end?))
169
- end
170
-
171
- def date_in_range(range)
172
- Date.jd number_in_range(Range.new(range.first.jd, range.last.jd, range.exclude_end?))
173
- end
174
-
175
- def number_in_range(range)
176
- if range.exclude_end?
177
- rand(range.last - range.first) + range.first
178
- else
179
- rand((range.last+1) - range.first) + range.first
180
- end
181
- end
182
-
183
- def format_date(date, date_format = '%d/%m/%Y')
184
- date.strftime(date_format)
185
- end
186
-
187
- def date_format(format_argument)
188
- if format_argument.nil? then
189
- get_locale_date_format(default_locale)
190
- elsif format_argument.class == Symbol then
191
- get_locale_date_format(format_argument)
192
- elsif format_argument.class == String then
193
- format_argument
194
- else
195
- # invalid input, use default
196
- get_locale_date_format(default_date_format)
197
- end
198
-
199
- end
200
-
201
- def get_locale_date_format(locale)
202
- case locale
203
- when :us
204
- "%m/%d/%Y"
205
- when :au, :uk
206
- "%d/%m/%Y"
207
- else
208
- "%Y-%m-%d"
209
- end
210
- end
211
-
212
- def default_locale
213
- return :au
214
- end
215
-
216
- end
217
- end
@@ -1,83 +0,0 @@
1
- require 'socket'
2
-
3
- module RWebSpec
4
- module TestWisePlugin
5
-
6
- def debug(message)
7
- connect_to_testwise(" DEBUG", message.to_s + "\r\n") if $RUN_IN_TESTWISE && message
8
- end
9
-
10
-
11
- # Support of iTest to ajust the intervals between keystroke/mouse operations
12
- def operation_delay
13
- begin
14
- if $ITEST2_OPERATION_DELAY && $ITEST2_OPERATION_DELAY > 0 &&
15
- $ITEST2_OPERATION_DELAY && $ITEST2_OPERATION_DELAY < 30000 then # max 30 seconds
16
- sleep($ITEST2_OPERATION_DELAY / 1000)
17
- end
18
-
19
- while $ITEST2_PAUSE
20
- debug("Paused, waiting ...")
21
- sleep 1
22
- end
23
- rescue => e
24
- puts "Error on delaying: #{e}"
25
- # ignore
26
- end
27
- end
28
-
29
- def notify_screenshot_location(image_file_path)
30
- connect_to_testwise(" SHOT", image_file_path)
31
- end
32
-
33
- # find out the line (and file) the execution is on, and notify iTest via Socket
34
- def dump_caller_stack
35
- return unless $ITEST2_TRACE_EXECUTION
36
- begin
37
- trace_lines = []
38
- trace_file = nil
39
- found_first_spec_reference = false
40
- caller.each_with_index do |position, idx|
41
- next unless position =~ /\A(.*?):(\d+)/
42
- trace_file = $1
43
- if trace_file =~ /(_spec|_test|_rwebspec)\.rb\s*$/
44
- found_first_spec_reference = true
45
- trace_lines << position
46
- break
47
- end
48
- trace_lines << position
49
- break if trace_file =~ /example\/example_methods\.rb$/ or trace_file =~ /example\/example_group_methods\.rb$/
50
- break if trace_lines.size > 10
51
- # TODO: send multiple trace to be parse with pages.rb
52
- # break if trace_file =~ /example\/example_methods\.rb$/ or trace_file =~ /example\/example_group_methods\.rb$/ or trace_file =~ /driver\.rb$/ or trace_file =~ /timeout\.rb$/ # don't include rspec or ruby trace
53
- end
54
-
55
- # (trace_file.include?("_spec.rb") || trace_file.include?("_rwebspec.rb") || trace_file.include?("_test.rb") || trace_file.include?("_cmd.rb"))
56
- if !trace_lines.empty?
57
- connect_to_testwise(" TRACE", trace_lines.reverse.join("|"))
58
- end
59
-
60
- rescue => e
61
- puts "failed to capture log: #{e}"
62
- end
63
- end
64
-
65
-
66
- def connect_to_testwise (message_type, body)
67
- begin
68
- the_message = message_type + "|" + body
69
- if @last_message == the_message then # ignore the message same as preivous one
70
- return
71
- end
72
- itest_port = $ITEST2_TRACE_PORT || 7025
73
- itest_socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
74
- itest_socket.connect(Socket.pack_sockaddr_in(itest_port, '127.0.0.1'))
75
- itest_socket.puts(the_message)
76
- @last_message = the_message
77
- itest_socket.close
78
- rescue => e
79
- end
80
- end
81
-
82
- end
83
- end
@@ -1,49 +0,0 @@
1
- module RWebSpec
2
- module UsingPages
3
-
4
- # support Ruby 1.9
5
- def self.extended(kclass)
6
- caller_file = caller[1]
7
- if caller_file && caller_file =~ /^(.*):\d+.*$/
8
- file = $1
9
- dir = File.expand_path(File.dirname(file))
10
- kclass.const_set "TestFileDir", dir
11
- end
12
- end
13
-
14
- # Example
15
- # pages :all
16
- # pages :login_page, :payment_page
17
- # pages :login_page, :payment_page, :page_dir => "c:/tmp"
18
- def pages(*args)
19
- return if args.nil? or args.empty?
20
-
21
- test_file_dir = class_eval{ self::TestFileDir }
22
- default_page_dir = File.join(test_file_dir, "pages")
23
- #puts "debug: default_page_dir :#{default_page_dir}}"
24
- page_dir = default_page_dir
25
-
26
- page_files = []
27
- args.each do |x|
28
- if x.class == Hash && x[:page_dir]
29
- page_dir = x[:page_dir]
30
- else
31
- page_files << x
32
- end
33
- end
34
-
35
- if page_files.size == 1 && page_files[0] == :all
36
- Dir[File.expand_path(page_dir)+ "/*_page.rb"].each { |page_file|
37
- load page_file
38
- }
39
- return
40
- end
41
-
42
- page_files.each do |page|
43
- page_file = File.join(page_dir, page.to_s)
44
- load page_file
45
- end
46
- end
47
-
48
- end
49
- end
@@ -1,742 +0,0 @@
1
- #***********************************************************
2
- #* Copyright (c) 2006, Zhimin Zhan.
3
- #* Distributed open-source, see full license in MIT-LICENSE
4
- #***********************************************************
5
-
6
- begin
7
- require "selenium-webdriver"
8
- rescue LoadError => e
9
- raise "You have must at least WebDriver installed"
10
- end
11
-
12
- require 'sanitize'
13
- require File.join(File.dirname(__FILE__), "element_locator.rb")
14
-
15
- module RWebSpec
16
-
17
- class WebBrowser
18
-
19
- include ElementLocator
20
-
21
- attr_accessor :context
22
-
23
- def initialize(base_url = nil, existing_browser = nil, options = {})
24
- default_options = {:speed => "zippy",
25
- :visible => true,
26
- :highlight_colour => 'yellow',
27
- :close_others => true
28
- }
29
- options = default_options.merge options
30
- @context = Context.new base_url if base_url
31
-
32
- case RUBY_PLATFORM
33
- when /java/i
34
- initialize_celerity_browser(base_url, options)
35
- when /mswin|windows|mingw/i
36
- options[:browser] ||= "ie"
37
- case options[:browser].to_s
38
- when "firefox"
39
- initialize_firefox_browser(existing_browser, base_url, options)
40
- when "chrome"
41
- initialize_chrome_browser(existing_browser, base_url, options)
42
- when "ie"
43
- initialize_ie_browser(existing_browser, options)
44
- end
45
-
46
- else
47
- puts "Ruby Linux or Mac platform: firefox"
48
- options[:browser] ||= "firefox"
49
- case options[:browser].to_s
50
- when "firefox"
51
- initialize_firefox_browser(existing_browser, base_url, options)
52
- when "chrome"
53
- initialize_chrome_browser(existing_browser, base_url, options)
54
- end
55
- end
56
- end
57
-
58
- def initialize_firefox_browser(existing_browser, base_url, options)
59
- if existing_browser then
60
- @browser = existing_browser
61
- return
62
- end
63
-
64
- @browser = Selenium::WebDriver.for :firefox
65
- @browser.navigate.to base_url
66
- end
67
-
68
- def initialize_chrome_browser(existing_browser, base_url, options)
69
- if existing_browser then
70
- @browser = existing_browser
71
- return
72
- end
73
-
74
- @browser = Selenium::WebDriver.for :chrome
75
- @browser.navigate.to base_url
76
- end
77
-
78
- def initialize_htmlunit_browser(base_url, options)
79
- # default_celerity_options = {:proxy => nil, :browser => :firefox, :resynchronize => true, :log_level => :off}
80
- # options = default_celerity_options.merge options
81
- # options.each { |k, v| options.delete(k) unless default_celerity_options.keys.include?(k) }
82
- @browser = Selenium::WebDriver.for :htmlunit
83
- @browser.navigate.to base_url
84
- end
85
-
86
- def initialize_ie_browser(existing_browser, options)
87
- if existing_browser then
88
- @browser = existing_browser
89
- if $ITEST2_EMULATE_TYPING && $ITEST2_TYPING_SPEED then
90
- @browser.set_slow_speed if $ITEST2_TYPING_SPEED == 'slow'
91
- @browser.set_fast_speed if $ITEST2_TYPING_SPEED == 'fast'
92
- else
93
- @browser.speed = :zippy
94
- end
95
- return
96
- end
97
-
98
- @browser = Selenium::WebDriver.for :ie
99
- # if $ITEST2_EMULATE_TYPING && $ITEST2_TYPING_SPEED then
100
- # @browser.set_slow_speed if $ITEST2_TYPING_SPEED == 'slow'
101
- # @browser.set_fast_speed if $ITEST2_TYPING_SPEED == 'fast'
102
- # else
103
- # @browser.speed = :zippy
104
- # end
105
- # @browser.activeObjectHighLightColor = options[:highlight_colour]
106
- # @browser.visible = options[:visible] unless $HIDE_IE
107
- # #NOTE: close_others fails
108
- # if RUBY_VERSION =~ /^1\.8/ && options[:close_others] then
109
- # @browser.close_others
110
- # else
111
- # puts "close other browser instances not working yet in Ruby 1.9.1 version of Watir"
112
- # end
113
- end
114
-
115
- # TODO resuse not working yet
116
- def self.reuse(base_url, options)
117
- if self.is_windows? && $ITEST2_BROWSER != "Firefox"
118
- Watir::IE.each do |browser_window|
119
- return WebBrowser.new(base_url, browser_window, options)
120
- end
121
- #puts "no browser instance found"
122
- WebBrowser.new(base_url, nil, options)
123
- else
124
- WebBrowser.new(base_url, nil, options)
125
- end
126
- end
127
-
128
- # for popup windows
129
- def self.new_from_existing(underlying_browser, web_context = nil)
130
- return WebBrowser.new(web_context ? web_context.base_url : nil, underlying_browser, {:close_others => false})
131
- end
132
-
133
- def find_element(* args)
134
- @browser.send("find_element", *args)
135
- end
136
-
137
- def find_elements(* args)
138
- @browser.send("find_elements", *args)
139
- end
140
-
141
- ##
142
- # Delegate to WebDriver
143
- #
144
- [: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|
145
- tag_name = method
146
- define_method method do |* args|
147
- if args.size == 2 then
148
- find_element(args[0].to_sym, args[1])
149
- end
150
- end
151
- end
152
- alias td cell
153
- alias check_box checkbox # seems watir doc is wrong, checkbox not check_box
154
- alias tr row
155
-
156
- # Wrapp of Watir's area to support Firefox and Watir
157
- #
158
- # Note: FireWatir does not support area directly, treat it as text_field
159
- def area(* args)
160
- if is_firefox?
161
- text_field(* args)
162
- else
163
- @browser.send("area", * args)
164
- end
165
- end
166
-
167
- def modal_dialog(how=nil, what=nil)
168
- @browser.modal_dialog(how, what)
169
- end
170
-
171
- # This is the main method for accessing a generic element with a given attibute
172
- # * how - symbol - how we access the element. Supports all values except :index and :xpath
173
- # * what - string, integer or regular expression - what we are looking for,
174
- #
175
- # Valid values for 'how' are listed in the Watir Wiki - http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
176
- #
177
- # returns an Watir::Element object
178
- #
179
- # Typical Usage
180
- #
181
- # element(:class, /foo/) # access the first element with class 'foo'. We can use a string in place of the regular expression
182
- # element(:id, "11") # access the first element that matches an id
183
- def element(how, what)
184
- return @browser.element(how, what)
185
- end
186
-
187
- # this is the main method for accessing generic html elements by an attribute
188
- #
189
- # Returns a HTMLElements object
190
- #
191
- # Typical usage:
192
- #
193
- # elements(:class, 'test').each { |l| puts l.to_s } # iterate through all elements of a given attribute
194
- # elements(:alt, 'foo')[1].to_s # get the first element of a given attribute
195
- # elements(:id, 'foo').length # show how many elements are foung in the collection
196
- #
197
- def elements(how, what)
198
- return @browser.elements(how, what)
199
- end
200
-
201
- def show_all_objects
202
- @browser.show_all_objects
203
- end
204
-
205
- # Returns the specified ole object for input elements on a web page.
206
- #
207
- # This method is used internally by Watir and should not be used externally. It cannot be marked as private because of the way mixins and inheritance work in watir
208
- #
209
- # * how - symbol - the way we look for the object. Supported values are
210
- # - :name
211
- # - :id
212
- # - :index
213
- # - :value etc
214
- # * what - string that we are looking for, ex. the name, or id tag attribute or index of the object we are looking for.
215
- # * types - what object types we will look at.
216
- # * value - used for objects that have one name, but many values. ex. radio lists and checkboxes
217
- def locate_input_element(how, what, types, value=nil)
218
- @browser.locate_input_element(how, what, types, value)
219
- end
220
-
221
- # This is the main method for accessing map tags - http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/map.asp?frame=true
222
- # * how - symbol - how we access the map,
223
- # * what - string, integer or regular expression - what we are looking for,
224
- #
225
- # Valid values for 'how' are listed in the Watir Wiki - http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
226
- #
227
- # returns a map object
228
- #
229
- # Typical Usage
230
- #
231
- # map(:id, /list/) # access the first map that matches list.
232
- # map(:index,2) # access the second map on the page
233
- # map(:title, "A Picture") # access a map using the tooltip text. See http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/title_1.asp?frame=true
234
- #
235
- def map(how, what=nil)
236
- @browser.map(how, what)
237
- end
238
-
239
- def contains_text(text)
240
- @browser.contains_text(text);
241
- end
242
-
243
- # return HTML of current web page
244
- def page_source
245
- @browser.page_source
246
- end
247
- alias html_body page_source
248
- alias html page_source
249
-
250
- def page_title
251
- @browser.title
252
- end
253
-
254
- #TODO return plain text of current web page
255
- def text
256
- Sanitize.clean(html)
257
- # @browser.text
258
- end
259
-
260
- [:images, :links, :buttons, :select_lists, :checkboxes, :radios, :text_fields, :divs, :dls, :dds, :dts, :ems, :lis, :maps, :spans, :strongs, :ps, :pres, :labels].each do |method|
261
- define_method method do
262
- @browser.send(method)
263
- end
264
- end
265
-
266
- # current url
267
- def current_url
268
- @browser.current_url
269
- end
270
- alias url current_url
271
-
272
- def base_url=(new_base_url)
273
- if @context
274
- @conext.base_url = new_base_url
275
- return
276
- end
277
- @context = Context.new base_url
278
- end
279
-
280
- def underlying_browser
281
- @browser
282
- end
283
-
284
- def is_ie?
285
- puts @browser.browser.to_s
286
- @browser.browser.to_s == "ie"
287
- end
288
-
289
- def is_firefox?
290
- @browser.browser.to_s == "firefox"
291
- end
292
-
293
- # Close the browser window. Useful for automated test suites to reduce
294
- # test interaction.
295
- def close_browser
296
- @browser.quit
297
- sleep 1
298
- end
299
- alias close close_browser
300
-
301
- #TODO determine browser type, check FireWatir support or not
302
- def self.close_all_browsers
303
- if RUBY_PLATFORM.downcase.include?("mswin")
304
- Watir::IE.close_all
305
- else
306
- # raise "not supported in FireFox yet."
307
- end
308
- end
309
-
310
- def full_url(relative_url)
311
- if @context && @context.base_url
312
- @context.base_url + relative_url
313
- else
314
- relative_url
315
- end
316
- end
317
-
318
- # Crahses where http:///ssshtttp:///
319
- def begin_at(relative_url)
320
- if relative_url =~ /\s*^http/
321
- @browser.navigate.to relative_url
322
- else
323
- @browser.navigate.to full_url(relative_url)
324
- end
325
- end
326
-
327
- def browser_opened?
328
- begin
329
- @browser != nil
330
- rescue => e
331
- return false
332
- end
333
- end
334
-
335
- # Some browsers (i.e. IE) need to be waited on before more actions can be
336
- # performed. Most action methods in Watir::Simple already call this before
337
- # and after.
338
- def wait_for_browser
339
- # NOTE: no need any more
340
- end
341
-
342
-
343
- # A convenience method to wait at both ends of an operation for the browser
344
- # to catch up.
345
- def wait_before_and_after
346
- wait_for_browser
347
- yield
348
- wait_for_browser
349
- end
350
-
351
-
352
- [:focus, :close_others].each do |method|
353
- define_method(method) do
354
- @browser.send(method)
355
- end
356
- end
357
-
358
- def forward
359
- @browser.navigate().forward
360
- end
361
- alias go_forward forward
362
-
363
- # TODO can't browse back if on invalid page
364
- def back
365
- @browser.navigate.back
366
- end
367
- alias go_back back
368
-
369
- def refresh
370
- @browser.navigate().refresh
371
- end
372
- alias refresh_page refresh
373
-
374
- # Go to a page
375
- # Usage:
376
- # open_browser("http://www.itest2.com"
377
- # ....
378
- # goto_page("/purchase") # full url => http://www.itest.com/purchase
379
- def goto_page(page)
380
- goto_url full_url(page);
381
- end
382
-
383
- # Go to a URL directly
384
- # goto_url("http://www.itest2.com/downloads")
385
- def goto_url(url)
386
- @browser.navigate.to url
387
- end
388
-
389
- # text fields
390
- def enter_text_into_field_with_name(name, text)
391
- the_element = find_element(:name, name)
392
- if the_element.tag_name == "input" || the_element.tag_name == "textarea" then
393
- the_element.clear
394
- the_element.send_keys(text)
395
- else
396
- elements = find_elements(:name, name)
397
- if elements.size == 1 then
398
- elements[0].send_keys(text)
399
- else
400
- element_set = elements.select {|x| x.tag_name == "textarea" || (x.tag_name == "input" && x.attribute("text")) }
401
- element_set[0].send_keys(text)
402
- end
403
- end
404
- return true
405
- end
406
-
407
- alias set_form_element enter_text_into_field_with_name
408
- alias enter_text enter_text_into_field_with_name
409
- alias set_hidden_field set_form_element
410
-
411
- #links
412
- def click_link_with_id(link_id, opts = {})
413
- if opts && opts[:index]
414
- elements = find_elements(:id, link_id)
415
- elements[opts[:index]-1].click
416
- else
417
- find_element(:id, link_id).click
418
- end
419
- end
420
-
421
- ##
422
- # click_link_with_text("Login")
423
- # click_link_with_text("Show", :index => 2)
424
- def click_link_with_text(link_text, opts = {})
425
- if opts && opts[:index]
426
- elements = find_elements(:link_text, link_text)
427
- elements[opts[:index]-1].click
428
- else
429
- find_element(:link_text, link_text).click
430
- end
431
- end
432
- alias click_link click_link_with_text
433
-
434
-
435
- # Click a button with give HTML id
436
- # Usage:
437
- # click_button_with_id("btn_sumbit")
438
- def click_button_with_id(id, opts = {})
439
- find_element(:id, id).click
440
- end
441
-
442
- # Click a button with give name
443
- # Usage:
444
- # click_button_with_name("confirm")
445
- # click_button_with_name("confirm", :index => 2)
446
- def click_button_with_name(name, opts={})
447
- find_element(:name, name).click
448
- end
449
-
450
- # Click a button with caption
451
- #
452
- # TODO: Caption is same as value
453
- #
454
- # Usage:
455
- # click_button_with_caption("Confirm payment")
456
- def click_button_with_caption(caption, opts={})
457
- all_buttons = button_elements
458
- matching_buttons = all_buttons.select{|x| x.attribute('value') == caption}
459
- if matching_buttons.size > 0
460
-
461
- if opts && opts[:index]
462
- puts "Call matching buttons: #{matching_buttons.inspect}"
463
- first_match = matching_buttons[opts[:index].to_i() - 1]
464
- first_match.click
465
- end
466
-
467
- the_button = matching_buttons[0]
468
- the_button.click
469
-
470
- else
471
- raise "No button with value: #{caption} found"
472
- end
473
- end
474
- alias click_button click_button_with_caption
475
- alias click_button_with_text click_button_with_caption
476
-
477
-
478
- # click_button_with_caption("Confirm payment")
479
- def click_button_with_value(value, opts={})
480
- all_buttons = button_elements
481
- if opts && opts[:index]
482
- all_buttons.select{|x| x.attribute('value') == caption}[index]
483
- else
484
- all_buttons.each do |button|
485
- if button.attribute('value') == value then
486
- button.click
487
- return
488
- end
489
- end
490
- end
491
- end
492
-
493
- # Click image buttion with image source name
494
- #
495
- # For an image submit button <input name="submit" type="image" src="/images/search_button.gif">
496
- # click_button_with_image("search_button.gif")
497
- def click_button_with_image_src_contains(image_filename)
498
- all_buttons = button_elements
499
- found = nil
500
- all_buttons.select do |x|
501
- if x["src"] =~ /#{Regexp.escape(image_filename)}/
502
- found = x
503
- break
504
- end
505
- end
506
-
507
- raise "not image button with src: #{image_filename} found" if found.nil?
508
- found.click
509
- end
510
-
511
- alias click_button_with_image click_button_with_image_src_contains
512
- # Select a dropdown list by name
513
- # Usage:
514
- # select_option("country", "Australia")
515
- def select_option(selectName, text)
516
- select_box = find_element(:name, selectName)
517
-
518
- options = select_box.find_elements(:tag_name, "option")
519
- options.each do |opt|
520
- # puts opt.methods
521
- opt.click if text == opt.text
522
- end
523
- # select_list(:name, selectName).select(option)
524
- end
525
-
526
- # submit first submit button
527
- def submit(buttonName = nil)
528
- if (buttonName.nil?) then
529
- buttons.each { |button|
530
- next if button.type != 'submit'
531
- button.click
532
- return
533
- }
534
- else
535
- click_button_with_name(buttonName)
536
- end
537
- end
538
-
539
- # Check a checkbox
540
- # Usage:
541
- # check_checkbox("agree")
542
- # check_checkbox("agree", "true")
543
- def check_checkbox(checkBoxName, values=nil)
544
- if values
545
- values.class == Array ? arys = values : arys = [values]
546
- elements = find_elements(:name, checkBoxName)
547
- the_checkbox = elements[0] if elements.size == 1
548
- if the_checkbox
549
- the_checkbox.click unless the_checkbox.selected?
550
- return
551
- end
552
-
553
- arys.each { |cbx_value|
554
- elements.each do |elem|
555
- elem.click if elem.attribute('value') == cbx_value && !the_checkbox.selected?
556
- end
557
- }
558
- else
559
- the_checkbox = find_element(:name, checkBoxName)
560
- the_checkbox.click unless the_checkbox.selected?
561
- end
562
- end
563
-
564
- # Check a checkbox
565
- # Usage:
566
- # uncheck_checkbox("agree")
567
- # uncheck_checkbox("agree", "false")
568
- def uncheck_checkbox(checkBoxName, values = nil)
569
- if values
570
- values.class == Array ? arys = values : arys = [values]
571
- elements = find_elements(:name, checkBoxName)
572
- the_checkbox = elements[0] if elements.size == 1
573
- if the_checkbox
574
- the_checkbox.click if the_checkbox.selected?
575
- return
576
- end
577
-
578
- arys.each { |cbx_value|
579
- elements.each do |elem|
580
- elem.click if elem.attribute('value') == cbx_value && the_checkbox && the_checkbox.selected?
581
- end
582
- }
583
- else
584
- the_checkbox = find_element(:name, checkBoxName)
585
- the_checkbox.click if the_checkbox.selected?
586
- end
587
- end
588
-
589
-
590
- # Click a radio button
591
- # Usage:
592
- # click_radio_option("country", "Australia")
593
- def click_radio_option(radio_group, radio_option)
594
- the_radio_button = find_element(:xpath, "//input[@type='radio' and @name='#{radio_group}' and @value='#{radio_option}']")
595
- the_radio_button.click
596
- end
597
- alias click_radio_button click_radio_option
598
-
599
- # Clear a radio button
600
- # Usage:
601
- # click_radio_option("country", "Australia")
602
- def clear_radio_option(radio_group, radio_option)
603
- the_radio_button = find_element(:xpath, "//input[@type='radio' and @name='#{radio_group}' and @value='#{radio_option}']")
604
- the_radio_button.clear
605
- end
606
- alias clear_radio_button clear_radio_option
607
-
608
- def element_by_id(elem_id)
609
- @browser.find_element(:id, elem_id)
610
- end
611
-
612
- def element_value(elementId)
613
- find_element(:id, elementId).attribute('value')
614
- end
615
-
616
- def element_source(elementId)
617
- elem = element_by_id(elementId)
618
- assert_not_nil(elem, "HTML element: #{elementId} not exists")
619
- elem.innerHTML
620
- end
621
-
622
- def select_file_for_upload(file_field, file_path)
623
- is_on_windows = RUBY_PLATFORM.downcase.include?("mingw") || RUBY_PLATFORM.downcase.include?("mswin")
624
- normalized_file_path = is_on_windows ? file_path.gsub("/", "\\") : file_path
625
- file_field(:name, file_field).set(normalized_file_path)
626
- end
627
-
628
- def start_window(url = nil)
629
- @browser.start_window(url);
630
- end
631
-
632
- # Attach to existing browser
633
- #
634
- # Usage:
635
- # WebBrowser.attach_browser(:title, "iTest2")
636
- # WebBrowser.attach_browser(:url, "http://www.itest2.com")
637
- # WebBrowser.attach_browser(:url, "http://www.itest2.com", {:browser => "Firefox", :base_url => "http://www.itest2.com"})
638
- # WebBrowser.attach_browser(:title, /agileway\.com\.au\/attachment/) # regular expression
639
- def self.attach_browser(how, what, options={})
640
- default_options = {:browser => "IE"}
641
- options = default_options.merge(options)
642
- site_context = Context.new(options[:base_url]) if options[:base_url]
643
- if (options[:browser].to_s == "firefox")
644
- ff = FireWatir::Firefox.attach(how, what)
645
- return WebBrowser.new_from_existing(ff, site_context)
646
- else
647
- return WebBrowser.new_from_existing(Watir::IE.attach(how, what), site_context)
648
- end
649
- end
650
-
651
- # Attach a Watir::IE instance to a popup window.
652
- #
653
- # Typical usage
654
- # new_popup_window(:url => "http://www.google.com/a.pdf")
655
- def new_popup_window(options, browser = "ie")
656
- if is_firefox?
657
- raise "not implemented"
658
- else
659
- if options[:url]
660
- Watir::IE.attach(:url, options[:url])
661
- elsif options[:title]
662
- Watir::IE.attach(:title, options[:title])
663
- else
664
- raise 'Please specify title or url of new pop up window'
665
- end
666
- end
667
- end
668
-
669
- # ---
670
- # For deubgging
671
- # ---
672
- def dump_response(stream = nil)
673
- stream.nil? ? puts(page_source) : stream.puts(page_source)
674
- end
675
-
676
- # A Better Popup Handler using the latest Watir version. Posted by Mark_cain@rl.gov
677
- #
678
- # http://wiki.openqa.org/display/WTR/FAQ#FAQ-HowdoIattachtoapopupwindow%3F
679
- #
680
- def start_clicker(button, waitTime= 9, user_input=nil)
681
- # get a handle if one exists
682
- hwnd = @browser.enabled_popup(waitTime)
683
- if (hwnd) # yes there is a popup
684
- w = WinClicker.new
685
- if (user_input)
686
- w.setTextValueForFileNameField(hwnd, "#{user_input}")
687
- end
688
- # I put this in to see the text being input it is not necessary to work
689
- sleep 3
690
- # "OK" or whatever the name on the button is
691
- w.clickWindowsButton_hwnd(hwnd, "#{button}")
692
- #
693
- # this is just cleanup
694
- w = nil
695
- end
696
- end
697
-
698
- # return underlying browser
699
- def ie
700
- @browser.class == "internet_explorer" ? @browser : nil;
701
- end
702
-
703
- # return underlying firefox browser object, raise error if not running using Firefox
704
- def firefox
705
- is_firefox? ? @browser : nil;
706
- end
707
-
708
- def htmlunit
709
- raise "can't call this as it is configured to use Celerity" unless RUBY_PLATFORM =~ /java/
710
- @browser
711
- end
712
-
713
- # Save current web page source to file
714
- # usage:
715
- # save_page("/tmp/01.html")
716
- # save_page() => # will save to "20090830112200.html"
717
- def save_page(file_name = nil)
718
- file_name ||= Time.now.strftime("%Y%m%d%H%M%S") + ".html"
719
- puts "about to save page: #{File.expand_path(file_name)}" if $DEBUG
720
- File.open(file_name, "w").puts page_source
721
- end
722
-
723
-
724
- # Verify the next page following an operation.
725
- #
726
- # Typical usage:
727
- # browser.expect_page HomePage
728
- def expect_page(page_clazz, argument = nil)
729
- if argument
730
- page_clazz.new(self, argument)
731
- else
732
- page_clazz.new(self)
733
- end
734
- end
735
-
736
- # is it running in MS Windows platforms?
737
- def self.is_windows?
738
- RUBY_PLATFORM.downcase.include?("mswin") or RUBY_PLATFORM.downcase.include?("mingw")
739
- end
740
-
741
- end
742
- end