operawatir 0.4-jruby → 0.4.1-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 (222) hide show
  1. data/.gitmodules +3 -3
  2. data/AUTHORS +1 -0
  3. data/CHANGES +454 -0
  4. data/README.md +67 -50
  5. data/Rakefile +6 -10
  6. data/VERSION +1 -1
  7. data/bin/desktopwatir +52 -29
  8. data/bin/operawatir +50 -18
  9. data/lib/operadriver/client-combined-nodeps.jar +0 -0
  10. data/lib/operadriver/webdriver-opera.jar +0 -0
  11. data/lib/operawatir.rb +8 -1
  12. data/lib/operawatir/browser.rb +35 -15
  13. data/lib/operawatir/collection.rb +2 -2
  14. data/lib/operawatir/compat.rb +3 -2
  15. data/lib/operawatir/compat/browser.rb +0 -5
  16. data/lib/operawatir/compat/collection.rb +15 -0
  17. data/lib/operawatir/compat/element.rb +72 -21
  18. data/lib/operawatir/compat/element_finders.rb +6 -0
  19. data/lib/operawatir/compat/selector.rb +7 -0
  20. data/lib/operawatir/compat/window.rb +49 -0
  21. data/lib/operawatir/desktop_browser.rb +88 -14
  22. data/lib/operawatir/desktop_common.rb +0 -2
  23. data/lib/operawatir/desktop_container.rb +82 -29
  24. data/lib/operawatir/desktop_helper.rb +2 -0
  25. data/lib/operawatir/element.rb +49 -25
  26. data/lib/operawatir/helper.rb +5 -3
  27. data/lib/operawatir/keys.rb +19 -6
  28. data/lib/operawatir/preferences.rb +315 -78
  29. data/lib/operawatir/quickwidgets.rb +2 -1
  30. data/lib/operawatir/quickwidgets/quick_addressfield.rb +12 -0
  31. data/lib/operawatir/quickwidgets/quick_button.rb +8 -2
  32. data/lib/operawatir/quickwidgets/quick_checkbox.rb +5 -5
  33. data/lib/operawatir/quickwidgets/quick_editfield.rb +8 -5
  34. data/lib/operawatir/quickwidgets/quick_find.rb +11 -0
  35. data/lib/operawatir/quickwidgets/quick_griditem.rb +11 -0
  36. data/lib/operawatir/quickwidgets/quick_gridlayout.rb +11 -0
  37. data/lib/operawatir/quickwidgets/quick_searchfield.rb +7 -1
  38. data/lib/operawatir/quickwidgets/quick_tab.rb +0 -1
  39. data/lib/operawatir/quickwidgets/quick_treeitem.rb +22 -1
  40. data/lib/operawatir/quickwidgets/quick_widget.rb +62 -23
  41. data/lib/operawatir/quickwidgets/quick_window.rb +32 -2
  42. data/lib/operawatir/screenshot.rb +46 -0
  43. data/lib/operawatir/version.rb +6 -4
  44. data/lib/operawatir/window.rb +53 -67
  45. data/operawatir.gemspec +310 -245
  46. data/spec/operawatir/README.md +4 -0
  47. data/spec/operawatir/core/browser_spec.rb +82 -0
  48. data/spec/operawatir/core/element_spec.rb +88 -0
  49. data/spec/operawatir/core/preferences_spec.rb +438 -0
  50. data/spec/operawatir/core/screenshot_spec.rb +76 -0
  51. data/spec/{new_watirspec → operawatir/core}/spatnav_spec.rb +3 -3
  52. data/spec/operawatir/core/window_spec.rb +76 -0
  53. data/spec/operawatir/desktop/desktopbrowser_spec.rb +316 -0
  54. data/spec/operawatir/desktop/quickaddressfield_spec.rb +59 -0
  55. data/spec/operawatir/desktop/quickbutton_spec.rb +248 -0
  56. data/spec/operawatir/desktop/quickcheckbox_spec.rb +36 -0
  57. data/spec/operawatir/desktop/quickdialogtab_spec.rb +30 -0
  58. data/spec/operawatir/desktop/quickdropdown_spec.rb +39 -0
  59. data/spec/operawatir/desktop/quickeditfield_spec.rb +51 -0
  60. data/spec/operawatir/desktop/quickfind_spec.rb +30 -0
  61. data/spec/operawatir/desktop/quickgriditem_spec.rb +16 -0
  62. data/spec/operawatir/desktop/quickgridlayout_spec.rb +15 -0
  63. data/spec/operawatir/desktop/quicklabel_spec.rb +28 -0
  64. data/spec/operawatir/desktop/quickradiobutton_spec.rb +24 -0
  65. data/spec/operawatir/desktop/quicksearchfield_spec.rb +26 -0
  66. data/spec/operawatir/desktop/quicktab_spec.rb +86 -0
  67. data/spec/operawatir/desktop/quickthumbnail_spec.rb +37 -0
  68. data/spec/operawatir/desktop/quicktreeitem_spec.rb +135 -0
  69. data/spec/operawatir/desktop/quicktreeview_spec.rb +30 -0
  70. data/spec/operawatir/desktop/quickwidget_spec.rb +101 -0
  71. data/spec/operawatir/desktop/quickwindow_spec.rb +108 -0
  72. data/spec/operawatir/desktop/shared/shared.rb +138 -0
  73. data/spec/operawatir/fixtures/boxes.html +22 -0
  74. data/spec/operawatir/fixtures/browsers.svg +367 -0
  75. data/spec/operawatir/fixtures/frames.html +13 -0
  76. data/spec/operawatir/fixtures/grid.html +29 -0
  77. data/spec/operawatir/fixtures/input_fields_value.html +6 -0
  78. data/spec/operawatir/fixtures/onclick.html +20 -0
  79. data/spec/operawatir/fixtures/paragraphs.html +15 -0
  80. data/spec/operawatir/fixtures/two_input_fields.html +6 -0
  81. data/spec/{new_watirspec → operawatir}/guards.rb +0 -0
  82. data/spec/operawatir/matchers.rb +68 -0
  83. data/spec/{legacy_watirspec → operawatir}/server.rb +0 -0
  84. data/spec/operawatir/watirspec.rake +43 -0
  85. data/spec/operawatir/watirspec_desktophelper.rb +14 -0
  86. data/spec/operawatir/watirspec_helper.rb +62 -0
  87. data/spec/{legacy_watirspec → watir2}/area_spec.rb +0 -0
  88. data/spec/{legacy_watirspec → watir2}/areas_spec.rb +0 -0
  89. data/spec/{legacy_watirspec → watir2}/browser_spec.rb +2 -0
  90. data/spec/{legacy_watirspec → watir2}/button_spec.rb +0 -0
  91. data/spec/{legacy_watirspec → watir2}/buttons_spec.rb +0 -0
  92. data/spec/{legacy_watirspec → watir2}/checkbox_spec.rb +0 -0
  93. data/spec/{legacy_watirspec → watir2}/checkboxes_spec.rb +0 -0
  94. data/spec/{legacy_watirspec → watir2}/collections_spec.rb +0 -0
  95. data/spec/{legacy_watirspec → watir2}/dd_spec.rb +0 -0
  96. data/spec/{legacy_watirspec → watir2}/dds_spec.rb +0 -0
  97. data/spec/{legacy_watirspec → watir2}/del_spec.rb +0 -0
  98. data/spec/{legacy_watirspec → watir2}/dels_spec.rb +0 -0
  99. data/spec/{legacy_watirspec → watir2}/div_spec.rb +0 -0
  100. data/spec/{legacy_watirspec → watir2}/divs_spec.rb +0 -0
  101. data/spec/{legacy_watirspec → watir2}/dl_spec.rb +0 -0
  102. data/spec/{legacy_watirspec → watir2}/dls_spec.rb +0 -0
  103. data/spec/{legacy_watirspec → watir2}/dt_spec.rb +0 -0
  104. data/spec/{legacy_watirspec → watir2}/dts_spec.rb +0 -0
  105. data/spec/watir2/element_spec.rb +155 -0
  106. data/spec/{legacy_watirspec → watir2}/em_spec.rb +0 -0
  107. data/spec/{legacy_watirspec → watir2}/ems_spec.rb +0 -0
  108. data/spec/{legacy_watirspec → watir2}/filefield_spec.rb +0 -0
  109. data/spec/{legacy_watirspec → watir2}/filefields_spec.rb +0 -0
  110. data/spec/{legacy_watirspec → watir2}/fixtures/2000_spans.html +0 -0
  111. data/spec/{legacy_watirspec → watir2}/fixtures/bug_duplicate_attributes.html +0 -0
  112. data/spec/{legacy_watirspec → watir2}/fixtures/bug_javascript_001.html +0 -0
  113. data/spec/{legacy_watirspec → watir2}/fixtures/buttons_with_duplicate_ids.html +0 -0
  114. data/spec/{legacy_watirspec → watir2}/fixtures/collections.html +0 -0
  115. data/spec/{legacy_watirspec → watir2}/fixtures/definition_lists.html +0 -0
  116. data/spec/{legacy_watirspec → watir2}/fixtures/euc-jp_text.html +0 -0
  117. data/spec/{legacy_watirspec → watir2}/fixtures/forms_with_input_elements.html +0 -0
  118. data/spec/{legacy_watirspec → watir2}/fixtures/frame_1.html +0 -0
  119. data/spec/{legacy_watirspec → watir2}/fixtures/frame_2.html +0 -0
  120. data/spec/{legacy_watirspec → watir2}/fixtures/frames.html +0 -0
  121. data/spec/{legacy_watirspec → watir2}/fixtures/iframes.html +0 -0
  122. data/spec/{legacy_watirspec → watir2}/fixtures/images.html +0 -0
  123. data/spec/{legacy_watirspec → watir2}/fixtures/images/1.gif +0 -0
  124. data/spec/{legacy_watirspec → watir2}/fixtures/images/2.gif +0 -0
  125. data/spec/{legacy_watirspec → watir2}/fixtures/images/3.gif +0 -0
  126. data/spec/{legacy_watirspec → watir2}/fixtures/images/button.jpg +0 -0
  127. data/spec/{legacy_watirspec → watir2}/fixtures/images/circle.jpg +0 -0
  128. data/spec/{legacy_watirspec → watir2}/fixtures/images/map.gif +0 -0
  129. data/spec/{legacy_watirspec → watir2}/fixtures/images/map2.gif +0 -0
  130. data/spec/{legacy_watirspec → watir2}/fixtures/images/minus.gif +0 -0
  131. data/spec/{legacy_watirspec → watir2}/fixtures/images/originaltriangle.jpg +0 -0
  132. data/spec/{legacy_watirspec → watir2}/fixtures/images/plus.gif +0 -0
  133. data/spec/{legacy_watirspec → watir2}/fixtures/images/square.jpg +0 -0
  134. data/spec/{legacy_watirspec → watir2}/fixtures/images/triangle.jpg +0 -0
  135. data/spec/{legacy_watirspec → watir2}/fixtures/iso-2022-jp_text.html +0 -0
  136. data/spec/{legacy_watirspec → watir2}/fixtures/javascript/helpers.js +0 -0
  137. data/spec/{legacy_watirspec → watir2}/fixtures/jquery.html +0 -0
  138. data/spec/{legacy_watirspec → watir2}/fixtures/latin1_text.html +0 -0
  139. data/spec/{legacy_watirspec → watir2}/fixtures/multiple_ids.html +0 -0
  140. data/spec/{legacy_watirspec → watir2}/fixtures/non_control_elements.html +0 -0
  141. data/spec/{legacy_watirspec → watir2}/fixtures/parser_bug_001.html +0 -0
  142. data/spec/{legacy_watirspec → watir2}/fixtures/prevent_form_submit.html +0 -0
  143. data/spec/{legacy_watirspec → watir2}/fixtures/right_click.html +0 -0
  144. data/spec/{legacy_watirspec → watir2}/fixtures/shift_jis_text.html +0 -0
  145. data/spec/{legacy_watirspec → watir2}/fixtures/tables.html +0 -0
  146. data/spec/{legacy_watirspec → watir2}/fixtures/timeout.html +0 -0
  147. data/spec/{legacy_watirspec → watir2}/fixtures/timeout_window_location.html +0 -0
  148. data/spec/{legacy_watirspec → watir2}/fixtures/tiny_mce.html +0 -0
  149. data/spec/{legacy_watirspec → watir2}/fixtures/utf8_text.html +0 -0
  150. data/spec/{legacy_watirspec → watir2}/fixtures/watirspec.css +0 -0
  151. data/spec/{legacy_watirspec → watir2}/form_spec.rb +0 -0
  152. data/spec/{legacy_watirspec → watir2}/forms_spec.rb +0 -0
  153. data/spec/{legacy_watirspec → watir2}/frame_spec.rb +0 -0
  154. data/spec/{legacy_watirspec → watir2}/frames_spec.rb +0 -0
  155. data/spec/{legacy_watirspec → watir2}/guards.rb +0 -0
  156. data/spec/{legacy_watirspec → watir2}/hidden_spec.rb +0 -0
  157. data/spec/{legacy_watirspec → watir2}/hiddens_spec.rb +0 -0
  158. data/spec/{legacy_watirspec → watir2}/hn_spec.rb +0 -0
  159. data/spec/{legacy_watirspec → watir2}/hns_spec.rb +0 -0
  160. data/spec/{legacy_watirspec → watir2}/image_spec.rb +0 -0
  161. data/spec/{legacy_watirspec → watir2}/images_spec.rb +0 -0
  162. data/spec/{legacy_watirspec → watir2}/ins_spec.rb +0 -0
  163. data/spec/{legacy_watirspec → watir2}/inses_spec.rb +0 -0
  164. data/spec/{legacy_watirspec → watir2}/label_spec.rb +0 -0
  165. data/spec/{legacy_watirspec → watir2}/labels_spec.rb +0 -0
  166. data/spec/{legacy_watirspec → watir2}/li_spec.rb +0 -0
  167. data/spec/{legacy_watirspec → watir2}/link_spec.rb +0 -0
  168. data/spec/{legacy_watirspec → watir2}/links_spec.rb +0 -0
  169. data/spec/{legacy_watirspec → watir2}/lis_spec.rb +0 -0
  170. data/spec/{legacy_watirspec → watir2}/map_spec.rb +0 -0
  171. data/spec/{legacy_watirspec → watir2}/maps_spec.rb +0 -0
  172. data/spec/{legacy_watirspec → watir2}/meta_spec.rb +0 -0
  173. data/spec/{legacy_watirspec → watir2}/metas_spec.rb +0 -0
  174. data/spec/{legacy_watirspec → watir2}/ol_spec.rb +0 -0
  175. data/spec/{legacy_watirspec → watir2}/ols_spec.rb +0 -0
  176. data/spec/{legacy_watirspec → watir2}/option_spec.rb +0 -0
  177. data/spec/{legacy_watirspec → watir2}/p_spec.rb +0 -0
  178. data/spec/{legacy_watirspec → watir2}/pre_spec.rb +0 -0
  179. data/spec/{legacy_watirspec → watir2}/pres_spec.rb +0 -0
  180. data/spec/{legacy_watirspec → watir2}/ps_spec.rb +0 -0
  181. data/spec/{legacy_watirspec → watir2}/radio_spec.rb +0 -0
  182. data/spec/{legacy_watirspec → watir2}/radios_spec.rb +0 -0
  183. data/spec/{legacy_watirspec → watir2}/select_list_spec.rb +84 -71
  184. data/spec/{legacy_watirspec → watir2}/select_lists_spec.rb +0 -0
  185. data/spec/{new_watirspec → watir2}/server.rb +0 -0
  186. data/spec/{legacy_watirspec → watir2}/span_spec.rb +0 -0
  187. data/spec/{legacy_watirspec → watir2}/spans_spec.rb +0 -0
  188. data/spec/{legacy_watirspec → watir2}/spec_helper.rb +0 -0
  189. data/spec/{legacy_watirspec → watir2}/strong_spec.rb +0 -0
  190. data/spec/{legacy_watirspec → watir2}/strongs_spec.rb +0 -0
  191. data/spec/{legacy_watirspec → watir2}/table_bodies_spec.rb +0 -0
  192. data/spec/{legacy_watirspec → watir2}/table_body_spec.rb +0 -0
  193. data/spec/{legacy_watirspec → watir2}/table_cell_spec.rb +0 -0
  194. data/spec/{legacy_watirspec → watir2}/table_cells_spec.rb +0 -0
  195. data/spec/{legacy_watirspec → watir2}/table_footer_spec.rb +0 -0
  196. data/spec/{legacy_watirspec → watir2}/table_footers_spec.rb +0 -0
  197. data/spec/{legacy_watirspec → watir2}/table_header_spec.rb +0 -0
  198. data/spec/{legacy_watirspec → watir2}/table_headers_spec.rb +0 -0
  199. data/spec/{legacy_watirspec → watir2}/table_row_spec.rb +0 -0
  200. data/spec/{legacy_watirspec → watir2}/table_rows_spec.rb +0 -0
  201. data/spec/{legacy_watirspec → watir2}/table_spec.rb +0 -0
  202. data/spec/{legacy_watirspec → watir2}/tables_spec.rb +0 -0
  203. data/spec/{legacy_watirspec → watir2}/text_field_spec.rb +0 -0
  204. data/spec/{legacy_watirspec → watir2}/text_fields_spec.rb +0 -0
  205. data/spec/{legacy_watirspec → watir2}/ul_spec.rb +0 -0
  206. data/spec/{legacy_watirspec → watir2}/uls_spec.rb +0 -0
  207. data/spec/{legacy_watirspec → watir2}/watir_compatibility_spec.rb +0 -0
  208. data/spec/{legacy_watirspec → watir2}/watirspec_helper.rb +0 -0
  209. data/spec/{new_watirspec → watir3}/browser_spec.rb +11 -21
  210. data/spec/{new_watirspec → watir3}/clipboard_spec.rb +2 -2
  211. data/spec/{new_watirspec → watir3}/collection_spec.rb +0 -0
  212. data/spec/{new_watirspec → watir3}/element_spec.rb +30 -12
  213. data/spec/watir3/guards.rb +39 -0
  214. data/spec/{new_watirspec → watir3}/keys_spec.rb +0 -0
  215. data/spec/watir3/server.rb +91 -0
  216. data/spec/{new_watirspec → watir3}/watirspec_helper.rb +0 -0
  217. data/spec/{new_watirspec → watir3}/window_spec.rb +8 -83
  218. metadata +315 -280
  219. data/lib/operadriver/selenium-common.jar +0 -0
  220. data/spec/legacy_watirspec/element_spec.rb +0 -86
  221. data/spec/new_watirspec/preferences_spec.rb +0 -144
  222. data/spec/new_watirspec/screenshot_spec.rb +0 -34
