watir-webdriver 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/Rakefile +53 -31
  2. data/VERSION +1 -1
  3. data/lib/watir-webdriver.rb +6 -8
  4. data/lib/watir-webdriver/attribute_helper.rb +121 -0
  5. data/lib/watir-webdriver/browser.rb +13 -6
  6. data/lib/watir-webdriver/collections/element_collection.rb +21 -15
  7. data/lib/watir-webdriver/collections/table_row_collection.rb +11 -0
  8. data/lib/watir-webdriver/container.rb +17 -11
  9. data/lib/watir-webdriver/element.rb +201 -0
  10. data/lib/watir-webdriver/elements/button.rb +19 -2
  11. data/lib/watir-webdriver/elements/checkbox.rb +24 -4
  12. data/lib/watir-webdriver/elements/file_field.rb +24 -4
  13. data/lib/watir-webdriver/elements/font.rb +10 -11
  14. data/lib/watir-webdriver/elements/frame.rb +11 -3
  15. data/lib/watir-webdriver/elements/generated.rb +2491 -1313
  16. data/lib/watir-webdriver/elements/hidden.rb +16 -5
  17. data/lib/watir-webdriver/elements/input.rb +44 -5
  18. data/lib/watir-webdriver/elements/link.rb +6 -8
  19. data/lib/watir-webdriver/elements/radio.rb +25 -6
  20. data/lib/watir-webdriver/elements/{select_list.rb → select.rb} +8 -9
  21. data/lib/watir-webdriver/elements/text_field.rb +32 -3
  22. data/lib/watir-webdriver/html.rb +18 -0
  23. data/lib/watir-webdriver/html/generator.rb +112 -0
  24. data/lib/watir-webdriver/html/idl_sorter.rb +49 -0
  25. data/lib/watir-webdriver/html/spec_extractor.rb +111 -0
  26. data/lib/watir-webdriver/html/util.rb +31 -0
  27. data/lib/watir-webdriver/html/visitor.rb +186 -0
  28. data/lib/watir-webdriver/locators/element_locator.rb +4 -0
  29. data/lib/watir-webdriver/locators/text_field_locator.rb +2 -2
  30. data/lib/watir-webdriver/xpath_support.rb +3 -5
  31. data/lib/yard/handlers/watir.rb +57 -0
  32. data/spec/{base_element_spec.rb → element_spec.rb} +3 -2
  33. data/spec/input_spec.rb +65 -0
  34. data/spec/spec_helper.rb +9 -2
  35. data/spec/watirspec/area_spec.rb +9 -13
  36. data/spec/watirspec/areas_spec.rb +7 -1
  37. data/spec/watirspec/browser_spec.rb +68 -72
  38. data/spec/watirspec/button_spec.rb +16 -9
  39. data/spec/watirspec/buttons_spec.rb +11 -9
  40. data/spec/watirspec/checkbox_spec.rb +1 -1
  41. data/spec/watirspec/checkboxes_spec.rb +7 -1
  42. data/spec/watirspec/collections_spec.rb +18 -0
  43. data/spec/watirspec/dd_spec.rb +1 -1
  44. data/spec/watirspec/dds_spec.rb +7 -1
  45. data/spec/watirspec/del_spec.rb +141 -0
  46. data/spec/watirspec/dels_spec.rb +37 -0
  47. data/spec/watirspec/div_spec.rb +6 -22
  48. data/spec/watirspec/divs_spec.rb +8 -2
  49. data/spec/watirspec/dl_spec.rb +1 -1
  50. data/spec/watirspec/dls_spec.rb +7 -1
  51. data/spec/watirspec/dt_spec.rb +1 -1
  52. data/spec/watirspec/dts_spec.rb +7 -1
  53. data/spec/watirspec/element_spec.rb +11 -20
  54. data/spec/watirspec/em_spec.rb +1 -1
  55. data/spec/watirspec/ems_spec.rb +7 -1
  56. data/spec/watirspec/filefield_spec.rb +8 -11
  57. data/spec/watirspec/filefields_spec.rb +7 -1
  58. data/spec/watirspec/font_spec.rb +2 -2
  59. data/spec/watirspec/form_spec.rb +10 -18
  60. data/spec/watirspec/forms_spec.rb +7 -1
  61. data/spec/watirspec/frame_spec.rb +69 -73
  62. data/spec/watirspec/frames_spec.rb +15 -2
  63. data/spec/watirspec/hidden_spec.rb +1 -1
  64. data/spec/watirspec/hiddens_spec.rb +7 -1
  65. data/spec/watirspec/hn_spec.rb +1 -1
  66. data/spec/watirspec/hns_spec.rb +23 -27
  67. data/spec/watirspec/image_spec.rb +9 -15
  68. data/spec/watirspec/images_spec.rb +7 -1
  69. data/spec/watirspec/ins_spec.rb +142 -0
  70. data/spec/watirspec/inses_spec.rb +37 -0
  71. data/spec/watirspec/label_spec.rb +1 -1
  72. data/spec/watirspec/labels_spec.rb +7 -1
  73. data/spec/watirspec/li_spec.rb +1 -1
  74. data/spec/watirspec/lib/guards.rb +12 -12
  75. data/spec/watirspec/lib/implementation.rb +48 -0
  76. data/spec/watirspec/lib/watirspec.rb +17 -12
  77. data/spec/watirspec/link_spec.rb +6 -11
  78. data/spec/watirspec/links_spec.rb +1 -1
  79. data/spec/watirspec/lis_spec.rb +7 -1
  80. data/spec/watirspec/map_spec.rb +1 -1
  81. data/spec/watirspec/maps_spec.rb +7 -1
  82. data/spec/watirspec/meta_spec.rb +13 -15
  83. data/spec/watirspec/metas_spec.rb +6 -1
  84. data/spec/watirspec/ol_spec.rb +57 -59
  85. data/spec/watirspec/ols_spec.rb +10 -4
  86. data/spec/watirspec/option_spec.rb +50 -83
  87. data/spec/watirspec/p_spec.rb +1 -1
  88. data/spec/watirspec/pre_spec.rb +1 -1
  89. data/spec/watirspec/pres_spec.rb +7 -1
  90. data/spec/watirspec/ps_spec.rb +7 -1
  91. data/spec/watirspec/radio_spec.rb +9 -11
  92. data/spec/watirspec/radios_spec.rb +1 -1
  93. data/spec/watirspec/select_list_spec.rb +27 -40
  94. data/spec/watirspec/select_lists_spec.rb +1 -1
  95. data/spec/watirspec/span_spec.rb +1 -1
  96. data/spec/watirspec/spans_spec.rb +7 -1
  97. data/spec/watirspec/spec_helper.rb +1 -0
  98. data/spec/watirspec/strong_spec.rb +1 -1
  99. data/spec/watirspec/strongs_spec.rb +7 -1
  100. data/spec/watirspec/table_bodies_spec.rb +22 -10
  101. data/spec/watirspec/table_body_spec.rb +33 -40
  102. data/spec/watirspec/table_cell_spec.rb +1 -1
  103. data/spec/watirspec/table_cells_spec.rb +36 -15
  104. data/spec/watirspec/table_footer_spec.rb +43 -40
  105. data/spec/watirspec/table_footers_spec.rb +35 -19
  106. data/spec/watirspec/table_header_spec.rb +44 -39
  107. data/spec/watirspec/table_headers_spec.rb +37 -19
  108. data/spec/watirspec/table_row_spec.rb +13 -9
  109. data/spec/watirspec/table_rows_spec.rb +16 -6
  110. data/spec/watirspec/table_spec.rb +83 -62
  111. data/spec/watirspec/tables_spec.rb +7 -1
  112. data/spec/watirspec/text_field_spec.rb +4 -6
  113. data/spec/watirspec/text_fields_spec.rb +1 -1
  114. data/spec/watirspec/ul_spec.rb +1 -1
  115. data/spec/watirspec/uls_spec.rb +25 -22
  116. data/support/html5.html +89235 -0
  117. data/watir-webdriver.gemspec +31 -21
  118. metadata +52 -23
  119. data/TODO +0 -15
  120. data/lib/watir-webdriver/base_element.rb +0 -361
  121. data/lib/watir-webdriver/collections/buttons_collection.rb +0 -15
  122. data/lib/watir-webdriver/collections/table_rows_collection.rb +0 -16
  123. data/lib/watir-webdriver/collections/text_fields_collection.rb +0 -15
  124. data/lib/watir-webdriver/elements/headings.rb +0 -48
  125. data/support/html5/html5.idl +0 -1274
  126. data/support/html5/old/html5.idl +0 -962
  127. data/support/html5/old/html5_extras.idl +0 -145
  128. data/support/html5/watir_visitor.rb +0 -173
  129. data/support/yard_handlers.rb +0 -87
