watir-classic 3.3.0 → 3.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.
Files changed (51) hide show
  1. data/CHANGES +17 -0
  2. data/Gemfile.lock +9 -8
  3. data/LICENSE +1 -0
  4. data/README.rdoc +6 -7
  5. data/Rakefile +3 -1
  6. data/VERSION +1 -1
  7. data/lib/watir-classic.rb +0 -5
  8. data/lib/watir-classic/browser.rb +58 -35
  9. data/lib/watir-classic/browsers.rb +1 -1
  10. data/lib/watir-classic/container.rb +39 -33
  11. data/lib/watir-classic/cookies.rb +32 -2
  12. data/lib/watir-classic/core.rb +0 -1
  13. data/lib/watir-classic/dialogs/alert.rb +12 -0
  14. data/lib/watir-classic/dialogs/file_field.rb +11 -0
  15. data/lib/watir-classic/drag_and_drop_helper.rb +14 -0
  16. data/lib/watir-classic/element.rb +292 -257
  17. data/lib/watir-classic/element_collection.rb +26 -8
  18. data/lib/watir-classic/element_extensions.rb +22 -16
  19. data/lib/watir-classic/exceptions.rb +4 -4
  20. data/lib/watir-classic/form.rb +52 -49
  21. data/lib/watir-classic/frame.rb +23 -14
  22. data/lib/watir-classic/ie-class.rb +363 -315
  23. data/lib/watir-classic/ie-process.rb +1 -0
  24. data/lib/watir-classic/ie.rb +0 -17
  25. data/lib/watir-classic/image.rb +58 -64
  26. data/lib/watir-classic/input_elements.rb +224 -219
  27. data/lib/watir-classic/link.rb +14 -15
  28. data/lib/watir-classic/locator.rb +12 -7
  29. data/lib/watir-classic/matches.rb +7 -3
  30. data/lib/watir-classic/modal_dialog.rb +38 -26
  31. data/lib/watir-classic/non_control_elements.rb +29 -0
  32. data/lib/watir-classic/options.rb +10 -15
  33. data/lib/watir-classic/page-container.rb +30 -48
  34. data/lib/watir-classic/process.rb +4 -2
  35. data/lib/watir-classic/screenshot.rb +6 -0
  36. data/lib/watir-classic/supported_elements.rb +36 -14
  37. data/lib/watir-classic/table.rb +81 -71
  38. data/lib/watir-classic/util.rb +9 -11
  39. data/lib/watir-classic/wait.rb +17 -4
  40. data/lib/watir-classic/wait_helper.rb +15 -2
  41. data/lib/watir-classic/win32.rb +2 -1
  42. data/lib/watir-classic/window.rb +35 -7
  43. data/lib/watir-classic/xpath_locator.rb +1 -0
  44. data/lib/watir-classic/yard/global_macros.rb +7 -0
  45. data/spec/frame_spec.rb +17 -0
  46. metadata +5 -7
  47. data/lib/watir-classic/close_all.rb +0 -31
  48. data/lib/watir-classic/contrib/enabled_popup.rb +0 -21
  49. data/lib/watir-classic/contrib/ie-new-process.rb +0 -27
  50. data/lib/watir-classic/contrib/page_checker.rb +0 -29
  51. data/watir.gif +0 -0
@@ -4,36 +4,19 @@ module Watir
4
4
  module PageContainer
5
5
  include Watir::Exception
6
6
 
7
- # This method checks the currently displayed page for http errors, 404, 500 etc
8
- # It gets called internally by the wait method, so a user does not need to call it explicitly
9
-
10
- def check_for_http_error
11
- # check for IE7
12
- n = self.document.invoke('parentWindow').navigator.appVersion
13
- m=/MSIE\s(.*?);/.match( n )
14
- if m and m[1] =='7.0'
15
- if m = /HTTP (\d\d\d.*)/.match( self.title )
16
- raise NavigationException, m[1]
17
- end
18
- else
19
- # assume its IE6
20
- url = self.document.location.href
21
- if /shdoclc.dll/.match(url)
22
- m = /id=IEText.*?>(.*?)</i.match(self.html)
23
- raise NavigationException, m[1] if m
24
- end
25
- end
26
- false
27
- end
28
-
29
- # The HTML Page
30
- def page
31
- document.documentelement
32
- end
33
-
34
- private :page
35
-
36
- # Execute the given JavaScript string
7
+ # Execute the given JavaScript string in the context of the current page.
8
+ #
9
+ # @example
10
+ # browser.execute_script "var a=1; var b=a+1; return b"
11
+ #
12
+ # @example
13
+ # browser.execute_script("return {a: 1, b: 2}")["b"] # => 1
14
+ #
15
+ # @note It is needed to call return inside of the JavaScript if the value
16
+ # is needed at Ruby side.
17
+ #
18
+ # @return [Object] appropriate type of the object, which is returned from the
19
+ # JavaScript via "return" keyword or nil when "return" is omitted.
37
20
  def execute_script(source)
