operawatir 0.4.1.pre5-jruby → 0.4.1.pre6-jruby

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 (60) hide show
  1. data/AUTHORS +1 -0
  2. data/CHANGES +170 -3
  3. data/README.md +30 -27
  4. data/VERSION +1 -1
  5. data/bin/desktopwatir +19 -16
  6. data/bin/operawatir +4 -4
  7. data/lib/operadriver/client-combined-nodeps.jar +0 -0
  8. data/lib/operadriver/webdriver-opera.jar +0 -0
  9. data/lib/operawatir/browser.rb +1 -2
  10. data/lib/operawatir/collection.rb +1 -1
  11. data/lib/operawatir/compat/collection.rb +13 -0
  12. data/lib/operawatir/compat/element.rb +57 -15
  13. data/lib/operawatir/compat/window.rb +41 -0
  14. data/lib/operawatir/desktop_browser.rb +26 -9
  15. data/lib/operawatir/desktop_container.rb +82 -29
  16. data/lib/operawatir/element.rb +48 -24
  17. data/lib/operawatir/keys.rb +18 -25
  18. data/lib/operawatir/preferences.rb +223 -6
  19. data/lib/operawatir/quickwidgets/quick_button.rb +8 -2
  20. data/lib/operawatir/quickwidgets/quick_checkbox.rb +4 -4
  21. data/lib/operawatir/quickwidgets/quick_editfield.rb +1 -1
  22. data/lib/operawatir/quickwidgets/quick_find.rb +11 -0
  23. data/lib/operawatir/quickwidgets/quick_griditem.rb +11 -0
  24. data/lib/operawatir/quickwidgets/quick_gridlayout.rb +11 -0
  25. data/lib/operawatir/quickwidgets/quick_searchfield.rb +5 -1
  26. data/lib/operawatir/quickwidgets/quick_tab.rb +0 -1
  27. data/lib/operawatir/quickwidgets/quick_treeitem.rb +22 -1
  28. data/lib/operawatir/quickwidgets/quick_widget.rb +61 -22
  29. data/lib/operawatir/quickwidgets/quick_window.rb +26 -0
  30. data/lib/operawatir/quickwidgets.rb +2 -1
  31. data/lib/operawatir/window.rb +36 -25
  32. data/lib/operawatir.rb +1 -1
  33. data/operawatir.gemspec +38 -5
  34. data/spec/operawatir/core/element_spec.rb +5 -0
  35. data/spec/operawatir/core/window_spec.rb +42 -0
  36. data/spec/operawatir/desktop/desktopbrowser_spec.rb +16 -0
  37. data/spec/operawatir/desktop/quickaddressfield_spec.rb +15 -3
  38. data/spec/operawatir/desktop/quickbutton_spec.rb +234 -20
  39. data/spec/operawatir/desktop/quickcheckbox_spec.rb +36 -0
  40. data/spec/operawatir/desktop/quickdialogtab_spec.rb +30 -0
  41. data/spec/operawatir/desktop/quickdropdown_spec.rb +39 -0
  42. data/spec/operawatir/desktop/quickeditfield_spec.rb +51 -0
  43. data/spec/operawatir/desktop/quickfind_spec.rb +30 -0
  44. data/spec/operawatir/desktop/quickgriditem_spec.rb +16 -0
  45. data/spec/operawatir/desktop/quickgridlayout_spec.rb +15 -0
  46. data/spec/operawatir/desktop/quicklabel_spec.rb +28 -0
  47. data/spec/operawatir/desktop/quickradiobutton_spec.rb +24 -0
  48. data/spec/operawatir/desktop/quicksearchfield_spec.rb +26 -0
  49. data/spec/operawatir/desktop/quicktab_spec.rb +86 -0
  50. data/spec/operawatir/desktop/quickthumbnail_spec.rb +37 -0
  51. data/spec/operawatir/desktop/quicktreeitem_spec.rb +135 -0
  52. data/spec/operawatir/desktop/quicktreeview_spec.rb +30 -0
  53. data/spec/operawatir/desktop/quickwidget_spec.rb +52 -11
  54. data/spec/operawatir/desktop/quickwindow_spec.rb +11 -0
  55. data/spec/operawatir/desktop/shared/shared.rb +100 -10
  56. data/spec/operawatir/fixtures/browsers.svg +367 -0
  57. data/spec/operawatir/fixtures/frames.html +13 -0
  58. data/spec/watir2/select_list_spec.rb +84 -71
  59. metadata +37 -4
  60. data/lib/operadriver/selenium-common.jar +0 -0
