watir-webdriver 0.7.0 → 0.8.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -2
  3. data/.travis.yml +2 -3
  4. data/CHANGES.md +10 -1
  5. data/Gemfile +1 -1
  6. data/README.md +22 -17
  7. data/Rakefile +55 -52
  8. data/lib/watir-webdriver.rb +3 -2
  9. data/lib/watir-webdriver/alert.rb +0 -1
  10. data/lib/watir-webdriver/atoms/README +1 -1
  11. data/lib/watir-webdriver/browser.rb +4 -5
  12. data/lib/watir-webdriver/cell_container.rb +2 -2
  13. data/lib/watir-webdriver/container.rb +2 -3
  14. data/lib/watir-webdriver/cookies.rb +8 -8
  15. data/lib/watir-webdriver/element_collection.rb +3 -4
  16. data/lib/watir-webdriver/elements/area.rb +0 -1
  17. data/lib/watir-webdriver/elements/button.rb +0 -1
  18. data/lib/watir-webdriver/elements/checkbox.rb +2 -4
  19. data/lib/watir-webdriver/elements/element.rb +69 -45
  20. data/lib/watir-webdriver/elements/file_field.rb +2 -3
  21. data/lib/watir-webdriver/elements/font.rb +2 -2
  22. data/lib/watir-webdriver/elements/form.rb +0 -1
  23. data/lib/watir-webdriver/elements/hidden.rb +2 -3
  24. data/lib/watir-webdriver/elements/html_elements.rb +2282 -0
  25. data/lib/watir-webdriver/elements/iframe.rb +6 -7
  26. data/lib/watir-webdriver/elements/image.rb +0 -1
  27. data/lib/watir-webdriver/elements/input.rb +0 -1
  28. data/lib/watir-webdriver/elements/link.rb +0 -1
  29. data/lib/watir-webdriver/elements/option.rb +3 -4
  30. data/lib/watir-webdriver/elements/radio.rb +2 -3
  31. data/lib/watir-webdriver/elements/select.rb +0 -1
  32. data/lib/watir-webdriver/elements/svg_elements.rb +787 -0
  33. data/lib/watir-webdriver/elements/table.rb +0 -2
  34. data/lib/watir-webdriver/elements/table_section.rb +1 -1
  35. data/lib/watir-webdriver/elements/text_field.rb +2 -3
  36. data/lib/watir-webdriver/exception.rb +0 -2
  37. data/lib/watir-webdriver/extensions/nokogiri.rb +1 -1
  38. data/lib/watir-webdriver/generator.rb +3 -0
  39. data/lib/watir-webdriver/generator/base.rb +11 -0
  40. data/lib/watir-webdriver/{html → generator/base}/generator.rb +23 -33
  41. data/lib/watir-webdriver/{html → generator/base}/idl_sorter.rb +3 -5
  42. data/lib/watir-webdriver/{html → generator/base}/spec_extractor.rb +15 -41
  43. data/lib/watir-webdriver/generator/base/util.rb +21 -0
  44. data/lib/watir-webdriver/{html → generator/base}/visitor.rb +15 -15
  45. data/lib/watir-webdriver/{html.rb → generator/html.rb} +3 -11
  46. data/lib/watir-webdriver/generator/html/generator.rb +36 -0
  47. data/lib/watir-webdriver/generator/html/spec_extractor.rb +50 -0
  48. data/lib/watir-webdriver/generator/html/visitor.rb +21 -0
  49. data/lib/watir-webdriver/generator/svg.rb +7 -0
  50. data/lib/watir-webdriver/generator/svg/generator.rb +38 -0
  51. data/lib/watir-webdriver/generator/svg/spec_extractor.rb +46 -0
  52. data/lib/watir-webdriver/generator/svg/visitor.rb +21 -0
  53. data/lib/watir-webdriver/has_window.rb +3 -3
  54. data/lib/watir-webdriver/locators/button_locator.rb +7 -2
  55. data/lib/watir-webdriver/locators/child_cell_locator.rb +1 -1
  56. data/lib/watir-webdriver/locators/child_row_locator.rb +1 -1
  57. data/lib/watir-webdriver/locators/element_locator.rb +44 -9
  58. data/lib/watir-webdriver/locators/text_area_locator.rb +4 -0
  59. data/lib/watir-webdriver/locators/text_field_locator.rb +7 -2
  60. data/lib/watir-webdriver/screenshot.rb +0 -1
  61. data/lib/watir-webdriver/version.rb +1 -1
  62. data/lib/watir-webdriver/wait.rb +10 -11
  63. data/lib/watir-webdriver/window.rb +5 -5
  64. data/lib/watir-webdriver/xpath_support.rb +0 -1
  65. data/spec/always_locate_spec.rb +4 -4
  66. data/spec/browser_spec.rb +3 -3
  67. data/spec/click_spec.rb +11 -4
  68. data/spec/container_spec.rb +2 -2
  69. data/spec/element_locator_spec.rb +145 -84
  70. data/spec/element_spec.rb +29 -16
  71. data/spec/html/clicks.html +3 -0
  72. data/spec/html/removed_element.html +7 -0
  73. data/spec/implementation.rb +5 -5
  74. data/spec/input_spec.rb +1 -1
  75. data/spec/spec_helper.rb +1 -2
  76. data/spec/special_chars_spec.rb +2 -2
  77. data/support/doctest_helper.rb +4 -4
  78. data/support/version_differ.rb +2 -2
  79. data/watir-webdriver.gemspec +3 -3
  80. metadata +27 -17
  81. data/lib/watir-webdriver/elements/generated.rb +0 -3106
  82. data/lib/watir-webdriver/html/util.rb +0 -22
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Watir
4
2
  class Table < HTMLElement