38
21
  result = nil
39
22
  begin
@@ -50,36 +33,24 @@ module Watir
50
33
  MultiJson.load(result)["value"] rescue nil
51
34
  end
52
35
 
53
- # The HTML of the current page
36
+ # @return [String] html of the current page.
54
37
  def html
55
38
  page.outerhtml
56
39
  end
57
40
 
58
- # The url of the page object.
41
+ # @return [String] url of the page.
59
42
  def url
60
43
  page.document.location.href
61
44
  end
62
45
 
63
- # The text of the current page
46
+ # @return [String] text of the page.
64
47
  def text
65
48
  page.innertext.strip
66
49
  end
67
50
 
68
- def set_container container
69
- @container = container
70
- @page_container = self
71
- end
72
-
73
- # Search the current page for specified text or regexp.
74
- # Returns the index if the specified text was found.
75
- # Returns matchdata object if the specified regexp was found.
76
- #
77
- # *Deprecated*
78
- # Instead use
79
- # IE#text.include? target
80
- # or
81
- # IE#text.match target
51
+ # @deprecated Use "browser.text.include?(target)" or "browser.text.match(target) instead."
82
52
  def contains_text(target)
53
+ Kernel.warn "Deprecated(Element#contains_text) - use \"browser.text.include?(target)\" or \"browser.text.match(target)\" instead."
83
54
  if target.kind_of? Regexp
84
55
  self.text.match(target)
85
56
  elsif target.kind_of? String
@@ -89,6 +60,14 @@ module Watir
89
60
  end
90
61
  end
91
62
 
63
+ # @private
64
+ def set_container container
65
+ @container = container
66
+ @page_container = self
67
+ end
68
+
69
+ private
70
+
92
71
  def with_json2_if_needed source