@@ -35,9 +35,9 @@ class OperaWatir::Element
35
35
  !attr(name).nil?
36
36
  end
37
37
 
38
- def method_missing(name, *args, &blk)
39
- if !(block_given? || !args.empty?) && has_attribute?(name)
40
- attr(name)
38
+ def method_missing(method, *args, &blk)
39
+ if !(block_given? || !args.empty?) && has_attribute?(method)
40
+ attr(method)
41
41
  else
42
42
  super
43
43
  end
@@ -59,6 +59,8 @@ class OperaWatir::Element
59
59
  def_delegator :node, :isEnabled, :enabled?
60
60
  def_delegator :node, :isSelected, :checked?
61
61
 
62
+ def_delegator :node, :setSelected, :select
63
+
62
64
  def_delegator :node, :isSelected, :selected?
63
65
 
64
66
  def_delegator :node, :toggle, :toggle_check!
@@ -66,8 +68,6 @@ class OperaWatir::Element
66
68
  def_delegator :node, :getText, :text
67
69
  def_delegator :node, :getHTML, :html
68
70
 
69
- alias_method :to_s, :text
70
-
71
71
  def_delegator :node, :getElementName, :tag_name
72
72
  def_delegator :node, :clear, :clear
73
73
 
@@ -77,32 +77,54 @@ class OperaWatir::Element
77
77
  #
78
78
  # @return [String] Value of the element.
79
79
  def value
80
+ =begin
80
81
  if tag_name =~ /input|textarea|select/i
81
- node.getValue
82
+ node.getValue #
83
+ elsif tag_name =~ /button/i
84
+ text # getVisibleContents
82
85
  else
83
- attr :value
86
+ attr :value # attribute @value
84
87
  end
88
+ =end
89
+
90
+ node.getValue
91
+ end
92
+
93
+ #
94
+ # Does the element exist in the DOM?
95
+ #
96
+ # @return [Boolean] True if element exists, false otherwise.
97
+ #
98
+
99
+ def exist?
100
+ !!!tag_name.empty?
85
101
  end
86
102
 
103
+ alias_method :exists?, :exist? # LOL Ruby
104
+
87
105
  def disabled?
88
106
  !enabled?
89
107
  end
90
108
 
91
109
  def check!
92
- if not selected?
93
- node.toggle
94
- end
110
+ node.toggle if not selected?
95
111
  end
96
112
 
97
113
  def uncheck!
98
- if selected?
99
- node.toggle
100
- end
114
+ node.toggle if selected?
101
115
  end
102
116
 
103
117
 
104
118
  # Events
105
119
 
120
+ #
121
+ # Clicks on the top left of the element, or the given x,y offset
122
+ # relative to the element.
123
+ #
124
+ # @param [Integer] x The offset from the top left of the element.
125
+ # @param [Integer] y The offset from the top of the element.
126
+ #
127
+
106
128
  def click(x=0, y=0)
107
129
  node.click(x.to_i, y.to_i)
108
130
  end
@@ -138,9 +160,13 @@ class OperaWatir::Element
138
160
  def_delegator :node, :submit, :submit!
139
161
 
140
162
  def text=(input)
141
- # Focus before typing
142
- clear unless value.empty?
143
- node.sendKeys(input.to_s.split('').to_java(:string))
163
+ if attr(:type) =~ /checkbox/i
164
+ toggle_check! unless checked?
165
+ else
166
+ # Focus before typing
167
+ clear unless value.empty?
168
+ node.sendKeys(input.to_s.split('').to_java(:string))
169
+ end
144
170
  end
145
171
 
146
172
  alias_method :set, :text=
@@ -150,6 +176,8 @@ class OperaWatir::Element
150
176
  raise Exceptions::NotImplementedException