@@ -0,0 +1,111 @@
1
+ # encoding: utf-8
2
+
3
+ module Watir
4
+ module HTML
5
+ class SpecExtractor
6
+ def initialize(uri)
7
+ @uri = uri
8
+ end
9
+
10
+ def process
11
+ download_and_parse
12
+ extract_idl_parts
13
+ extract_interface_map
14
+ build_result
15
+ end
16
+
17
+ def errors
18
+ @errors ||= []
19
+ end
20
+
21
+ #
22
+ # returns a topoligically sorted array of WebIDL::Ast::Interface objects
23
+ #
24
+
25
+ def sorted_interfaces
26
+ process if @interfaces.nil?
27
+
28
+ sorter.sort.map { |name|
29
+ @interfaces_by_name[name] or puts "ignoring interface: #{name}"
30
+ }.flatten.compact
31
+ end
32
+
33
+ def print_hierarchy
34
+ process if @interfaces.nil?
35
+ sorter.print
36
+ end
37
+
38
+ private
39
+
40
+ def download_and_parse
41
+ open(@uri) { |io| @doc = Nokogiri.HTML(io) }
42
+ end
43
+
44
+ def extract_idl_parts
45
+ parsed = @doc.search("//pre[@class='idl']").map { |e| parse_idl(e.inner_text) }.compact
46
+
47
+ @interfaces = parsed.map { |elements|
48
+ elements.select { |e| e.kind_of? WebIDL::Ast::Interface }
49
+ }.flatten
50
+
51
+ @interfaces_by_name = @interfaces.group_by { |i| i.name }
52
+ end
53
+
54
+ def extract_interface_map
55
+ table = @doc.search("//h3[@id='elements-1']/following-sibling::table[1]").first
56
+ table or raise "could not find elements-1 table"
57
+
58
+ @interface_map = {}
59
+
60
+ parse_table(table).each do |row|
61
+ row['Element'].split(", ").each { |tag| @interface_map[tag] = row['Interface'] }
62
+ end
63
+ end
64
+
65
+ def build_result
66
+ # tag name => Interface instance(s)
67
+ result = {}
68
+
69
+ @interface_map.each do |tag, interface|
70
+ result[tag] = @interfaces_by_name[interface] or raise "#{interface} not found in IDL"
71
+ end
72
+
73
+ result
74
+ end
75
+
76
+ def parse_table(table)
77
+ headers = table.css("thead th").map { |e| e.inner_text.strip }
78
+
79
+ table.css("tbody tr").map do |row|
80
+ result = {}
81
+
82
+ row.css("th, td").each_with_index do |node, idx|
83
+ result[headers[idx]] = node.inner_text.strip
84
+ end
85
+
86
+ result
87
+ end
88
+ end
89
+
90
+ def parse_idl(str)
91
+ result = idl_parser.parse(str)
92
+
93
+ if result
94
+ result.build
95
+ else
96
+ errors << idl_parser.failure_reason
97
+ nil
98
+ end
99
+ end
100
+
101
+ def idl_parser
102
+ @idl_parser ||= WebIDL::Parser::IDLParser.new
103
+ end
104
+
105
+ def sorter
106
+ @idl_sroter ||= IDLSorter.new(@interfaces)
107
+ end
108
+
109
+ end # SpecExtractor
110
+ end # HTML
111
+ end # Watir
@@ -0,0 +1,31 @@
1
+ module Watir
2
+ module HTML
3
+ module Util
4
+
5
+ module_function
6
+
7
+
8
+ def classify(name)
9
+ if name =~ /^HTML(.+)Element$/
10
+ $1
11
+ else
12
+ name
13
+ end
14
+ end
15
+
16
+ SPECIALS = {
17
+ 'img' => 'image'
18
+ }
19
+
20
+ def paramify(str)
21
+ if SPECIALS.has_key?(str)
22
+ SPECIALS[str]
23
+ else
24
+ classify(str).snake_case
25
+ end
26
+ end
27
+
28
+ end # Util
29
+ end # HTML
30
+ end # Watir
31
+
@@ -0,0 +1,186 @@
1
+ # encoding: utf-8
2
+
3
+ module Watir
4
+ module HTML
5
+ class Visitor < WebIDL::RubySexpVisitor
6
+
7
+ def initialize
8
+ super
9
+
10
+ # When an interface has multiple IDL definitions in the spec, the inheritance is sometimes
11
+ # not repeated. So we'll keep track ourselves.
12
+ @inheritance_map = {}
13
+
14
+ @already_defined = []
15
+ end
16
+
17
+ #
18
+ # WebIDL visitor interface
19
+ #
20
+
21
+ def visit_interface(interface)
22
+ name = interface.name
23
+ parent = interface.inherits.first
24
+
25
+ $stderr.puts name
26
+ return unless name =~ /^HTML/ && name !~ /(Collection|Document)$/
27
+
28
+ if name == "HTMLElement"
29
+ parent = 'Element'
30
+ elsif parent
31
+ @inheritance_map[name] ||= parent.name
32
+ parent = parent.name
33
+ else
34
+ parent = @inheritance_map[name] || return
35
+ end
36
+
37
+ [ :scope,
38
+ [:block,
39
+ element_class(interface.name, interface.members.select { |e| e.kind_of?(WebIDL::Ast::Attribute) }, parent),
40
+ collection_class(interface.name)
41
+ ]
42
+ ]
43
+ end
44
+
45
+ def visit_module(mod)
46
+ # ignored
47
+ end
48
+
49
+ def visit_implements_statement(stmt)
50
+ # ignored
51
+ end
52
+
53
+ # TODO: do everything in the visitor somehow?
54
+ # problem is we lack the tag name info while walking the interface AST
55
+ # #
56
+ # # Watir generator visitor interface
57
+ # #
58
+ #
59
+ # def visit_tag(tag_name, interface_name)
60
+ # tag_string = tag.inspect
61
+ # singular = Util.paramify(tag)
62
+ # plural = singular.pluralize
63
+ # element_class = Util.classify(interfaces.first.name)
64
+ # collection_class = "#{element_class}Collection"
65
+ #
66
+ # [:defn,
67
+ # :a,
68
+ # [:args, :"*args"],
69
+ # [:scope,
70
+ # [:block,
71
+ # [:call,
72
+ # [:const, :Anchor],
73
+ # :new,
74
+ # [:arglist,
75
+ # [:self],
76
+ # [:call,
77
+ # [:call, nil, :extract_selector, [:arglist, [:lvar, :args]]],
78
+ # :merge,
79
+ # [:arglist, [:hash, [:lit, :tag_name], [:str, "a"]]]]]]]]]
80
+ # end
81
+
82
+ private
83
+
84
+ def element_class(name, attributes, parent)
85
+ [:class, Util.classify(name), [:const, Util.classify(parent)],
86
+ [:scope,
87
+ [:block, attributes_call(attributes)]
88
+ ]
89
+ ]
90
+ end
91
+
92
+ def collection_class(name)
93
+ return if @already_defined.include?(name)
94
+ @already_defined << name
95
+ name = Util.classify(name)
96
+
97
+ [:class, "#{name}Collection", [:const, :ElementCollection],
98
+ [:scope,
99
+ [:defn, :element_class,
100
+ [:args],
101
+ [:scope,
102
+ [:block, [:const, name]]
103
+ ]
104
+ ]
105
+ ]
106
+ ]
107
+ end
108
+
109
+ def attributes_call(attributes)
110
+ return if attributes.empty?
111
+
112
+ attrs = Hash.new { |hash, key| hash[key] = [] }
113
+ attributes.each do |a|
114
+ attrs[ruby_type_for(a.type)] << a.name.snake_case
115
+ end
116
+
117
+ call :attributes, [[:hash] + attrs.map { |type, names| [[:lit, type], literal_array(names)] }.flatten(1)]
118
+ end
119
+
120
+ def identifier_call(tag_name)
121
+ call :identifier, [literal_hash(:tag_name => tag_name)]
122
+ end
123
+
124
+ def container_call(name)
125
+ call :container_method, [[:lit, Util.paramify(name).to_sym]]
126
+ end
127
+
128
+ def collection_call(name)
129
+ call :collection_method, [[:lit, Util.paramify(name).pluralize.to_sym]]
130
+ end
131
+
132
+ def literal_hash(hash)
133
+ [:hash] + hash.map { |k, v| [[:lit, k.to_sym], [:lit, v]] }.flatten(1)
134
+ end
135
+
136
+ def literal_array(arr)
137
+ [:array] + arr.map { |e| [:lit, e.to_sym] }
138
+ end
139
+
140
+ def call(name, args)
141
+ [:call, nil, name.to_sym, [:arglist] + args]
142
+ end
143
+
144
+ def ruby_type_for(type)
145
+ case type.name.to_s
146
+ when 'DOMString', 'any'
147
+ :string
148
+ when 'UnsignedLong', 'Long', 'Integer', 'Short', 'UnsignedShort'
149
+ :int
150
+ when 'Float', 'Double'
151
+ :float
152
+ when 'Function'
153
+ :function
154
+ when 'Boolean'
155
+ :bool
156
+ when 'Document'
157
+ :document
158
+ when 'DOMTokenList', 'DOMSettableTokenList'
159
+ :token_list
160
+ when 'DOMStringMap'
161
+ :string_map
162
+ when 'HTMLPropertiesCollection'
163
+ :properties_collection
164
+ when /HTML(.*)Element/
165
+ :html_element
166
+ when /HTML(.*)Collection/
167
+ :html_collection
168
+ when 'CSSStyleDeclaration'
169
+ :style
170
+ when /.+List$/
171
+ :list
172
+ when 'Date'
173
+ :date
174
+ when 'Element'
175
+ :element
176
+ when 'WindowProxy', 'ValidityState', 'MediaError', 'TimeRanges', 'Location', 'Any', 'TimedTrackArray', 'TimedTrack'
177
+ # probably completely wrong.
178
+ :string
179
+ else
180
+ raise "unknown type: #{type.name}"
181
+ end
182
+ end
183
+
184
+ end # Visitor
185
+ end # Support
186
+ end # Watir
@@ -231,6 +231,10 @@ module Watir
231
231
  nil