5
3
  include RowContainer
@@ -9,7 +9,7 @@ module Watir
9
9
  #
10
10
 
11
11
  def [](idx)
12
- row(:index => idx)
12
+ row(index: idx)
13
13
  end
14
14
  end # TableSection
15
15
  end # Watir
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Watir
3
2
  class TextField < Input
4
3
  include UserEditable
@@ -22,11 +21,11 @@ module Watir
22
21
 
23
22
  module Container
24
23
  def text_field(*args)
25
- TextField.new(self, extract_selector(args).merge(:tag_name => "input"))
24
+ TextField.new(self, extract_selector(args).merge(tag_name: "input"))
26
25
  end
27
26
 
28
27
  def text_fields(*args)
29
- TextFieldCollection.new(self, extract_selector(args).merge(:tag_name => "input"))
28
+ TextFieldCollection.new(self, extract_selector(args).merge(tag_name: "input"))
30
29
  end
31
30
  end # Container
32
31
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Watir
4
2
  module Exception
5
3
  class Error < StandardError; end
@@ -4,7 +4,7 @@ module Watir
4
4
  class Browser
5
5
 
6
6
  def text
7
- doc = Nokogiri::HTML(body(:index => 0).html)
7
+ doc = Nokogiri::HTML(body(index: 0).html)
8
8
  doc.css("script").remove # encoding bug in older libxml?
9
9
 
10
10
  doc.inner_text
@@ -0,0 +1,3 @@
1
+ require "watir-webdriver/generator/base"
2
+ require "watir-webdriver/generator/html"
3
+ require "watir-webdriver/generator/svg"
@@ -0,0 +1,11 @@
1
+ require "nokogiri"
2
+ require "open-uri"
3
+ require "pp"
4
+ require "webidl"
5
+ require "active_support/inflector"
6
+
7
+ require "watir-webdriver/generator/base/generator"
8
+ require "watir-webdriver/generator/base/idl_sorter"
9
+ require "watir-webdriver/generator/base/spec_extractor"
10
+ require "watir-webdriver/generator/base/util"
11
+ require "watir-webdriver/generator/base/visitor"
@@ -1,10 +1,6 @@
1
- # encoding: utf-8
2
-
3
1
  module Watir
4
- module HTML
5
- class Generator
6
-
7
- IGNORED_ATTRIBUTES = %w(cells elements hash rows span text)
2
+ module Generator
3
+ class Base
8
4
 
9
5
  def generate(spec_url, io = StringIO.new)
10
6
  @spec_url, @io = spec_url, io
@@ -27,11 +23,11 @@ module Watir
27
23
  end
28
24
 
29
25
  def visitor
30
- @visitor ||= Visitor.new
26
+ @visitor ||= visitor_class.new
31
27
  end
32
28
 
33
29
  def extractor
34
- @extractor ||= SpecExtractor.new(@spec_url)
30
+ @extractor ||= extractor_class.new(@spec_url)
35
31
  end
36
32
 
37
33
  def extract_spec
@@ -44,20 +40,21 @@ module Watir
44
40
  end
45
41
 
46
42
  def cleanup_spec
47
- # ignore the link element for now
48
- @tag2interfaces.delete("link")
49
- @sorted_interfaces.reject! { |intf| intf.name == "HTMLLinkElement" }
50
- # frame is implemented manually, see https://github.com/watir/watir-webdriver/issues/204
51
- @sorted_interfaces.reject! { |intf| intf.name == "HTMLFrameElement" }
43
+ ignored_tags.each do |tag|
44
+ @tag2interfaces.delete(tag)
45
+ end
46
+
47
+ ignored_interfaces.each do |interface|
48
+ @sorted_interfaces.reject! { |intf| intf.name == interface }
49
+ end
52
50
 