151
177
  end
152
178
 
179
+ # FIXME: This should be migrated to using browserbot.js, as watir-webdriver
180
+ # is using.
153
181
  def fire_event(event, x = 0, y = 0)
154
182
  loc = location
155
183
  x += loc[:x]
@@ -162,19 +190,15 @@ class OperaWatir::Element
162
190
  event = $1 if $1
163
191
  event = event.downcase.to_sym
164
192
 
165
- # TODO Should this be moved to OperaDriver instead?
166
193
  case event
167
- when :abort, :blur, :change, :error, :focus, :load, :reset,
168
- :resize, :scroll, :submit, :unload
194
+ when :abort, :blur, :change, :error, :focus, :load, :reset, :resize, :scroll, :submit, :unload
169
195
  type = 'HTMLEvents';
170
196
  init = "initEvent(\"#{event.to_s}\", true, true)"
171
- when :click, :dblclick, :mousedown, :mousemove, :mouseout,
172
- :mouseover, :mouseup
197
+ when :click, :dblclick, :mousedown, :mousemove, :mouseout, :mouseover, :mouseup
173
198
  type = 'MouseEvents'
174
199
  init = "initMouseEvent(\"#{event.to_s}\", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null)"
175
200
  else
176
- raise Exceptions::NotImplementedException,
177
- "Event on#{event} is not a valid ECMAscript event for OperaWatir."
201
+ raise Exceptions::NotImplementedException, "Event on#{event} is not a valid ECMAscript event for OperaWatir."
178
202
  end
179
203
 
180
204
  script = "var event = document.createEvent(\"#{type}\"); " +
@@ -185,7 +209,7 @@ class OperaWatir::Element
185
209
  end
186
210
 
187
211
  def visible?
188
- node.isVisible()
212
+ node.isVisible
189
213
  end
190
214
 
191
215
  # UI
@@ -7,42 +7,27 @@ class OperaWatir::Keys
7
7
  self.browser = browser
8
8
  end
9
9
 
10
- # Holds down supplied arbitrary list of keys indefinitely.
11
10
  #
12
- # @param [Symbol, String] *args Arbitrary list of symbols
13
- # (modification keys) or strings (regular keys) to be pressed
14
- # down.
11
+ # Holds down supplied arbitrary list of keys indefinitely.
15
12
  #
13
+ # @param [Symbol, String] *args Arbitrary list of symbols (modification)
14
+ # keys or strings (regular keys) to be
15
+ # pressed down.
16
+ #
16
17
  # @example
18
+ #
17
19
  # browser.keys.down 'a'
18
20
  # browser.keys.down 'a', :right
19
- #
21
+ #
20
22
  # @seealso up
21
23
  # @seealso send
24
+ #
22
25
 
23
-
24
-
25
- =begin
26
-
27
- Holds down supplied arbitrary list of keys indefinitely.
28
-
29
- @param [Symbol, String] *args Arbitrary list of symbols (modification)
30
- keys or strings (regular keys) to be
31
- pressed down.
32
-
33
- @example
34
-
35
- browser.keys.down 'a'
36
- browser.keys.down 'a', :right
37
-
38
- @seealso up
39
- @seealso send
40
-
41
- =end
42
26
  def down(*args)
43
27
  args.each { |key| driver.keyDown(key) }
44
28
  end
45
29
 
30
+ #
46
31
  # Depresses supplied arbitrary list of keys.
47
32
  #
48
33
  # @param [Symbol, String] *args Arbitrary list of symbols
@@ -52,19 +37,25 @@ class OperaWatir::Keys
52
37
  # browser.keys.up 'a', :right
53
38
  #
54
39
  # @seealso release
40
+ #
41
+
55
42
  def up(*args)
56
43
  args.each { |key| driver.keyUp(key) }
57
44
  end
58
45
 
46
+ #
59
47
  # Releases all pressed down keys.
60
48
  #
61
49
  # @example
62
50
  # browser.keys.down :control, :shift, 'a'
63
51
  # browser.keys.release
52
+ #
53
+
64
54
  def release