232
232
  end
233
233
 
234
+ def all_elements
235
+ @wd.find_elements(:xpath => ".//*")
236
+ end
237
+
234
238
  def tag_name_matches?(element, tag_name)
235
239
  tag_name === element.tag_name
236
240
  end
@@ -12,7 +12,7 @@ module Watir
12
12
  def build_xpath(selectors)
13
13
  return if selectors.values.any? { |e| e.kind_of? Regexp }
14
14
 
15
- selectors.delete(:tag_name) || raise("internal error: no tag_name?!")
15
+ selectors.delete(:tag_name)
16
16
 
17
17
  @building = :textarea
18
18
  textarea_attr_exp = attribute_expression(selectors)
@@ -58,4 +58,4 @@ module Watir
58
58
  !!(/^(input|textarea)$/ === element.tag_name)
59
59
  end
60
60
  end # TextFieldLocator
61
- end # Watir
61
+ end # Watir
@@ -9,9 +9,9 @@ module Watir
9
9
 
10
10
  def element_by_xpath(xpath)
11
11
  e = wd.find_element(:xpath, xpath)
12
- Watir.element_class_for(e.tag_name).new(self, :element, e)
12
+ Watir.element_class_for(e.tag_name).new(self, :element => e)
13
13
  rescue WebDriver::Error::NoSuchElementError
