watir-nokogiri 1.0.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 (43) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +65 -0
  3. data/lib/watir-nokogiri.rb +69 -0
  4. data/lib/watir-nokogiri/aliases.rb +6 -0
  5. data/lib/watir-nokogiri/attribute_helper.rb +145 -0
  6. data/lib/watir-nokogiri/cell_container.rb +31 -0
  7. data/lib/watir-nokogiri/container.rb +50 -0
  8. data/lib/watir-nokogiri/document.rb +171 -0
  9. data/lib/watir-nokogiri/element_collection.rb +93 -0
  10. data/lib/watir-nokogiri/elements/button.rb +71 -0
  11. data/lib/watir-nokogiri/elements/checkbox.rb +61 -0
  12. data/lib/watir-nokogiri/elements/dlist.rb +12 -0
  13. data/lib/watir-nokogiri/elements/element.rb +319 -0
  14. data/lib/watir-nokogiri/elements/file_field.rb +45 -0
  15. data/lib/watir-nokogiri/elements/font.rb +11 -0
  16. data/lib/watir-nokogiri/elements/form.rb +17 -0
  17. data/lib/watir-nokogiri/elements/frame.rb +75 -0
  18. data/lib/watir-nokogiri/elements/generated.rb +2662 -0
  19. data/lib/watir-nokogiri/elements/hidden.rb +24 -0
  20. data/lib/watir-nokogiri/elements/image.rb +59 -0
  21. data/lib/watir-nokogiri/elements/input.rb +34 -0
  22. data/lib/watir-nokogiri/elements/link.rb +7 -0
  23. data/lib/watir-nokogiri/elements/option.rb +83 -0
  24. data/lib/watir-nokogiri/elements/radio.rb +44 -0
  25. data/lib/watir-nokogiri/elements/select.rb +126 -0
  26. data/lib/watir-nokogiri/elements/table.rb +44 -0
  27. data/lib/watir-nokogiri/elements/table_cell.rb +36 -0
  28. data/lib/watir-nokogiri/elements/table_row.rb +46 -0
  29. data/lib/watir-nokogiri/elements/table_section.rb +15 -0
  30. data/lib/watir-nokogiri/elements/text_area.rb +22 -0
  31. data/lib/watir-nokogiri/elements/text_field.rb +44 -0
  32. data/lib/watir-nokogiri/exception.rb +20 -0
  33. data/lib/watir-nokogiri/locators/button_locator.rb +54 -0
  34. data/lib/watir-nokogiri/locators/child_cell_locator.rb +24 -0
  35. data/lib/watir-nokogiri/locators/child_row_locator.rb +29 -0
  36. data/lib/watir-nokogiri/locators/element_locator.rb +298 -0
  37. data/lib/watir-nokogiri/locators/text_area_locator.rb +20 -0
  38. data/lib/watir-nokogiri/locators/text_field_locator.rb +71 -0
  39. data/lib/watir-nokogiri/row_container.rb +42 -0
  40. data/lib/watir-nokogiri/user_editable.rb +38 -0
  41. data/lib/watir-nokogiri/version.rb +3 -0
  42. data/lib/watir-nokogiri/xpath_support.rb +22 -0
  43. metadata +102 -0