65
55
  driver.releaseKeys
66
56
  end
67
57
 
58
+ #
68
59
  # Presses an arbitrary list of keys or key combinations. Provided
69
60
  # arguments are performed in sequence.
70
61
  #
@@ -90,6 +81,8 @@ class OperaWatir::Keys
90
81
  # browser.keys.send :control
91
82
  # browser.keys.send [:control, 'a']
92
83
  # browser.keys.send [:control, 'a'], :backspace
84
+ #
85
+
93
86
  def send(*list) # TODO rename?
94
87
  list.each do |item|
95
88
  case item
@@ -102,9 +95,9 @@ class OperaWatir::Keys
102
95
  down key
103
96
  else
104
97
  key key
105
- release
106
98
  end
107
99
  end
100
+ release
108
101
  when Symbol
109
102
  key item
110
103
  else
@@ -1,13 +1,104 @@
1
1
  class String
2
+
3
+ #
4
+ # Translates an Opera preferences key string into a Ruby method name.
5
+ # It will remove tabs and spaces at beginning of string, replace
6
+ # further spaces with an underscore and make the string lower-case.
7
+ #
8
+ # The method extends the String object and can be called as a regular
9
+ # method on any string in Ruby.
10
+ #
11
+
2
12
  def methodize
3
13
  self.gsub(/^\\t(\s+)/, '').gsub(/\s+/, '_').downcase
4
14
  end
5
15
 
16
+ #
17
+ # Translates a previously keyized Opera preferences method string into
18
+ # an Opera preferences key string. This is done by replacing
19
+ # underscores with spaces and capitalizing each word in the string.
20
+ #
21
+ # The method extends the String object and can be called as a regular
22
+ # method on any string in Ruby.
23
+ #
24
+
6
25
  def keyize