@@ -8,6 +8,8 @@ require 'operawatir'
8
8
  require 'rspec'
9
9
  require 'rbconfig'
10
10
 
11
+ require File.expand_path('../../../spec/operawatir/matchers', __FILE__)
12
+
11
13
  module OperaWatir::DesktopHelper
12
14
  extend self
13
15
 
@@ -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
@@ -137,10 +159,14 @@ class OperaWatir::Element
137
159
 
138
160
  def_delegator :node, :submit, :submit!
139
161
 
140
- def text=(string)
141
- # Focus before typing
142
- clear unless value.empty?
143
- node.sendKeys(string.split('').to_java(:string))
162
+ def text=(input)
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
@@ -26,12 +26,12 @@ module OperaWatir::Helper
26
26
  settings.each do |key, value|
27
27
  config.send("#{key}=", value) if config.respond_to?("#{key}=")
28
28
  end
29
-
29
+
30
30
  config.include SpecHelpers
31
31
 
32
32
  config.after(:suite) do
33
- browser.quit if browser
34
- exit
33
+ browser.quit if @browser
34
+ abort
35
35
  end
36
36
  end
37
37
  end
@@ -54,3 +54,5 @@ private
54
54
  end
55
55
  end
56
56
  end
57
+
58
+ OperaWatir::Helper.run!
@@ -7,22 +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
+ #
25
+
22
26
  def down(*args)
