ayanko-watir-webdriver 0.1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +55 -0
  7. data/Rakefile +139 -0
  8. data/VERSION +1 -0
  9. data/lib/watir-webdriver.rb +71 -0
  10. data/lib/watir-webdriver/attribute_helper.rb +128 -0
  11. data/lib/watir-webdriver/browser.rb +164 -0
  12. data/lib/watir-webdriver/browserbot.js +49 -0
  13. data/lib/watir-webdriver/cell_container.rb +19 -0
  14. data/lib/watir-webdriver/container.rb +40 -0
  15. data/lib/watir-webdriver/core_ext/string.rb +22 -0
  16. data/lib/watir-webdriver/element_collection.rb +96 -0
  17. data/lib/watir-webdriver/elements/button.rb +75 -0
  18. data/lib/watir-webdriver/elements/checkbox.rb +73 -0
  19. data/lib/watir-webdriver/elements/element.rb +265 -0
  20. data/lib/watir-webdriver/elements/file_field.rb +69 -0
  21. data/lib/watir-webdriver/elements/font.rb +11 -0
  22. data/lib/watir-webdriver/elements/form.rb +17 -0
  23. data/lib/watir-webdriver/elements/frame.rb +110 -0
  24. data/lib/watir-webdriver/elements/generated.rb +2541 -0
  25. data/lib/watir-webdriver/elements/hidden.rb +24 -0
  26. data/lib/watir-webdriver/elements/image.rb +51 -0
  27. data/lib/watir-webdriver/elements/input.rb +42 -0
  28. data/lib/watir-webdriver/elements/link.rb +7 -0
  29. data/lib/watir-webdriver/elements/option.rb +55 -0
  30. data/lib/watir-webdriver/elements/radio.rb +49 -0
  31. data/lib/watir-webdriver/elements/select.rb +216 -0
  32. data/lib/watir-webdriver/elements/table.rb +37 -0
  33. data/lib/watir-webdriver/elements/table_cell.rb +36 -0
  34. data/lib/watir-webdriver/elements/table_row.rb +45 -0
  35. data/lib/watir-webdriver/elements/table_section.rb +9 -0
  36. data/lib/watir-webdriver/elements/text_field.rb +97 -0
  37. data/lib/watir-webdriver/exception.rb +21 -0
  38. data/lib/watir-webdriver/extensions/alerts.rb +69 -0
  39. data/lib/watir-webdriver/extensions/cookies.rb +39 -0
  40. data/lib/watir-webdriver/extensions/firefox/webdriver.xpi +0 -0
  41. data/lib/watir-webdriver/extensions/nokogiri.rb +14 -0
  42. data/lib/watir-webdriver/extensions/performance.rb +54 -0
  43. data/lib/watir-webdriver/extensions/wait.rb +141 -0
  44. data/lib/watir-webdriver/html.rb +19 -0
  45. data/lib/watir-webdriver/html/generator.rb +112 -0
  46. data/lib/watir-webdriver/html/idl_sorter.rb +49 -0
  47. data/lib/watir-webdriver/html/spec_extractor.rb +111 -0
  48. data/lib/watir-webdriver/html/util.rb +22 -0
  49. data/lib/watir-webdriver/html/visitor.rb +174 -0
  50. data/lib/watir-webdriver/locators/button_locator.rb +74 -0
  51. data/lib/watir-webdriver/locators/child_cell_locator.rb +32 -0
  52. data/lib/watir-webdriver/locators/child_row_locator.rb +37 -0
  53. data/lib/watir-webdriver/locators/element_locator.rb +352 -0
  54. data/lib/watir-webdriver/locators/text_field_locator.rb +65 -0
  55. data/lib/watir-webdriver/row_container.rb +34 -0
  56. data/lib/watir-webdriver/window_switching.rb +105 -0
  57. data/lib/watir-webdriver/xpath_support.rb +28 -0
  58. data/lib/yard/handlers/watir.rb +57 -0
  59. data/spec/alert_spec.rb +49 -0
  60. data/spec/browser_spec.rb +42 -0
  61. data/spec/container_spec.rb +42 -0
  62. data/spec/element_locator_spec.rb +304 -0
  63. data/spec/element_spec.rb +13 -0
  64. data/spec/html/alerts.html +11 -0
  65. data/spec/html/keylogger.html +15 -0
  66. data/spec/html/wait.html +27 -0
  67. data/spec/implementation.rb +17 -0
  68. data/spec/input_spec.rb +39 -0
  69. data/spec/locator_spec_helper.rb +51 -0
  70. data/spec/spec_helper.rb +14 -0
  71. data/spec/wait_spec.rb +98 -0
  72. data/support/html5.html +90243 -0
  73. data/watir-webdriver.gemspec +59 -0
  74. metadata +238 -0
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ module Watir
3
+ class Hidden < Input
4
+ def visible?
5
+ false
6
+ end
7
+ end
8
+
9
+ module Container
10
+ def hidden(*args)
11
+ Hidden.new(self, extract_selector(args).merge(:tag_name => "input", :type => "hidden"))
12
+ end
13
+
14
+ def hiddens(*args)
15
+ HiddenCollection.new(self, extract_selector(args).merge(:tag_name => "input", :type => "hidden"))
16
+ end
17
+ end # Container
18
+
19
+ class HiddenCollection < InputCollection
20
+ def element_class
21
+ Hidden
22
+ end
23
+ end # HiddenCollection
24
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ module Watir
3
+ class Image < HTMLElement
4
+
5
+ alias_method :loaded?, :complete?
6
+
7
+ #
8
+ # returns the image's width in pixels
9
+ #
10
+ # @return [Integer] width
11
+ #
12
+
13
+ def width
14
+ assert_exists
15
+ driver.execute_script "return arguments[0].width", @element
16
+ end
17
+
18
+ #
19
+ # returns the image's height in pixels
20
+ #
21
+ # @return [Integer] height
22
+ #
23
+
24
+ def height
25
+ assert_exists
26
+ driver.execute_script "return arguments[0].height", @element
27
+ end
28
+
29
+ def file_created_date
30
+ assert_exists
31
+ raise NotImplementedError
32
+ end
33
+
34
+ def file_size
35
+ assert_exists
36
+ raise NotImplementedError
37
+ end
38
+
39
+ def save(path)
40
+ assert_exists
41
+ raise NotImplementedError
42
+ end
43
+
44
+ end # Image
45
+
46
+ module Container
47
+ alias_method :image, :img
48
+ alias_method :images, :imgs
49
+ end # Container
50
+
51
+ end # Watir
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module Watir
3
+ class Input < HTMLElement
4
+
5
+ alias_method :readonly?, :read_only?
6
+
7
+ #
8
+ # @private
9
+ #
10
+ # subclasses can use this to validate the incoming element
11
+ #
12
+
13
+ def self.from(parent, element)
14
+ unless element.tag_name == "input"
15
+ raise TypeError, "can't create #{self} from #{element.inspect}"
16
+ end
17
+
18
+ new(parent, :element => element)
19
+ end
20
+
21
+ def enabled?
22
+ !disabled?
23
+ end
24
+
25
+ #
26
+ # Return the type attribute of the element, or 'text' if the attribute is invalid.
27
+ # TODO: discuss.
28
+ #
29
+ # @return [String]
30
+ #
31
+
32
+ def type
33
+ assert_exists
34
+ value = @element.attribute("type").to_s
35
+
36
+ # we return 'text' if the type is invalid
37
+ # not sure if we really should do this
38
+ TextFieldLocator::NON_TEXT_TYPES.include?(value) ? value : 'text'
39
+ end
40
+
41
+ end # Input
42
+ end # Watir
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+ module Watir
3
+ module Container
4
+ alias_method :link, :a
5
+ alias_method :links, :as
6
+ end
7
+ end # Watir
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ module Watir
3
+
4
+ #
5
+ # Represents an option in a select list.
6
+ #
7
+
8
+ class Option < HTMLElement
9
+
10
+ #
11
+ # Select this option
12
+ #
13
+
14
+ def select
15
+ assert_exists
16
+
17
+ @element.select
18
+ fire_event("onclick") rescue nil
19
+ end
20
+
21
+ #
22
+ # Toggle the selected state of this option
23
+ #
24
+
25
+ def toggle
26
+ assert_exists
27
+ @element.toggle
28
+ end
29
+
30
+ #
31
+ # Is this option selected?
32
+ #
33
+
34
+ def selected?
35
+ assert_exists
36
+ @element.selected?
37
+ end
38
+
39
+ def text
40
+ assert_exists
41
+
42
+ # A little unintuitive - we'll return the 'label' or 'text' attribute if
43
+ # they exist, otherwise the inner text of the element
44
+
45
+ attribute = [:label, :text].find { |a| attribute? a }
46
+
47
+ if attribute
48
+ @element.attribute(attribute)
49
+ else
50
+ @element.text
51
+ end
52
+ end
53
+
54
+ end # Option
55
+ end # Watir
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ module Watir
3
+ class Radio < Input
4
+ def self.from(parent, element)
5
+ if element.attribute(:type) != "radio"
6
+ raise TypeError, "expected type=radio for #{element.inspect}"
7
+ end
8
+
9
+ super
10
+ end
11
+ #
12
+ # Select this radio button.
13
+ #
14
+
15
+ def set
16
+ assert_exists
17
+ assert_enabled
18
+
19
+ @element.click unless set?
20
+ end
21
+
22
+ #
23
+ # Is this radio set?
24
+ #
25
+
26
+ def set?
27
+ assert_exists
28
+ @element.selected?
29
+ end
30
+ end # Radio
31
+
32
+ module Container
33
+ def radio(*args)
34
+ Radio.new(self, extract_selector(args).merge(:tag_name => "input", :type => "radio"))
35
+ end
36
+
37
+ def radios(*args)
38
+ RadioCollection.new(self, extract_selector(args).merge(:tag_name => "input", :type => "radio" ))
39
+ end
40
+ end # Container
41
+
42
+ class RadioCollection < InputCollection
43
+ private
44
+
45
+ def element_class
46
+ Radio
47
+ end
48
+ end # RadioCollection
49
+ end # Watir
@@ -0,0 +1,216 @@
1
+ # encoding: utf-8
2
+ module Watir
3
+ class Select < HTMLElement
4
+ include Watir::Exception
5
+
6
+ #
7
+ # Returns true if this element is enabled
8
+ #
9
+ # @return [Boolean]
10
+ #
11
+
12
+ def enabled?
13
+ !disabled?
14
+ end
15
+
16
+ #
17
+ # Clear all selected options
18
+ #
19
+
20
+ def clear
21
+ assert_exists
22
+
23
+ raise Error, "you can only clear multi-selects" unless multiple?
24
+
25
+ options.each do |o|
26
+ o.toggle if o.selected?
27
+ end
28
+ end
29
+
30
+ def options
31
+ assert_exists
32
+ super
33
+ end
34
+
35
+ #
36
+ # Returns true if the select list has one or more options where text or label matches the given value.
37
+ #
38
+ # @param [String, Regexp] value A value.
39
+ # @return [Boolean]
40
+ #
41
+
42
+ def include?(str_or_rx)
43
+ assert_exists
44
+ # TODO: optimize similar to selected?
45
+ options.any? { |e| str_or_rx === e.text }
46
+ end
47
+
48
+ #
49
+ # Select the option(s) whose text or label matches the given string.
50
+ # If this is a multi-select and several options match the value given, all will be selected.
51
+ #
52
+ # @param [String, Regexp] value A value.
53
+ # @raise [Watir::Exception::NoValueFoundException] if the value does not exist.
54
+ # @return [String] The text of the option selected. If multiple options match, returns the first match.
55
+ #
56
+
57
+ def select(str_or_rx)
58
+ select_by :text, str_or_rx
59
+ end
60
+
61
+ #
62
+ # Selects the option(s) whose value attribute matches the given string.
63
+ #
64
+ # @see +select+
65
+ #
66
+ # @param [String, Regexp] value A value.
67
+ # @raise [Watir::Exception::NoValueFoundException] if the value does not exist.
68
+ # @return [String] The option selected. If multiple options match, returns the first match
69
+ #
70
+
71
+ def select_value(str_or_rx)
72
+ select_by :value, str_or_rx
73
+ end
74
+
75
+ #
76
+ # Returns true if any of the selected options' text or label match the given value.
77
+ #
78
+ # @param [String, Regexp] value A value.
79
+ # @raise [Watir::Exception::UnknownObjectException] if the value does not exist.
80
+ # @return [Boolean]
81
+ #
82
+
83
+ def selected?(str_or_rx)
84
+ assert_exists
85
+ matches = @element.find_elements(:tag_name, 'option').select { |e| str_or_rx === e.text || str_or_rx === e.attribute(:label) }
86
+
87
+ if matches.empty?
88
+ raise UnknownObjectException, "Unable to locate option matching #{str_or_rx.inspect}"
89
+ end
90
+
91
+ matches.any? { |e| e.selected? }
92
+ end
93
+
94
+ #
95
+ # Returns the value of the first selected option in the select list.
96
+ # Returns nil if no option is selected.
97
+ #
98
+ # @return [String, nil]
99
+ #
100
+
101
+ def value
102
+ o = options.find { |e| e.selected? } || return
103
+ o.value
104
+ end
105
+
106
+
107
+ #
108
+ # @return [Array<String>] An array of strings representing the text value of the currently selected options.
109
+ #
110
+
111
+ def selected_options
112
+ assert_exists
113
+ options.map { |e| e.text if e.selected? }.compact
114
+ end
115
+
116
+ private
117
+
118
+ def select_by(how, str_or_rx)
119
+ assert_exists
120
+
121
+ case str_or_rx
122
+ when String, Numeric
123
+ select_by_string(how, str_or_rx.to_s)
124
+ when Regexp
125
+ select_by_regexp(how, str_or_rx)
126
+ else
127
+ raise TypeError, "expected String or Regexp, got #{str_or_rx.inspect}:#{str_or_rx.class}"
128
+ end
129
+ end
130
+
131
+ def select_by_string(how, string)
132
+ xpath = option_xpath_for(how, string)
133
+
134
+ if multiple?
135
+ elements = @element.find_elements(:xpath, xpath)
136
+ no_value_found(string) if elements.empty?
137
+
138
+ elements.each { |e| e.select unless e.selected? }
139
+ elements.first.text
140
+ else
141
+ begin
142
+ e = @element.find_element(:xpath, xpath)
143
+ rescue WebDriver::Error::NoSuchElementError
144
+ no_value_found(string)
145
+ end
146
+
147
+ e.select unless e.selected?
148
+
149
+ safe_text(e)
150
+ end
151
+ end
152
+
153
+ def select_by_regexp(how, exp)
154
+ elements = @element.find_elements(:tag_name, 'option')
155
+ no_value_found(nil, "no options in select list") if elements.empty?
156
+
157
+ if multiple?
158
+ found = elements.select do |e|
159
+ next unless matches_regexp?(how, e, exp)
160
+ e.select unless e.selected?
161
+ true
162
+ end
163
+
164
+ no_value_found(exp) if found.empty?
165
+
166
+ found.first.text
167
+ else
168
+ element = elements.find { |e| matches_regexp?(how, e, exp) }
169
+ no_value_found(exp) unless element
170
+
171
+ element.select unless element.selected?
172
+
173
+ safe_text(element)
174
+ end
175
+ end
176
+
177
+ def option_xpath_for(how, string)
178
+ case how
179
+ when :text
180
+ ".//option[normalize-space()='#{string}' or @label='#{string}']"
181
+ when :value
182
+ ".//option[@value='#{string}']"
183
+ else
184
+ raise Error, "unknown how: #{how.inspect}"
185
+ end
186
+ end
187
+
188
+ def matches_regexp?(how, element, exp)
189
+ case how
190
+ when :text
191
+ element.text =~ exp || element.attribute(:label) =~ exp
192
+ when :value
193
+ element.attribute(:value) =~ exp
194
+ else
195
+ raise Error, "unknown how: #{how.inspect}"
196
+ end
197
+ end
198
+
199
+ def safe_text(element)
200
+ element.text
201
+ rescue Selenium::WebDriver::Error::ObsoleteElementError
202
+ # guard for scenario where selecting the element changes the page, making our element obsolete
203
+
204
+ ''
205
+ end
206
+
207
+ def no_value_found(arg, msg = nil)
208
+ raise NoValueFoundException, msg || "#{arg.inspect} not found in select list"
209
+ end
210
+ end # Select
211
+
212
+ module Container
213
+ alias_method :select_list, :select
214
+ alias_method :select_lists, :selects
215
+ end # Container
216
+ end # Watir