7
26
  self.gsub(/_/, ' ').gsub(/\b('?[a-z])/) { $1.capitalize }
8
27
  end
9
28
  end
10
29
 
30
+ #
31
+ # OperaWatir::Preferences enables you to access the browser preferences
32
+ # in the Opera web browser.
33
+ #
34
+ # @example
35
+ #
36
+ # The Preferences object is created automatically when creating a new
37
+ # Browser object and is exposed as an interface on that object:
38
+ #
39
+ # browser.preferences
40
+ # => <OperaWatir::Preferences>
41
+ #
42
+ # You can interact with this object as you would with any Ruby object.
43
+ # Sections and entries are exposed as Rubyized method names, which
44
+ # means that you can access them like this:
45
+ #
46
+ # browser.preferences.interface_colors # a section
47
+ # browser.preferences.interface_colors.background # an entry
48
+ #
49
+ # Over the preference object itself or over a section you can also use
50
+ # built-in Ruby convenience methods such as:
51
+ #
52
+ # browser.preferences.first # first section
53
+ # browser.preferences.interface_colors # first entry in section
54
+ # browser.preferences.size # number of sections
55
+ #
56
+ # This is a full list of available convenience methods:
57
+ #
58
+ # * []
59
+ # * each
60
+ # * length
61
+ # * size
62
+ # * first
63
+ # * last
64
+ # * empty?
65
+ #
66
+ # Essentially, the preference and section objects are collections
67
+ # (kind of like arrays) that allows you to also iterate over them:
68
+ #
69
+ # browser.preferences.each_with_index do |section, index|
70
+ # puts "Section No. #{index} is called `#{section.key}'"
71
+ # end
72
+ #
73
+ # browser.preferences.interface_colors.each { |e| e.value = '#cccccc' }
74
+ #
75
+ # browser.preferences.interface_colors[5].value
76
+ # => '#cccccc'
77
+ #
78
+ # On each section, the follow getters are available in addition to the
79
+ # convenience methods mentioned above:
80
+ #
81
+ # * section? # Returns true/false based on whether it's a section
82
+ # * exists? # Returns true/false based on whether it exists
83
+ #
84
+ # On each entry, the following getters and setters are available in
85
+ # addition to the convenience methods mentioned above:
86
+ #
87
+ # * value # Returns current preference's value
88
+ # * value= # Sets current preference's value to provided string
89
+ # * default # Returns current preference's default
90
+ # * default! # Sets current preference to its default
91
+ #
92
+ # This means you can do crazy stuff like resetting all the preferences
93
+ # in `opera:config` to their standard value like this:
94
+ #
95
+ # browser.preferences.each do |section|
96
+ # section.each do |entry|
97
+ # entry.default!
98
+ # end
99
+ # end
100
+ #
101
+
11
102
  class OperaWatir::Preferences
12
103
  extend Forwardable
13
104
  include Enumerable
@@ -27,10 +118,40 @@ class OperaWatir::Preferences
27
118
  'User Agent', 'User Display Mode', 'User Prefs', 'Visited Link',
28
119
  'Visited Link', 'Web Server', 'Widgets', 'Workspace']
29
120
 
121
+ #
122
+ # The OperaWatir::Preferences object is created automatically when you
123
+ # create an OperaWatir::Browser object, and is available as
124
+ # Browser#prefrences.
125
+ #
126
+ # @example
127
+ #
128
+ # browser.preferences.method_name
129
+ #
130
+ # @param [Object] browser An OperaWatir::Browser object.
131
+ #
132
+
30
133
  def initialize(browser)
31
134
  self.browser, self.driver = browser, browser.driver
32
135
  end
33
136
 
137
+ #
138
+ # When calling Preferences#any_method_name, the `any_method_name` will
139
+ # be caught by this method.
140
+ #
141
+ # This is the standard way of looking up sections. `any_method_name`
142
+ # should be replaced by a methodized version of the section as it
143
+ # appears in the Opera preferences list which you can find at
144
+ # `opera:config`.
145
+ #
146
+ # @example
147
+ #
148
+ # browser.preferences.interface_colors
149
+ # # will return section “Interface Colors”
150
+ #
151
+ # @param section Method to look up in preferences.
152
+ # @return [Object] A Preferences::Entry (section) object.
153
+ #
154
+
34
155
  def method_missing(section)
35
156
  if _prefs.any? { |s| s.method == section.to_s }
36
157
  _prefs.find { |s| s.method == section.to_s }
@@ -48,6 +169,15 @@ class OperaWatir::Preferences
48
169
  :last,
49
170
  :empty?
50
171
 
172
+ #
173
+ # Retrieves a human-readable list of Opera preferences available.
174
+ # This is used for convenience and should never be parsed. Consider
175
+ # using the built-in Ruby iterator #each (with friends) or
176
+ # Preferences#to_a for that.
177
+ #
178
+ # @return [String] List of preferences.
179
+ #
180
+
51
181
  def to_s
52
182
  text = ''
53
183
 
@@ -65,10 +195,26 @@ class OperaWatir::Preferences
65
195
  text
66
196
  end
67
197
 
198
+ #
199
+ # Returns a list of all preferences in array form. This can be used
200
+ # for external parsing. If you wish to manipulate or iterate through
201
+ # the list of preferences consider using the built-in Ruby iterator
202
+ # #each (with friends).
203
+ #
204
+ # @return [Array] List of preferences.
205
+ #
206
+
68
207
  def to_a
69
208
  _prefs.dup
70
209
  end
71
210
 
211
+ #
212
+ # Checks if any preferences exists in your Opera build. If true,
213
+ # there are preferences available, false otherwise.
214
+ #
215
+ # @return [Boolean] Whether any preferences exists.
216
+ #
217
+
72
218
  def exists?
73
219
  !_prefs.empty?
74
220
  end
@@ -88,6 +234,16 @@ private
88
234
 
89
235
  attr_accessor :parent, :method, :key, :value, :type, :default, :driver
90
236
 
237
+ #
238
+ # OperaWatir::Preferences::Entry is the object that represents
239
+ # either a section or a section's entry.
240
+ #
241
+ # It's created automatically when you query for entries using the
242
+ # Preference object itself.
243
+ #
244
+ # @return [Object] An OperaWatir::Preferences::Entry object.
245
+ #
246
+
91
247
  def initialize(parent, method, key=nil, type=nil)
92
248
  self.parent = parent
93
249
  self.method = method.to_s
@@ -96,22 +252,54 @@ private
96
252
  self.driver = parent.driver
97
253
  end
98
254
 
99
- def method_missing(key)
100
- key = key.to_s
255
+ #
256
+ # When calling Preferences::Entry#any_method_name, the
257
+ # `any_method_name` will be caught by this method.
258
+ #
259
+ # This is the standard way of looking up preference entries.
260
+ # `any_method_name` should be replaced by a methodized version of
261
+ # the entry as it appears in the Opera preferences list which you
262
+ # can find at `opera:config`.
263
+ #
264
+ # @example
265
+ #
266
+ # browser.preferences.interface_colors.background
267
+ # # will return the “Background” entry in section “Interface Colors”
268
+ #
269
+ # @param method Method to look up in section.
270
+ # @return [Object] A Preferences::Entry (entry) object.
271
+ #
272
+
273
+ def method_missing(method)
274
+ method = method.to_s
101
275
 
102
- if _keys.any? { |k| k.method == key }
103
- _keys.find { |k| k.method == key }
276
+ if _keys.any? { |k| k.method == method }
277
+ _keys.find { |k| k.method == method }
104
278
  else
105
- _keys << Entry.new(self, key)
279
+ _keys << Entry.new(self, method)
106
280
  _keys.last
107
281
  end
108
282
  end
109
283
 
284
+ #
285
+ # Returns the value of an entry in a section. Note that it's not
286
+ # possible to retrieve the value for sections.
287
+ #
288
+ # @return [String] Value of the entry.
289
+ #
290
+
110
291
  def value
111
292
  raise OperaWatir::Exceptions::PreferencesException, 'Sections do not have values' if section?
112
293
  @value ||= driver.getPref(parent.key, key)
113
294
  end
114
295
 
296
+ #
297
+ # Sets the entry's value to the specified string. Note that it's
298
+ # not possible to set a section's value.
299
+ #
300
+ # @param [String] value Value you wish to set for the entry.
301
+ #
302
+
115
303
  def value=(value)
116
304
  raise OperaWatir::Exceptions::PreferencesException, 'Sections cannot have values' if section?
117
305
  value = value.truthy? ? '1' : '0' if type.include?('Boolean')
@@ -119,19 +307,48 @@ private
119
307
  @value = value
120
308
  end
121
309
 
310
+ #
311
+ # Returns entry's default value. Note that it's not possible to
312
+ # return a section's default value.
313
+ #
314
+ # @return [String] The default value of the entry.
315
+ #
316
+
122
317
  def default
123
318
  raise OperaWatir::Exceptions::PreferencesException, 'Sections do not have defaults' if section?
124
319
  @default ||= driver.getDefaultPref parent.key, key
125
320
  end
126
321
 
322
+ #
323
+ # Returns and sets the default value of the entry. Note that it's
324
+ # not possible to return and set a section's default value.
325
+ #
326
+ # @return [String] The default value of the entry.
327
+ #
328
+
127
329
  def default!
128
330
  self.value=(default) # WTF? Bug in Ruby?
129
331
  end
130
332
 
333
+ #
334
+ # Is the current node a section?
335
+ #
336
+ # @return [Boolean] True/false based on whether you're
337
+ # interacting with a section or entry.
338
+ #
339
+
131
340
  def section?
132
341
  parent.kind_of? OperaWatir::Preferences
133
342
  end
134
343
 
344
+ #
345
+ # Does this entry/section exist?
346
+ #
347
+ # @return [Boolean] True/false based on whether the method you
348
+ # are attempting to access exists as a
349
+ # preference entry/section.
350
+ #
351
+
135
352
  def exists?
136
353
  section? ? SECTIONS.include?(key) : !type.empty?
137
354
  end
@@ -165,7 +382,7 @@ private
165
382
  p = p.to_s
166
383
 
167
384
  p =~ /^key: \"([a-zA-Z0-9\(\)\\\.\-\s]*)\"$/
168
- key = $1
385
+ key = $1.to_s
169
386
 
170
387
  p =~ /^type: ([A-Z]+)$/
171
388
  type = $1.to_s.capitalize