23
27
  args.each { |key| driver.keyDown(key) }
24
28
  end
25
29
 
30
+ #
26
31
  # Depresses supplied arbitrary list of keys.
27
32
  #
28
33
  # @param [Symbol, String] *args Arbitrary list of symbols
@@ -32,19 +37,25 @@ class OperaWatir::Keys
32
37
  # browser.keys.up 'a', :right
33
38
  #
34
39
  # @seealso release
40
+ #
41
+
35
42
  def up(*args)
36
43
  args.each { |key| driver.keyUp(key) }
37
44
  end
38
45
 
46
+ #
39
47
  # Releases all pressed down keys.
40
48
  #
41
49
  # @example
42
50
  # browser.keys.down :control, :shift, 'a'
43
51
  # browser.keys.release
52
+ #
53
+
44
54
  def release
45
55
  driver.releaseKeys
46
56
  end
47
57
 
58
+ #
48
59
  # Presses an arbitrary list of keys or key combinations. Provided
49
60
  # arguments are performed in sequence.
50
61
  #
@@ -70,6 +81,8 @@ class OperaWatir::Keys
70
81
  # browser.keys.send :control
71
82
  # browser.keys.send [:control, 'a']
72
83
  # browser.keys.send [:control, 'a'], :backspace
84
+ #
85
+
73
86
  def send(*list) # TODO rename?