@@ -0,0 +1,93 @@
1
+ module WatirNokogiri
2
+
3
+ #
4
+ # Base class for element collections.
5
+ #
6
+
7
+ class ElementCollection
8
+ include Enumerable
9
+
10
+ def initialize(parent, selector)
11
+ @parent = parent
12
+ @selector = selector
13
+ end
14
+
15
+ #
16
+ # Yields each element in collection.
17
+ #
18
+ # @yieldparam [WatirNokogiri::Element] element Iterate through the elements in this collection.
19
+ #
20
+
21
+ def each(&blk)
22
+ to_a.each(&blk)
23
+ end
24
+
25
+ #
26
+ # Returns number of elements in collection.
27
+ #
28
+ # @return [Fixnum]
29
+ #
30
+
31
+ def length
32
+ elements.length
33
+ end
34
+ alias_method :size, :length
35
+
36
+ #
37
+ # Get the element at the given index.
38
+ # Note that this is 0-indexed.
39
+ #
40
+ # @param [Fixnum] idx Index of wanted element, 0-indexed
41
+ # @return [WatirNokogiri::Element] Returns an instance of a WatirNokogiri::Element subclass
42
+ #
43
+
44
+ def [](idx)
45
+ to_a[idx] || element_class.new(@parent, :index => idx)
46
+ end
47
+
48
+ #
49
+ # First element of this collection
50
+ #
51
+ # @return [WatirNokogiri::Element] Returns an instance of a WatirNokogiri::Element subclass
52
+ #
53
+
54
+ def first
55
+ self[0]
56
+ end
57
+
58
+ #
59
+ # Last element of the collection
60
+ #
61
+ # @return [WatirNokogiri::Element] Returns an instance of a WatirNokogiri::Element subclass
62
+ #
63
+
64
+ def last
65
+ self[-1]
66
+ end
67
+
68
+ #
69
+ # This collection as an Array.
70
+ #
71
+ # @return [Array<WatirNokogiri::Element>]
72
+ #
73
+
74
+ def to_a()
75
+ @to_a ||= elements.map{ |e| element_class.new(@parent, :element => e) }
76
+ end
77
+
78
+ private
79
+
80
+ def elements()
81
+ @elements ||= locator_class.new(@parent.nokogiri, @selector, element_class.attribute_list).locate_all
82
+ end
83
+
84
+ def element_class()
85
+ Element
86
+ end
87
+
88
+ def locator_class()
89
+ ElementLocator
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ module WatirNokogiri
3
+
4
+ #
5
+ # Class representing button elements.
6
+ #
7
+ # This class covers both <button> and <input type="submit|reset|image|button" /> elements.
8
+ #
9
+
10
+ class Button < HTMLElement
11
+
12
+ # add the attributes from <input>
13
+ attributes WatirNokogiri::Input.typed_attributes
14
+
15
+ VALID_TYPES = %w[button reset submit image]
16
+
17
+ #
18
+ # Returns the text of the button.
19
+ #
20
+ # For input elements, returns the "value" attribute.
21
+ # For button elements, returns the inner text.
22
+ #
23
+ # @return [String]
24
+ #
25
+
26
+ def text
27
+ assert_exists
28
+
29
+ tn = @element.node_name.downcase
30
+
31
+ case tn
32
+ when 'input'
33
+ @element.get_attribute(:value)
34
+ when 'button'
35
+ @element.text
36
+ else
37
+ raise Exception::Error, "unknown tag name for button: #{tn}"
38
+ end
39
+ end
40
+
41
+ #
42
+ # Returns true if this element is enabled.
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+
47
+ def enabled?
48
+ !disabled?
49
+ end
50
+
51
+ private
52
+
53
+ def locate
54
+ @parent.assert_exists
55
+ ButtonLocator.new(@parent.nokogiri, @selector, self.class.attribute_list).locate
56
+ end
57
+
58
+ end # Button
59
+
60
+ class ButtonCollection < ElementCollection
61
+ private
62
+
63
+ def locator_class
64
+ ButtonLocator
65
+ end
66
+
67
+ def element_class
68
+ Button
69
+ end
70
+ end # ButtonsCollection
71
+ end # Watir
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ module WatirNokogiri
4
+ class CheckBox < Input
5
+
6
+ #
7
+ # Sets checkbox to the given value.
8
+ #
9
+ # @example
10
+ # checkbox.set? #=> false
11
+ # checkbox.set
12
+ # checkbox.set? #=> true
13
+ # checkbox.set(false)
14
+ # checkbox.set? #=> false
15
+ #
16
+ # @param [Boolean] bool
17
+ #
18
+
19
+ def set(bool = true)
20
+ assert_exists
21
+ raise NotImplementedError, "not currently supported by WatirNokogiri"
22
+ end
23
+
24
+ #
25
+ # Returns true if the element is checked
26
+ # @return [Boolean]
27
+ #
28
+
29
+ def set?
30
+ assert_exists
31
+ !@element.get_attribute('checked').nil?
32
+ end
33
+
34
+ #
35
+ # Unsets checkbox.
36
+ #
37
+ # Same as +set(false)+
38
+ #
39
+
40
+ def clear
41
+ set false
42
+ end
43
+
44
+ end # CheckBox
45
+
46
+ module Container
47
+ def checkbox(*args)
48
+ CheckBox.new(self, extract_selector(args).merge(:tag_name => "input", :type => "checkbox"))
49
+ end
50
+
51
+ def checkboxes(*args)
52
+ CheckBoxCollection.new(self, extract_selector(args).merge(:tag_name => "input", :type => "checkbox"))
53
+ end
54
+ end # Container
55
+
56
+ class CheckBoxCollection < InputCollection
57
+ def element_class
58
+ CheckBox
59
+ end
60
+ end # CheckBoxCollection
61
+ end # Watir
@@ -0,0 +1,12 @@
1
+ module WatirNokogiri
2
+ class DList < HTMLElement
3
+
4
+ def to_hash
5
+ keys = dts.map { |e| e.text }
6
+ values = dds.map { |e| e.text }
7
+
8
+ Hash[keys.zip(values)]
9
+ end
10
+
11
+ end # DList
12
+ end # WatirNokogiri
@@ -0,0 +1,319 @@
1
+ # encoding: utf-8
2
+
3
+ module WatirNokogiri
4
+
5
+ #
6
+ # Base class for HTML elements.
7
+ #
8
+
9
+ class Element
10
+ extend AttributeHelper
11
+
12
+ include Exception
13
+ include Container
14
+
15
+ attributes :string => [:id, :class_name]
16
+
17
+ def initialize(parent, selector)
18
+ @parent = parent
19
+ @selector = selector
20
+ @element = nil
21
+
22
+ unless @selector.kind_of? Hash
23
+ raise ArgumentError, "invalid argument: #{selector.inspect}"
24
+ end
25
+ end
26
+
27
+ #
28
+ # Returns true if two elements are equal.
29
+ #
30
+ # @example
31
+ # html.a(:id => "foo") == html.a(:id => "foo")
32
+ # #=> true
33
+ #
34
+
35
+ def ==(other)
36
+ return false unless other.kind_of? self.class
37
+
38
+ assert_exists
39
+ @element == other.nokogiri
40
+ end
41
+ alias_method :eql?, :==
42
+
43
+ #
44
+ # Returns given attribute value of element.
45
+ #
46
+ # @example
47
+ # html.a(:id => "foo").attribute_value "href"
48
+ # #=> "http://watir.com"
49
+ #
50
+ # @param [String] attribute_name
51
+ # @return [String]
52
+ #
53
+
54
+ def attribute_value(attribute_name)
55
+ assert_exists
56
+ @element.get_attribute(attribute_name) || ''
57
+ end
58
+
59
+ def click(*modifiers)
60
+ assert_exists
61
+ raise "Not implemented"
62
+ end
63
+
64
+ #
65
+ # Returns the css path for the element
66
+ #
67
+
68
+ def css_path()
69
+ assert_exists
70
+ @element.css_path
71
+ end
72
+
73
+ #
74
+ # @api private
75
+ #
76
+
77
+ def document
78
+ @parent.document
79
+ end
80
+
81
+ #
82
+ # @api private
83
+ #
84
+
85
+ def driver
86
+ @parent.driver
87
+ end
88
+
89
+ #
90
+ # Returns true if element exists.
91
+ #
92
+ # @return [Boolean]
93
+ #
94
+
95
+ def exists?()
96
+ begin
97
+ assert_exists
98
+ return true
99
+ rescue UnknownObjectException, UnknownFrameException
100
+ return false
101
+ end
102
+ end
103
+ alias_method :exist?, :exists?
104
+
105
+ #
106
+ # Returns outer (inner + element itself) HTML code of element.
107
+ #
108
+ # @example
109
+ # html.div(:id => "foo").html
110
+ # #=> "<div id=\"foo\"><a>Click</a></div>"
111
+ #
112
+ # @return [String]
113
+ #
114
+
115
+ def html
116
+ assert_exists
117
+ @element.to_html
118
+ end
119
+
120
+ def id()
121
+ assert_exists
122
+ attribute_value('id')
123
+ end
124
+
125
+ def inspect()
126
+ if @selector.has_key?(:element)
127
+ '#<%s:0x%x located=%s selector=%s>' % [self.class, hash*2, !!@element, '{:element=>(nokogiri element)}']
128
+ else
129
+ '#<%s:0x%x located=%s selector=%s>' % [self.class, hash*2, !!@element, @selector.inspect]
130
+ end
131
+ end
132
+
133
+ #
134
+ # @api private
135
+ #
136
+
137
+ def nokogiri()
138
+ assert_exists
139
+ @element
140
+ end
141
+
142
+ #
143
+ # Returns given style property of this element.
144
+ #
145
+ # @example
146
+ # html.a(:id => "foo").style
147
+ # #=> "display: block"
148
+ # html.a(:id => "foo").style "display"
149
+ # #=> "block"
150
+ #
151
+ # @param [String] property
152
+ # @return [String]
153
+ #
154
+
155
+ def style(property = nil)
156
+ assert_exists
157
+ styles = attribute_value('style').to_s.strip
158
+ if property
159
+ properties = Hash[styles.downcase.split(";").map { |p| p.split(":").map(&:strip) }]
160
+ properties[property]
161
+ else
162
+ styles
163
+ end
164
+ end
165
+
166
+ #
167
+ # Returns parent element of current element.
168
+ #
169
+
170
+ def parent
171
+ assert_exists
172
+
173
+ e = @element.parent
174
+
175
+ if e.kind_of?(Nokogiri::XML::Element)
176
+ WatirNokogiri.element_class_for(e.node_name.downcase).new(@parent, :element => e)
177
+ end
178
+ end
179
+
180
+ #
181
+ # Returns true if the element exists and is visible on the page.
182
+ #
183
+ # @return [Boolean]
184
+ #
185
+
186
+ def present?
187
+ assert_exists
188
+ raise "Not implemented"
189
+ end
190
+
191
+ #
192
+ # Returns tag name of the element.
193
+ #
194
+ # @return [String]
195
+ #
196
+
197
+ def tag_name
198
+ assert_exists
199
+ @element.node_name.downcase
200
+ end
201
+
202
+ #
203
+ # Returns the text of the element.
204
+ #
205
+ # @return [String]
206
+ #
207
+
208
+ def text()
209
+ assert_exists
210
+ @element.text.strip.gsub(/\s+/, ' ')
211
+ end
212
+
213
+ #
214
+ # Cast this Element instance to a more specific subtype.
215
+ #
216
+ # @example
217
+ # browser.element(:xpath => "//input[@type='submit']").to_subtype
218
+ # #=> #<WatirNokogiri::Button>
219
+ #
220
+
221
+ def to_subtype
222
+ elem = nokogiri()
223
+ tag_name = elem.node_name.downcase
224
+
225
+ klass = nil
226
+
227
+ if tag_name == "input"
228
+ klass = case elem.get_attribute(:type)
229
+ when *Button::VALID_TYPES
230
+ Button
231
+ when 'checkbox'
232
+ CheckBox
233
+ when 'radio'
234
+ Radio
235
+ when 'file'
236
+ FileField
237
+ else
238
+ TextField
239
+ end
240
+ else
241
+ klass = WatirNokogiri.element_class_for(tag_name)
242
+ end
243
+
244
+ klass.new(@parent, :element => elem)
245
+ end
246
+
247
+ #
248
+ # Returns value of the element.
249
+ #
250
+ # @return [String]
251
+ #
252
+
253
+ def value
254
+ assert_exists
255
+ attribute_value('value')
256
+ end
257
+
258
+ #
259
+ # Returns true if this element is visible on the page.
260
+ #
261
+ # @return [Boolean]
262
+ #
263
+
264
+ def visible?
265
+ assert_exists
266
+ raise "Not implemented"
267
+ end
268
+
269
+ #
270
+ # Returns the xpath of the current element.
271
+ #
272
+
273
+ def xpath()
274
+ assert_exists
275
+ @element.path
276
+ end
277
+
278
+ protected
279
+
280
+ def assert_exists()
281
+ return if @element
282
+
283
+ @element = @selector[:element] || locate
284
+
285
+ unless @element
286
+ raise UnknownObjectException, "unable to locate element, using #{@selector.inspect}"
287
+ end
288
+ end
289
+
290
+ def locate
291
+ @parent.assert_exists
292
+ locator_class.new(@parent.nokogiri, @selector, self.class.attribute_list).locate
293
+ end
294
+
295
+ private
296
+
297
+ #
298
+ # Returns attribute value if attribute exists; nil otherwise
299
+ #
300
+ def attribute?(attribute)
301
+ assert_exists
302
+ @element.get_attribute(attribute.to_s.downcase)
303
+ end
304
+
305
+ def locator_class
306
+ ElementLocator
307
+ end
308
+
309
+ def method_missing(meth, *args, &blk)
310
+ method = meth.to_s
311
+ if method =~ /^data_(.+)$/
312
+ attribute_value(method.gsub(/_/, '-'), *args)
313
+ else
314
+ super
315
+ end
316
+ end
317
+ end
318
+
319
+ end