14
- BaseElement.new(self, :xpath, xpath)
14
+ Element.new(self, :xpath => xpath)
15
15
  end
16
16
 
17
17
  #
@@ -20,10 +20,8 @@ module Watir
20
20
 
21
21
  def elements_by_xpath(xpath)
22
22
  wd.find_elements(:xpath, xpath).map do |e|
23
- Watir.element_class_for(e.tag_name).new(self, :element, e)
23
+ Watir.element_class_for(e.tag_name).new(self, :element => e)
24
24
  end
25
- rescue WebDriver::Error::NoSuchElementError
26
- []
27
25
  end
28
26
 
29
27
  end # XpathSupport
@@ -0,0 +1,57 @@
1
+ require "watir-webdriver/core_ext/string"
2
+
3
+ module YARD
4
+ module Handlers
5
+ module Watir
6
+ #
7
+ # @private
8
+ #
9
+
10
+ class AttributesHandler < YARD::Handlers::Ruby::Base
11
+ handles method_call(:attributes)
12
+
13
+ TYPES = {
14
+ :string => "String",
15
+ :bool => "Boolean",
16
+ :int => "Integer"
17
+ }
18
+
19
+ def process
20
+ attributes = try_eval
21
+
22
+ if attributes.nil?
23
+ p :ignoring => statement.source, :in => namespace.to_s
24
+ return
25
+ end
26
+
27
+ TYPES.each do |type, return_type|
28
+ if attributes.member? type
29
+ create_attributes attributes[type], return_type
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def create_attributes(names, return_type)
37
+ names.each do |attribute_name|
38
+ p :adding => "#{namespace}##{attribute_name}"
39
+ attribute_name = "#{attribute_name}?".to_sym if return_type == "Boolean"
40
+ register MethodObject.new(namespace, attribute_name, scope) do |o|
41
+ o.visibility = :public
42
+ o.explicit = false
43
+ o.docstring.add_tag YARD::Tags::Tag.new(:return, "", return_type)
44
+ end
45
+ end
46
+ end
47
+
48
+ def try_eval
49
+ eval "{#{statement.parameters.source}}"
50
+ rescue SyntaxError, StandardError
51
+ nil
52
+ end
53
+
54
+ end # AttributesHandler
55
+ end # Watir
56
+ end # Handlers
57
+ end
@@ -1,6 +1,7 @@
1
- require File.dirname(__FILE__) + '/watirspec/spec_helper'
1
+ require File.expand_path 'watirspec/spec_helper', File.dirname(__FILE__)
2
2
 
3
- describe Watir::BaseElement do
3
+
4
+ describe Watir::Element do
4
5
 
5
6
  before :each do
6
7
  browser.goto("file://" + File.expand_path("html/keylogger.html", File.dirname(__FILE__)))