74
87
  list.each do |item|
75
88
  case item
@@ -82,9 +95,9 @@ class OperaWatir::Keys
82
95
  down key
83
96
  else
84
97
  key key
85
- release
86
98
  end
87
99
  end
100
+ release
88
101
  when Symbol
89
102
  key item
90
103
  else
@@ -1,23 +1,110 @@
1
- require 'inifile'
2
- require 'tmpdir'
3
- require 'pp'
4
- require 'active_support/inflector'
5
-
1
+ # -*- coding: utf-8 -*-
6
2
  class String
7
- def keyize
8
- self.humanize.titleize
9
- end
3
+
4
+ #
5
+ # Translates an Opera preferences key string into a Ruby method name.
6
+ # It will remove tabs and spaces at beginning of string, replace
7
+ # further spaces with an underscore and make the string lower-case.
8
+ #
9
+ # The method extends the String object and can be called as a regular
10
+ # method on any string in Ruby.
11
+ #
10
12
 
11
13
  def methodize
12
- self.titleize.gsub(/\s+/, '').underscore
14
+ self.gsub(/^\\t(\s+)/, '').gsub(/\s+/, '_').downcase
15
+ end
16
+
17
+ #
18
+ # Translates a previously keyized Opera preferences method string into
19
+ # an Opera preferences key string. This is done by replacing
20
+ # underscores with spaces and capitalizing each word in the string.
21
+ #
22
+ # The method extends the String object and can be called as a regular
23
+ # method on any string in Ruby.
24
+ #
25
+
26
+ def keyize
27
+ self.gsub(/_/, ' ').gsub(/\b('?[a-z])/) { $1.capitalize }
13
28
  end
14
29
  end
15
30
 
31
+ #
32
+ # OperaWatir::Preferences enables you to access the browser preferences
33
+ # in the Opera web browser.
34
+ #
35
+ # @example
36
+ #
37
+ # The Preferences object is created automatically when creating a new
38
+ # Browser object and is exposed as an interface on that object:
39
+ #
40
+ # browser.preferences
41
+ # => <OperaWatir::Preferences>
42
+ #
43
+ # You can interact with this object as you would with any Ruby object.
44
+ # Sections and entries are exposed as Rubyized method names, which
45
+ # means that you can access them like this:
46
+ #
47
+ # browser.preferences.interface_colors # a section
48
+ # browser.preferences.interface_colors.background # an entry
49
+ #
50
+ # Over the preference object itself or over a section you can also use
51
+ # built-in Ruby convenience methods such as:
52
+ #
53
+ # browser.preferences.first # first section
54
+ # browser.preferences.interface_colors # first entry in section
55
+ # browser.preferences.size # number of sections
56
+ #
57
+ # This is a full list of available convenience methods:
58
+ #
59
+ # * []
60
+ # * each
61
+ # * length
62
+ # * size
63
+ # * first
64
+ # * last
65
+ # * empty?
66
+ #
67
+ # Essentially, the preference and section objects are collections
68
+ # (kind of like arrays) that allows you to also iterate over them:
69
+ #
70
+ # browser.preferences.each_with_index do |section, index|
71
+ # puts "Section No. #{index} is called `#{section.key}'"
72
+ # end
73
+ #
74
+ # browser.preferences.interface_colors.each { |e| e.value = '#cccccc' }
75
+ #
76
+ # browser.preferences.interface_colors[5].value
77
+ # => '#cccccc'
78
+ #
79
+ # On each section, the follow getters are available in addition to the
80
+ # convenience methods mentioned above:
81
+ #
82
+ # * section? # Returns true/false based on whether it's a section
83
+ # * exists? # Returns true/false based on whether it exists
84
+ #
85
+ # On each entry, the following getters and setters are available in
86
+ # addition to the convenience methods mentioned above:
87
+ #
88
+ # * value # Returns current preference's value
89
+ # * value= # Sets current preference's value to provided string
90
+ # * default # Returns current preference's default
91
+ # * default! # Sets current preference to its default
92
+ #
93
+ # This means you can do crazy stuff like resetting all the preferences
94
+ # in `opera:config` to their standard value like this:
95
+ #
96
+ # browser.preferences.each do |section|
97
+ # section.each do |entry|
98
+ # entry.default!
99
+ # end
100
+ # end
101
+ #
102
+
16
103
  class OperaWatir::Preferences
17
104
  extend Forwardable
18
105
  include Enumerable
19
106
 
20
- attr_accessor :browser
107
+ attr_accessor :browser, :driver
21
108
 
22
109
  # FIXME This should be retrievable from OperaDriver
23
110
  SECTIONS = ['Author Display Mode', 'Auto Update', 'BitTorrent',
@@ -32,61 +119,113 @@ class OperaWatir::Preferences
32
119
  'User Agent', 'User Display Mode', 'User Prefs', 'Visited Link',
33
120
  'Visited Link', 'Web Server', 'Widgets', 'Workspace']
34
121
 
122
+ #
123
+ # The OperaWatir::Preferences object is created automatically when you
124
+ # create an OperaWatir::Browser object, and is available as
125
+ # Browser#prefrences.
126
+ #
127
+ # @example
128
+ #
129
+ # browser.preferences.method_name
130
+ #
131
+ # @param [Object] browser An OperaWatir::Browser object.
132
+ #
133
+
35
134
  def initialize(browser)
36
- self.browser = browser
135
+ self.browser, self.driver = browser, browser.driver
37
136
  end
38
137
 
39
- # Section locator
138
+ #
139
+ # When calling Preferences#any_method_name, the `any_method_name` will
140
+ # be caught by this method.
141
+ #
142
+ # This is the standard way of looking up sections. `any_method_name`
143
+ # should be replaced by a methodized version of the section as it
144
+ # appears in the Opera preferences list which you can find at
145
+ # `opera:config`.
146
+ #
147
+ # @example
148
+ #
149
+ # browser.preferences.interface_colors
150
+ # # will return section “Interface Colors”
151
+ #
152
+ # @param section Method to look up in preferences.
153
+ # @return [Object] A Preferences::Entry (section) object.
154
+ #
155
+
40
156
  def method_missing(section)
41
- # @_prefs[section.to_s] ||= Entry.new self, section
42
- Entry.new self, section
157
+ if _prefs.any? { |s| s.method == section.to_s }
158
+ _prefs.find { |s| s.method == section.to_s }
159
+ else
160
+ _prefs << Entry.new(self, section)
161
+ _prefs.last
162
+ end
43
163
  end
44
164
 
45
- def cleanup; end
46
- def cleanup!; end
165
+ def_delegators :_prefs, :[],
166
+ :each,
167
+ :length,
168
+ :size,
169
+ :first,
170
+ :last,
171
+ :empty?
172
+
173
+ #
174
+ # Retrieves a human-readable list of Opera preferences available.
175
+ # This is used for convenience and should never be parsed. Consider
176
+ # using the built-in Ruby iterator #each (with friends) or
177
+ # Preferences#to_a for that.
178
+ #
179
+ # @return [String] List of preferences.
180
+ #
47
181
 
48
- def_delegators :sections, :each,
49
- :length,
50
- :size,
51
- :first,
52
- :last,
53
- :empty?
182
+ def to_s
183
+ text = ''
54
184
 
55
- alias_method :each_section, :each
185
+ _prefs.each do |s|
186
+ text << "#{s.method}\n"
56
187
 
57
- def to_s
58
- pp _prefs
59
- end
188
+ s.each do |k|
189
+ text << " #{k.method}\n"
190
+ text << " type: #{k.type.inspect}\n"
191
+ text << " value: #{k.value.inspect}\n"
192
+ text << " default: #{k.default.inspect}\n"
193
+ end
194
+ end
60
195
 
61
- def to_h
62
- _prefs.dup
196
+ text
63
197
  end
64
198
 
65
- private
66
- def sections
67
- # @_prefs ||= all_prefs
68
- all_prefs
69
- end
199
+ #
200
+ # Returns a list of all preferences in array form. This can be used
201
+ # for external parsing. If you wish to manipulate or iterate through
202
+ # the list of preferences consider using the built-in Ruby iterator
203
+ # #each (with friends).
204
+ #
205
+ # @return [Array] List of preferences.
206
+ #
70
207
 
71
- def all_prefs
72
- list = []
73
- SECTIONS.each { |s| list << Entry.new(self, s.methodize) }
74
- list
208
+ def to_a
209
+ _prefs.dup
75
210
  end
76
211
 
77
- def load_from_file(file)
78
- inifile = Loader.new file
79
- loaded_prefs = IniFile.new inifile.output.path
212
+ #
213
+ # Checks if any preferences exists in your Opera build. If true,
214
+ # there are preferences available, false otherwise.
215
+ #
216
+ # @return [Boolean] Whether any preferences exists.
217
+ #
80
218
 
81
- loaded_prefs.each_section do |s|
82
- s.each do |k,v|
83
- driver.setPref s,k,v
84
- end
85
- end
219
+ def exists?
220
+ !_prefs.empty?
86
221
  end
222
+
223
+ alias_method :exist?, :exists? # LOL Ruby
87
224
 
88
- def driver
89
- browser.driver
225
+ private
226
+
227
+ def _prefs
228
+ @_prefs ||= SECTIONS.map { |s| Entry.new(self, s.methodize, s) }
90
229
  end
91
230
 
92
231
 
@@ -94,66 +233,164 @@ private
94
233
  extend Forwardable
95
234
  include Enumerable
96
235
 
97
- attr_accessor :parent, :method, :key, :value
98
-
99
- def initialize(parent, method)
100
- self.parent, self.method, self.key = parent, method, method.to_s.keyize
236
+ attr_accessor :parent, :method, :key, :value, :type, :default, :driver
237
+
238
+ #
239
+ # OperaWatir::Preferences::Entry is the object that represents
240
+ # either a section or a section's entry.
241
+ #
242
+ # It's created automatically when you query for entries using the
243
+ # Preference object itself.
244
+ #
245
+ # @return [Object] An OperaWatir::Preferences::Entry object.
246
+ #
247
+
248
+ def initialize(parent, method, key=nil, type=nil)
249
+ self.parent = parent
250
+ self.method = method.to_s
251
+ self.key = key ? key : method.to_s.keyize
252
+ self.type = type
253
+ self.driver = parent.driver
101
254
  end
102
255
 
103
- def method_missing(key)
104
- Entry.new self, key
256
+ #
257
+ # When calling Preferences::Entry#any_method_name, the
258
+ # `any_method_name` will be caught by this method.
259
+ #
260
+ # This is the standard way of looking up preference entries.
261
+ # `any_method_name` should be replaced by a methodized version of
262
+ # the entry as it appears in the Opera preferences list which you
263
+ # can find at `opera:config`.
264
+ #
265
+ # @example
266
+ #
267
+ # browser.preferences.interface_colors.background
268
+ # # will return the “Background” entry in section “Interface Colors”
269
+ #
270
+ # @param method Method to look up in section.
271
+ # @return [Object] A Preferences::Entry (entry) object.
272
+ #
273
+
274
+ def method_missing(method)
275
+ method = method.to_s
276
+
277
+ if _keys.any? { |k| k.method == method }
278
+ _keys.find { |k| k.method == method }
279
+ else
280
+ _keys << Entry.new(self, method)
281
+ _keys.last
282
+ end
105
283
  end
106
284
 
285
+ #
286
+ # Returns the value of an entry in a section. Note that it's not
287
+ # possible to retrieve the value for sections.
288
+ #
289
+ # @return [String] Value of the entry.
290
+ #
291
+
107
292
  def value
108
- return nil if is_section?
109
- @value ||= driver.getPref parent.key, @key
293
+ raise OperaWatir::Exceptions::PreferencesException, 'Sections do not have values' if section?
294
+ @value ||= driver.getPref(parent.key, key)
110
295
  end
111
296
 
297
+ #
298
+ # Sets the entry's value to the specified string. Note that it's
299
+ # not possible to set a section's value.
300
+ #
301
+ # @param [String] value Value you wish to set for the entry.
302
+ #
303
+
112
304
  def value=(value)
113
- raise OperaWatir::Exceptions::PreferencesException, 'Sections cannot have values'
114
- driver.setPref parent.key, @key, value
305
+ raise OperaWatir::Exceptions::PreferencesException, 'Sections cannot have values' if section?
306
+ value = value.truthy? ? '1' : '0' if type.include?('Boolean')
307
+ driver.setPref parent.key, key, value.to_s
308
+ @value = value
115
309
  end
116
310
 
311
+ #
312
+ # Returns entry's default value. Note that it's not possible to
313
+ # return a section's default value.
314
+ #
315
+ # @return [String] The default value of the entry.
316
+ #
317
+
117
318
  def default
118
- return nil if is_section?
119
- @default ||= driver.getDefaultPref parent.key, @key
319
+ raise OperaWatir::Exceptions::PreferencesException, 'Sections do not have defaults' if section?
320
+ @default ||= driver.getDefaultPref parent.key, key
120
321
  end
121
322
 
323
+ #
324
+ # Returns and sets the default value of the entry. Note that it's
325
+ # not possible to return and set a section's default value.
326
+ #
327
+ # @return [String] The default value of the entry.
328
+ #
329
+
122
330
  def default!
123
- raise OperaWatir::Exceptions::PreferencesException, 'Sections do not have defaults'
124
- value=(default)
331
+ self.value=(default) # WTF? Bug in Ruby?
125
332
  end
126
333
 
127
- def each_key
128
- return unless block_given?
129
- raw_keys.each { |k| yield k }
334
+ #
335
+ # Is the current node a section?
336
+ #
337
+ # @return [Boolean] True/false based on whether you're
338
+ # interacting with a section or entry.
339
+ #
340
+
341
+ def section?
342
+ parent.kind_of? OperaWatir::Preferences
130
343
  end
131
344
 
132
- alias_method :each, :each_key
345
+ #
346
+ # Does this entry/section exist?
347
+ #
348
+ # @return [Boolean] True/false based on whether the method you
349
+ # are attempting to access exists as a
350
+ # preference entry/section.
351
+ #
133
352
 
134
- def is_section?
135
- @parent.kind_of? OperaWatir::Preferences
353
+ def exists?
354
+ section? ? SECTIONS.include?(key) : !type.empty?
136
355
  end
137
356
 
138
- private
139
- def driver
140
- @parent.browser.driver || @parent.parent.browser.driver
357
+ alias_method :exist?, :exists? # LOL Ruby
358
+
359
+ def each
360
+ return unless block_given?
361
+ _keys.each { |k| yield k }
141
362
  end
142
363
 
143
- def raw_keys
364
+ def_delegators :_keys, :[],
365
+ :length,
366
+ :size,
367
+ :first,
368
+ :last,
369
+ :empty?
370
+
371
+ private
372
+
373
+ def _keys
374
+ raise OperaWatir::Exceptions::PreferencesException, 'Keys are not iteratable objects' if not section?
144
375
  @_keys ||= all_keys
145
376
  end
146
377
 
147
378
  def all_keys
379
+ return if not section?
148
380
  keys = []
149
381
 
150
- driver.listPrefs(true, @key).to_a.each do |data|
151
- data = data.to_s
152
-
153
- data =~ /^key: \"([a-zA-Z0-9\(\)\\\.\-\s]*)\"/
154
- key = $1.gsub(/\\t/, '')
155
-
156
- keys << Entry.new(self, key.methodize)
382
+ driver.listPrefs(true, key).to_a.each do |p|
383
+ p = p.to_s
384
+
385
+ p =~ /^key: \"([a-zA-Z0-9\(\)\\\.\-\s]*)\"$/
386
+ key = $1.to_s.gsub(/^\\t/, "\t") # Workaround for double-encoded tabs:
387
+ # We get \\t, but it only accepts \t.
388
+
389
+ p =~ /^type: ([A-Z]+)$/
390
+ type = $1.to_s.capitalize
391
+
392
+ next if key.empty? # “Opera Widgets/Unite Style File” is bugged, workaround.
393
+ keys << Entry.new(self, key.methodize, key, type)
157
394
  end
158
395
 
159
396
  keys