93
72
  %Q[
94
73
  (function() {
@@ -104,7 +83,10 @@ module Watir
104
83
  ]
105
84
  end
106
85
 
107
- private :with_json2_if_needed
86
+ # The HTML Page
87
+ def page
88
+ document.documentelement
89
+ end
108
90
 
109
91
  end # module
110
92
  end
@@ -1,8 +1,9 @@
1
1
  module Watir
2
+ # @private
2
3
  module Process
3
4
 
4
5
  # Returns the number of windows processes running with the specified name.
5
- def self.count name
6
+ def self.count(name)
6
7
  mgmt = WIN32OLE.connect('winmgmts:\\\\.')
7
8
  processes = mgmt.InstancesOf('win32_process')
8
9
  processes.extend Enumerable
@@ -13,8 +14,9 @@ module Watir
13
14
 
14
15
  class IE
15
16
  # Returns the number of IEXPLORE processes currently running.
17
+ # @return [Fixnum] number of ie processes.
16
18
  def self.process_count
17
19
  Watir::Process.count 'iexplore.exe'
18
20
  end
19
21
  end
20
- end
22
+ end
@@ -3,15 +3,20 @@ require "base64"
3
3
  require "win32/screenshot"
4
4
 
5
5
  module Watir
6
+ # Returned by {IE#screenshot}.
6
7
  class Screenshot
7
8
  def initialize(browser_hwnd)
8
9
  @hwnd = browser_hwnd
9
10
  end
10
11
 
12
+ # Save screenshot to the file.
13
+ #
14
+ # @param [String] path path to the image.
11
15
  def save(path)
12
16
  screenshot.write(path)
13
17
  end
14
18
 
19
+ # @return [String] image in png format.
15
20
  def png
16
21
  path = File.expand_path "temporary-image-#{Time.now.to_i}.png", Dir.tmpdir
17
22
  save path
@@ -20,6 +25,7 @@ module Watir
20
25
  File.delete path rescue nil
21
26
  end
22
27
 
28
+ # @return [String] {#png} image formatted as base64.
23
29
  def base64
24
30
  Base64.encode64 png
25
31
  end
@@ -2,7 +2,30 @@ module Watir
2
2
  module Container
3
3
 
4
4
  class << self
5
- def support_element method_name, args={}
5
+
6
+ private
7
+
8
+ # @!macro support_element
9
+ # @!method $1
10
+ # Create an $1 html element instance.
11
+ #
12
+ # Elements can be searched by using different locators.
13
+ #
14
+ # @example Search by partial text:
15
+ # browser.$1(:text => /partial text/)
16
+ #
17
+ # @example Search by id:
18
+ # browser.$1(:id => "htmlid")
19
+ #
20
+ # @example Search by any arbitrary html attribute:
21
+ # browser.$1(:foo => "value-of-foo-attribute)
22
+ #
23
+ # @example Search by multiple attributes, all provided locators should evaluate to true - only then element is considered to be found:
24
+ # browser.$1(:text => "some text", :class => "css class")
25
+ #
26
+ # @example It is also possible to search for multiple elements of the same type like this:
27
+ # browser.divs(:class => "foo") # => instance of Watir::DivCollection
28
+ def support_element(method_name, args={})
6
29
  klass = args[:class] || method_name.to_s.capitalize
7
30
  super_class = args[:super_class] || "Element"
8
31
 
@@ -28,20 +51,8 @@ module Watir
28
51
  ]
29
52
  end
30
53
 
31
- private :support_element
32
- end
33
-
34
- def format_specifiers(tag_name, how, what)
35
- defaults = {:tag_name => [tag_name].flatten.map(&:to_s)}
36
- formatted_specifiers = defaults.merge(what ? {how => what} : how)
37
- if (formatted_specifiers[:css] || formatted_specifiers[:xpath]) && formatted_specifiers.size > 2
38
- raise ArgumentError, ":xpath and :css specifiers should be the only one when used in #{formatted_specifiers.inspect}"
39
- end
40
- formatted_specifiers
41
54
  end
42
55
 
43
- private :format_specifiers
44
-
45
56
  support_element :a, :class => :Link
46
57
  alias_method :link, :a
47
58
  alias_method :links, :as
@@ -103,7 +114,6 @@ module Watir
103
114
  support_element :hgroup
104
115
  support_element :hidden, :super_class => :TextField, :super_collection => :InputElement
105
116
  support_element :hr
106
- # html and htmls?!
107
117
  support_element :i
108
118
  support_element :img, :class => :Image
109
119
  alias_method :image, :img
@@ -168,5 +178,17 @@ module Watir
168
178
  support_element :var
169
179
  support_element :video
170
180
  support_element :wbr
181
+
182
+ private
183
+
184
+ def format_specifiers(tag_name, how, what)
185
+ defaults = {:tag_name => [tag_name].flatten.map(&:to_s)}
186
+ formatted_specifiers = defaults.merge(what ? {how => what} : how)
187
+ if (formatted_specifiers[:css] || formatted_specifiers[:xpath]) && formatted_specifiers.size > 2
188
+ raise ArgumentError, ":xpath and :css specifiers should be the only one when used in #{formatted_specifiers.inspect}"
189
+ end
190
+ formatted_specifiers
191
+ end
192
+
171
193
  end
172
194
  end
@@ -1,13 +1,16 @@
1
1
  module Watir
2
2
 
3
3
  module TableContainer
4
- # Returns a row in the table
5
- # * index - the index of the row
4
+ # @return [TableRow] a row in the {Table}.
5
+ # @param [Fixnum] index row number to retrieve.
6
+ # @macro exists
6
7
  def [](index)
7
8
  assert_exists
8
9
  TableRow.new(self, :ole_object => @o.rows.item(index))
9
10
  end
10
11
 
12
+ # @return [Array<String>] array of table element texts.
13
+ # @macro exists
11
14
  def strings
12
15
  assert_exists
13
16
  rows_memo = []
@@ -23,22 +26,28 @@ module Watir
23
26
  end
24
27
 
25
28
  module TableElementsContainer
29
+
30
+ private
31
+
26
32
  def table_elements(klass, tags, how, what, ole_collection)
27
33
  specifiers = format_specifiers(tags, how, what)
28
34
  klass.new(self, specifiers, ole_collection)
29
35
  end
30
36
 
31
- private :table_elements
32
37
  end
33
38
 
34
39
  module TableCellsContainer
35
40
  include TableElementsContainer
36
41
 
42
+ # @return [TableCellCollection] cells inside of the {Table}.
43
+ # @macro exists
37
44
  def cells(how={}, what=nil)
38
45
  assert_exists
39
46
  table_elements(TableCellCollection, [:th, :td], how, what, @o.cells)
40
47
  end
41
48
 
49
+ # @return [TableCell] cell inside of the {Table}.
50
+ # @macro exists
42
51
  def cell(how={}, what=nil)
43
52
  specifiers = format_specifiers([:th, :td], how, what)
44
53
  index = specifiers.delete(:index) || 0
@@ -49,11 +58,15 @@ module Watir
49
58
  module TableRowsContainer
50
59
  include TableElementsContainer
51
60
 
61
+ # @return [TableRowCollection] rows inside of the {Table}.
62
+ # @macro exists
52
63
  def rows(how={}, what=nil)
53
64
  assert_exists
54
65
  table_elements(TableRowCollection, [:tr], how, what, @o.rows)
55
66
  end
56
67
 
68
+ # @return [TableRow] row inside of the {Table}.
69
+ # @macro exists
57
70
  def row(how={}, what=nil)
58
71
  specifiers = format_specifiers([:tr], how, what)
59
72
  index = specifiers.delete(:index) || 0
@@ -61,11 +74,7 @@ module Watir
61
74
  end
62
75
  end
63
76
 
64
- # This class is used for dealing with tables.
65
- # Normally a user would not need to create this object as it is returned by the Watir::Container#table method
66
- #
67
- # many of the methods available to this object are inherited from the Element class
68
- #
77
+ # Returned by {Container#table}
69
78
  class Table < Element
70
79
  include TableContainer
71
80
  include TableRowsContainer
@@ -73,81 +82,39 @@ module Watir
73
82
 
74
83
  attr_ole :rules
75
84
 
76
- # override the highlight method, as if the tables rows are set to have a background color,
77
- # this will override the table background color, and the normal flash method won't work
78
- def highlight(set_or_clear)
79
- if set_or_clear == :set
80
- begin
81
- @original_border = @o.border.to_i
82
- if @o.border.to_i==1
83
- @o.border = 2
84
- else
85
- @o.border = 1
86
- end
87
- rescue
88
- @original_border = nil
89
- end
90
- else
91
- begin
92
- @o.border= @original_border unless @original_border == nil
93
- @original_border = nil
94
- rescue
95
- # we could be here for a number of reasons...
96
- ensure
97
- @original_border = nil
98
- end
99
- end
100
- super
101
- end
102
-
103
- # this method is used to populate the properties in the to_s method
104
- def table_string_creator
105
- n = []
106
- n << "rows:".ljust(TO_S_SIZE) + self.row_count.to_s
107
- n << "cols:".ljust(TO_S_SIZE) + self.column_count.to_s
108
- return n
109
- end
110
- private :table_string_creator
111
-
112
- # returns the properties of the object in a string
113
- # raises an ObjectNotFound exception if the object cannot be found
114
- def to_s
115
- assert_exists
116
- r = string_creator
117
- r += table_string_creator
118
- return r.join("\n")
119
- end
120
-
121
- # Returns the number of rows inside the table, including rows in nested tables.
85
+ # @return [Fixnum] number of rows inside of the table, including rows from
86
+ # nested tables.
87
+ # @macro exists
122
88
  def row_count
123
89
  assert_exists
124
90
  rows.length
125
91
  end
126
92
 
127
- # This method returns the number of columns in a row of the table.
128
- # Raises an UnknownObjectException if the table doesn't exist.
129
- # * index - the index of the row
93
+ # @return [Fixnum] number of columns inside of the table, including columns from
94
+ # nested tables.
95
+ # @param [Fixnum] index the number of row.
96
+ # @macro exists
130
97
  def column_count(index=0)
131
98
  assert_exists
132
99
  rows[index].cells.length
133
100
  end
134
101
 
135
- # Returns an array containing all the text values in the specified column
136
- # Raises an UnknownCellException if the specified column does not exist in every
137
- # Raises an UnknownObjectException if the table doesn't exist.
138
- # row of the table
139
- # * columnnumber - column index to extract values from
102
+ # @return [Array<String>] array of each row's specified column text.
103
+ # @param [Fixnum] columnnumber the number of column to extract text from.
104
+ # @macro exists
140
105
  def column_values(columnnumber)
141
- return (0..row_count - 1).collect {|i| self[i][columnnumber].text}
106
+ (0..row_count - 1).collect {|i| self[i][columnnumber].text}
142
107
  end
143
108
 
144
- # Returns an array containing all the text values in the specified row
145
- # Raises an UnknownObjectException if the table doesn't exist.
146
- # * rownumber - row index to extract values from
109
+ # @return [Array<String>] array of each column's text on specified row.
110
+ # @param [Fixnum] rownumber the number of row to extract column texts from.
111
+ # @macro exists
147
112
  def row_values(rownumber)
148
- return (0..column_count(rownumber) - 1).collect {|i| self[rownumber][i].text}
113
+ (0..column_count(rownumber) - 1).collect {|i| self[rownumber][i].text}
149
114
  end
150
115
 
116
+ # @return [Array<Hash>] array with hashes of table data.
117
+ # @macro exists
151
118
  def hashes
152
119
  assert_exists
153
120
 
@@ -176,6 +143,41 @@ module Watir
176
143
  end
177
144
  rows_memo
178
145
  end
146
+
147
+ def to_s
148
+ assert_exists
149
+ r = string_creator
150
+ r += table_string_creator
151
+ r.join("\n")
152
+ end
153
+
154
+ private
155
+
156
+ # this method is used to populate the properties in the to_s method
157
+ def table_string_creator
158
+ n = []
159
+ n << "rows:".ljust(TO_S_SIZE) + self.row_count.to_s
160
+ n << "cols:".ljust(TO_S_SIZE) + self.column_count.to_s
161
+ n
162
+ end
163
+
164
+ # override the highlight method, as if the tables rows are set to have a background color,
165
+ # this will override the table background color, and the normal flash method won't work
166
+ def set_highlight
167
+ perform_highlight do
168
+ @original_border = @o.border.to_i
169
+ @o.border = @original_border + 1
170
+ super
171
+ end
172
+ end
173
+
174
+ def clear_highlight
175
+ perform_highlight do
176
+ @o.border = @original_border if @original_border
177
+ super
178
+ end
179
+ end
180
+
179
181
  end
180
182
 
181
183
  class TableSection < Element
@@ -184,24 +186,30 @@ module Watir
184
186
  include TableCellsContainer
185
187
  end
186
188
 
189
+ # Returned by {Container#tr}.
187
190
  class TableRow < Element
188
191
  include TableCellsContainer
189
192
 
190
- # this method iterates through each of the cells in the row. Yields a TableCell object
193
+ # Iterate over each of the cell in the row.
194
+ # @yieldparam [TableCell] cell cell instance.
191
195
  def each
192
196
  locate
193
197
  cells.each {|cell| yield cell}
194
198
  end
195
199
 
196
- # Returns an element from the row as a TableCell object
200
+ # @return [TableCell] cell from the row.
201
+ # @param [Fixnum] index cell index in the row.
202
+ # @macro exists
197
203
  def [](index)
198
204
  assert_exists
199
205
  if cells.length <= index
200
206
  raise UnknownCellException, "Unable to locate a cell at index #{index}"
201
207
  end
202
- return cells[index]
208
+ cells[index]
203
209
  end
204
210
 
211
+ # @return [Fixnum] cells count in the row.
212
+ # @macro exists
205
213
  def column_count
206
214
  assert_exists
207
215
  cells.length
@@ -209,12 +217,14 @@ module Watir
209
217
 
210
218
  end
211
219
 
212
- # this class is a table cell - when called via the Table object
220
+ # Returned by {Container#td} and {Container#th}.
213
221
  class TableCell < Element
214
222
  attr_ole :headers
215
223
 
216
224
  alias_method :to_s, :text
217
225
 
226
+ # @return [Fixnum] colspan attribute value.
227
+ # @macro exists
218
228
  def colspan
219
229
  locate
220
230
  @o.colSpan