53
- # cleanup attributes
54
51
  @sorted_interfaces.each do |intf|
55
- intf.members.delete_if { |member| IGNORED_ATTRIBUTES.include?(member.name) }
52
+ intf.members.delete_if { |member| ignored_attributes.include?(member.name) }
56
53
  end
57
54
  end
58
55
 
59
56
  def write_header
60
- @io.puts "# Autogenerated from the HTML5 specification. Edits may be lost."
57
+ @io.puts "# Autogenerated from #{generator_implementation} specification. Edits may be lost."
61
58
  @io.puts "module Watir"
62
59
  end
63
60
 
@@ -67,42 +64,35 @@ module Watir
67
64
  unless interface.empty?
68
65
  interface.gsub!(/^\s+\n/, '') # remove empty lines
69
66
  @io.puts indent(interface)
67
+ @io.puts "\n"
70
68
  end
71
69
  end
72
70
  end
73
71
 
74
72
  def write_container_methods
75
- @io.puts "\n\n"
73
+ @io.puts "\n"
76
74
  @io.puts indent("module Container")
77
75
 
78
76
  @tag2interfaces.sort.each do |tag, interfaces|
79
- raise "multiple interfaces for tag #{tag.inspect}" unless interfaces.map { |e| e.name }.uniq.size == 1
77
+ raise "multiple interfaces for tag #{tag.inspect}" if interfaces.map(&:name).uniq.size != 1
80
78
 
81
79
  tag_string = tag.inspect
82
- singular = Util.paramify(tag)
80
+ singular = Util.paramify(visitor.classify_regexp, tag)
83
81
  plural = singular.pluralize
84
- element_class = Util.classify(interfaces.first.name)
82
+ element_class = Util.classify(visitor.classify_regexp, interfaces.first.name)
85
83
  collection_class = "#{element_class}Collection"
86
84
 
87
85
  # visitor.visit_tag(tag, interfaces.first.name) !?
88
- @io.puts indent(<<-CODE, 3)
86
+ @io.puts indent(<<-CODE, 2)
89
87
 
90
- #
91
88
  # @return [#{element_class}]
92
- #
93
-
94
89
  def #{singular}(*args)
95
- #{element_class}.new(self, extract_selector(args).merge(:tag_name => #{tag_string}))
90
+ #{element_class}.new(self, extract_selector(args).merge(tag_name: #{tag_string}))
96
91
  end
97
-
98
- #
99
92
  # @return [#{collection_class}]
100
- #
101
-
102
93
  def #{plural}(*args)
103
- #{collection_class}.new(self, extract_selector(args).merge(:tag_name => #{tag_string}))
94
+ #{collection_class}.new(self, extract_selector(args).merge(tag_name: #{tag_string}))
104
95
  end
105
-
106
96
  Watir.tag_to_class[#{tag.to_sym.inspect}] = #{element_class}
107
97
 
108
98
  CODE
@@ -120,6 +110,6 @@ CODE
120
110
  code.split("\n").map { |line| line.empty? ? line : indent_string + line }.join("\n")
121
111
  end
122
112
 
123
- end # Generator
124
- end # HTML5
113
+ end # Base
114
+ end # Generator
125
115
  end # Watir
@@ -1,10 +1,8 @@
1
- # encoding: utf-8
2
-
3
1
  require 'tsort'
4
2
 
5
3
  module Watir
6
- module HTML
7
- class IDLSorter
4
+ module Generator
5
+ class Base::IDLSorter
8
6
  include TSort
9
7
 
10
8
  def initialize(interfaces)
@@ -45,5 +43,5 @@ module Watir
45
43
  end
46
44
 
47
45
  end # IDLSorter
48
- end # HTML
46
+ end # Generator
49
47
  end # Watir
@@ -1,11 +1,10 @@
1
- # encoding: utf-8
2
-
3
1
  module Watir
4
- module HTML
5
- class SpecExtractor
2
+ module Generator
3
+ class Base::SpecExtractor
6
4
 
7
- class InterfaceNotFound < StandardError
8
- end
5
+ IDL_SELECTOR = "//pre[@class='idl']"
6
+
7
+ class InterfaceNotFound < StandardError; end
9
8
 
10
9
  def initialize(uri)
11
10
  @uri = uri
@@ -15,6 +14,7 @@ module Watir
15
14
  download_and_parse
16
15
  extract_idl_parts
17
16
  extract_interface_map
17
+ drop_issued_interfaces
18
18
  build_result
19
19
  rescue
20
20
  p errors
@@ -53,7 +53,7 @@ module Watir
53
53
  end
54
54
 
55
55
  def extract_idl_parts
56
- parsed = @doc.search("//pre[@class='idl']").map { |e| parse_idl(e.inner_text) }.compact
56
+ parsed = @doc.search(IDL_SELECTOR).map { |e| parse_idl(e.inner_text) }.compact
57
57
 
58
58
  implements = []
59
59
  @interfaces = []
@@ -73,43 +73,17 @@ module Watir
73
73
  end
74
74
 
75
75
  def extract_interface_map
76
- # http://www.whatwg.org/specs/web-apps/current-work/#elements-1
77
- table = @doc.search("//h3[@id='elements-3']/following-sibling::table[1]").first
78
- table or raise "could not find elements-3 table"
79
-
80
- @interface_map = {}
81
-
82
- parse_table(table).each do |row|
83
- row['Element'].split(", ").each { |tag| @interface_map[tag] = row['Interface'] }
84
- end
76
+ raise NotImplementedError
85
77
  end
86
78
 
87
- def build_result
88
- # tag name => Interface instance(s)
89
- result = {}
90
-
91
- @interface_map.each do |tag, interface|
92
- result[tag] = fetch_interface(interface)
79
+ def drop_issued_interfaces
80
+ @interface_map.delete_if do |_, interface|
81
+ issued_interfaces.include?(interface)
93
82
  end
94
-
95
- # missing from the elements-1 table
96
- result['frameset'] = fetch_interface('HTMLFrameSetElement')
97
-
98
- result
99
83
  end
100
84
 
101
- def parse_table(table)
102
- headers = table.css("thead th").map { |e| e.inner_text.strip }
103
-
104
- table.css("tbody tr").map do |row|
105
- result = {}
106
-
107
- row.css("th, td").each_with_index do |node, idx|
108
- result[headers[idx]] = node.inner_text.strip
109
- end
110
-
111
- result
112
- end
85
+ def build_result
86
+ raise NotImplementedError
113
87
  end
114
88
 
115
89
  def parse_idl(str)
@@ -156,9 +130,9 @@ module Watir
156
130
  end
157
131
 
158
132
  def sorter
159
- @idl_sorter ||= IDLSorter.new(@interfaces)
133
+ @idl_sorter ||= Base::IDLSorter.new(@interfaces)
160
134
  end
161
135
 
162
136
  end # SpecExtractor
163
- end # HTML
137
+ end # Generator
164
138
  end # Watir
@@ -0,0 +1,21 @@
1
+ module Watir
2
+ module Generator
3
+ module Util
4
+
5
+ module_function
6
+
7
+ def classify(regexp, str)
8
+ if str =~ regexp
9
+ $1
10
+ else
11
+ str
12
+ end
13
+ end
14
+
15
+ def paramify(regexp, str)
16
+ classify(regexp, str).snake_case
17
+ end
18
+
19
+ end # Util
20
+ end # Generator
21
+ end # Watir
@@ -1,8 +1,6 @@
1
- # encoding: utf-8
2
-
3
1
  module Watir
4
- module HTML
5
- class Visitor < WebIDL::RubySexpVisitor
2
+ module Generator
3
+ class Base::Visitor < WebIDL::RubySexpVisitor
6
4
 
7
5
  def initialize
8
6
  super
@@ -23,10 +21,10 @@ module Watir
23
21
  parent = interface.inherits.first
24
22
 
25
23
  $stderr.puts name
26
- return unless name =~ /^HTML/ && name !~ /(Collection|Document)$/
24
+ return if name !~ interface_regexp || name =~ /(Collection|Document)$/
27
25
 
28
- if name == "HTMLElement"
29
- parent = 'Element'
26
+ if force_inheritance.keys.include?(name)
27
+ parent = force_inheritance[name]
30
28
  elsif parent
31
29
  @inheritance_map[name] ||= parent.name
32
30
  parent = parent.name
@@ -58,9 +56,9 @@ module Watir
58
56
  #
59
57
  # def visit_tag(tag_name, interface_name)
60
58
  # tag_string = tag.inspect
61
- # singular = Util.paramify(tag)
59
+ # singular = Util.paramify(classify_regexp, tag)
62
60
  # plural = singular.pluralize
63
- # element_class = Util.classify(interfaces.first.name)
61
+ # element_class = Util.classify(classify_regexp, interfaces.first.name)
64
62
  # collection_class = "#{element_class}Collection"
65
63
  #
66
64
  # [:defn,
@@ -82,7 +80,7 @@ module Watir
82
80
  private
83
81
 
84
82
  def element_class(name, attributes, parent)
85
- [:class, Util.classify(name), [:const, Util.classify(parent)],
83
+ [:class, Util.classify(classify_regexp, name), [:const, Util.classify(classify_regexp, parent)],
86
84
  *attribute_calls(attributes)
87
85
  ]
88
86
  end
@@ -97,7 +95,7 @@ module Watir
97
95
  def collection_class(name)
98
96
  return if @already_defined.include?(name)
99
97
  @already_defined << name
100
- name = Util.classify(name)
98
+ name = Util.classify(classify_regexp, name)
101
99
 
102
100
  [:class, "#{name}Collection", [:const, :ElementCollection],
103
101
  [:scope,
@@ -142,7 +140,8 @@ module Watir
142
140
  case type.name.to_s
143
141
  when 'DOMString', 'any'
144
142
  String
145
- when 'UnsignedLong', 'Long', 'Integer', 'Short', 'UnsignedShort'
143
+ when 'UnsignedLong', 'Long', 'Integer', 'Short', 'UnsignedShort',
144
+ 'SVGAnimatedLength'
146
145
  Fixnum
147
146
  when 'Float', /.*Double$/
148
147
  Float
@@ -152,8 +151,9 @@ module Watir
152
151
  'Any', 'TimedTrackArray', 'TimedTrack', 'TextTrackArray', 'TextTrack',
153
152
  /Media.+/, 'TextTrackKind', 'Function', /.*EventHandler$/,
154
153
  'Document', 'DocumentFragment', 'DOMTokenList', 'DOMSettableTokenList',
155
- 'DOMStringMap', 'HTMLPropertiesCollection', /HTML(.*)Element/, /HTML(.*)Collection/,
156
- 'CSSStyleDeclaration', /.+List$/, 'Date', 'Element'
154
+ 'DOMStringMap', 'HTMLPropertiesCollection', /HTML.*Element/, /HTML.*Collection/,
155
+ 'CSSStyleDeclaration', /.+List$/, 'Date', 'Element', /DOM.+ReadOnly/,
156
+ /SVGAnimated.+/, /SVG.*Element/, /SVG.*Collection/, 'SVGViewSpec'
157
157
  # probably completely wrong.
158
158
  String
159
159
  else
@@ -162,5 +162,5 @@ module Watir
162
162
  end
163
163
 
164
164
  end # Visitor
165
- end # Support
165
+ end # Generator
166
166
  end # Watir
@@ -1,9 +1,3 @@
1
- require "nokogiri"
2
- require "open-uri"
3
- require "pp"
4
- require "webidl"
5
- require "active_support/inflector"
6
-
7
1
  ActiveSupport::Inflector.inflections do |inflect|
8
2
  inflect.plural 'body', 'bodys'
9
3
  inflect.plural 'tbody', 'tbodys'
@@ -16,8 +10,6 @@ ActiveSupport::Inflector.inflections do |inflect|
16
10
  inflect.plural 'datalist', 'datalists'
17
11
  end
18
12
 
19
- require "watir-webdriver/html/util"
20
- require "watir-webdriver/html/visitor"
21
- require "watir-webdriver/html/idl_sorter"
22
- require "watir-webdriver/html/spec_extractor"
23
- require "watir-webdriver/html/generator"
13
+ require "watir-webdriver/generator/html/generator"
14
+ require "watir-webdriver/generator/html/spec_extractor"
15
+ require "watir-webdriver/generator/html/visitor"
@@ -0,0 +1,36 @@
1
+ module Watir
2
+ module Generator
3
+ class HTML < Base
4
+
5
+ private
6
+
7
+ def ignored_tags
8
+ # ignore the link element for now
9
+ %w(link)
10
+ end
11
+
12
+ def ignored_interfaces
13
+ ignored = ignored_tags.map { |tag| "HTML#{tag.capitalize}Element" }
14
+ # frame is implemented manually, see https://github.com/watir/watir-webdriver/issues/204
15
+ ignored << 'HTMLFrameElement'
16
+ end
17
+
18
+ def ignored_attributes
19
+ %w(cells elements hash rows span text)
20
+ end
21
+
22
+ def generator_implementation
23
+ 'HTML'
24
+ end
25
+
26
+ def visitor_class
27
+ HTML::Visitor
28
+ end
29
+
30
+ def extractor_class
31
+ HTML::SpecExtractor
32
+ end
33
+
34
+ end # Generator
35
+ end # HTML
36
+ end # Watir