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
@@ -1,13 +1,24 @@
1
1
  # encoding: utf-8
2
2
  module Watir
3
3
  class Hidden < Input
4
- identifier :type => 'hidden'
5
-
6
- container_method :hidden
7
- collection_method :hiddens
8
-
9
4
  def visible?
10
5
  false
11
6
  end
12
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
13
24
  end
@@ -4,6 +4,20 @@ module Watir
4
4
 
5
5
  alias_method :readonly?, :read_only?
6
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
+
7
21
  def enabled?
8
22
  !disabled?
9
23
  end
@@ -31,24 +45,49 @@ module Watir
31
45
  # 'cast' the returned Input instance to one of the subclasses
32
46
  #
33
47
 
48
+ #
49
+ # @return [Watir::CheckBox]
50
+ #
51
+
34
52
  def to_checkbox
35
53
  assert_exists
36
- Watir::CheckBox.new(@parent, :element, @element)
54
+ CheckBox.from(@parent, @element)
37
55
  end
38
56
 
57
+ #
58
+ # @return [Watir::Radio]
59
+ #
60
+
39
61
  def to_radio
40
62
  assert_exists
41
- Watir::Radio.new(@parent, :element, @element)
63
+ Radio.from(@parent, @element)
42
64
  end
43
65
 
66
+ #
67
+ # @return [Watir::Button]
68
+ #
69
+
44
70
  def to_button
45
71
  assert_exists
46
- Watir::Button.new(@parent, :element, @element)
72
+ Button.from(@parent, @element)
73
+ end
74
+
75
+ #
76
+ # @return [Watir::TextField]
77
+ #
78
+
79
+ def to_text_field
80
+ assert_exists
81
+ TextField.from(@parent, @element)
47
82
  end
48
83
 
49
- def to_select_list
84
+ #
85
+ # @return [Watir::FileField]
86
+ #
87
+
88
+ def to_file_field
50
89
  assert_exists
51
- Watir::SelectList.new(@parent, :element, @element)
90
+ FileField.from(@parent, @element)
52
91
  end
53
92
 
54
93
  end # Input
@@ -1,13 +1,11 @@
1
1
  # encoding: utf-8
2
2
  module Watir
3
- class Link < Anchor
4
- default_selector.clear
5
-
6
- identifier :tag_name => 'a'
7
- container_method :link
8
- collection_method :links
9
-
3
+ class Anchor
10
4
  alias_method :url, :href # deprecate?
5
+ end # Anchor
11
6
 
12
- end # Link
7
+ module Container
8
+ alias_method :link, :a
9
+ alias_method :links, :as
10
+ end
13
11
  end # Watir
@@ -1,11 +1,13 @@
1
1
  # encoding: utf-8
2
2
  module Watir
3
3
  class Radio < Input
4
- identifier :type => 'radio'
5
-
6
- container_method :radio
7
- collection_method :radios
4
+ def self.from(parent, element)
5
+ if element.attribute(:type) != "radio"
6
+ raise TypeError, "expected type=radio for #{element.inspect}"
7
+ end
8
8
 
9
+ super
10
+ end
9
11
  #
10
12
  # Select this radio button.
11
13
  #
@@ -25,6 +27,23 @@ module Watir
25
27
  assert_exists
26
28
  @element.selected?
27
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
28
36
 
29
- end
30
- end
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
@@ -1,11 +1,8 @@
1
1
  # encoding: utf-8
2
2
  module Watir
3
- class SelectList < Select
3
+ class Select < HTMLElement
4
4
  include Watir::Exception
5
5
 
6
- container_method :select_list
7
- collection_method :select_lists
8
-
9
6
  #
10
7
  # Returns true if this element is enabled
11
8
  #
@@ -59,7 +56,7 @@ module Watir
59
56
  #
60
57
 
61
58
  def select(str_or_rx)
62
- select_by :text, str_or_rx, multiple?
59
+ select_by :text, str_or_rx, multiple?
63
60
  end
64
61
 
65
62
  #
@@ -103,9 +100,7 @@ module Watir
103
100
  #
104
101
 
105
102
  def value
106
- o = options.find { |e| e.selected? }
107
- return if o.nil?
108
-
103
+ o = options.find { |e| e.selected? } || return
109
104
  o.value
110
105
  end
111
106
 
@@ -215,6 +210,10 @@ module Watir
215
210
 
216
211
  ''
217
212
  end
213
+ end # Select
218
214
 
219
- end # SelectList
215
+ module Container
216
+ alias_method :select_list, :select
217
+ alias_method :select_lists, :selects
218
+ end # Container
220
219
  end # Watir
@@ -4,13 +4,20 @@ module Watir
4
4
 
5
5
  attributes Watir::TextArea.typed_attributes
6
6
 
7
+ def self.from(parent, element)
8
+ type = element.attribute(:type)
9
+
10
+ if TextFieldLocator::NON_TEXT_TYPES.include?(type)
11
+ raise TypeError, "expected type != #{type} for #{element.inspect}"
12
+ end
13
+
14
+ super
15
+ end
16
+
7
17
  # hacky, but we want Input#type here, which was overriden by TextArea's attributes
8
18
  # so we're *overwriting* that method definition here
9
19
  def type; super; end
10
20
 
11
- container_method :text_field
12
- collection_method :text_fields
13
-
14
21
  def inspect
15
22
  '#<%s:0x%x located=%s selector=%s>' % [self.class, hash*2, !!@element, selector_string]
16
23
  end
@@ -75,4 +82,26 @@ module Watir
75
82
  s
76
83
  end
77
84
  end
85
+
86
+ module Container
87
+ def text_field(*args)
88
+ TextField.new(self, extract_selector(args).merge(:tag_name => "input"))
89
+ end
90
+
91
+ def text_fields(*args)
92
+ TextFieldCollection.new(self, extract_selector(args).merge(:tag_name => "input"))
93
+ end
94
+ end # Container
95
+
96
+ class TextFieldCollection < InputCollection
97
+ private
98
+
99
+ def locator_class
100
+ TextFieldLocator
101
+ end
102
+
103
+ def element_class
104
+ TextField
105
+ end
106
+ end # TextFieldCollection
78
107
  end
@@ -0,0 +1,18 @@
1
+ require "nokogiri"
2
+ require "open-uri"
3
+ require "pp"
4
+ require "webidl"
5
+ require "active_support/inflector"
6
+
7
+ ActiveSupport::Inflector.inflections do |inflect|
8
+ inflect.irregular 'body', 'bodys'
9
+ inflect.irregular 'tbody', 'tbodys'
10
+ inflect.irregular 'canvas', 'canvases'
11
+ inflect.irregular 'ins', 'inses'
12
+ end
13
+
14
+ require "watir-webdriver/html/util"
15
+ require "watir-webdriver/html/visitor"
16
+ require "watir-webdriver/html/idl_sorter"
17
+ require "watir-webdriver/html/spec_extractor"
18
+ require "watir-webdriver/html/generator"
@@ -0,0 +1,112 @@
1
+ # encoding: utf-8
2
+
3
+ module Watir
4
+ module HTML
5
+ class Generator
6
+
7
+ def generate(spec_url, io = StringIO.new)
8
+ @spec_url, @io = spec_url, io
9
+
10
+ extract_spec
11
+ cleanup_spec
12
+
13
+ write_header
14
+ write_class_defs
15
+ write_container_methods
16
+ write_footer
17
+
18
+ io
19
+ end
20
+
21
+ private
22
+
23
+ def generator
24
+ @generator ||= WebIDL::Generator.new(visitor)
25
+ end
26
+
27
+ def visitor
28
+ @visitor ||= Visitor.new
29
+ end
30
+
31
+ def extractor
32
+ @extractor ||= SpecExtractor.new(@spec_url)
33
+ end
34
+
35
+ def extract_spec
36
+ @tag2interfaces = extractor.process
37
+ @sorted_interfaces = extractor.sorted_interfaces
38
+
39
+ if extractor.errors.any?
40
+ raise "error extracting spec: #{extractor.errors.join("\n")}"
41
+ end
42
+ end
43
+
44
+ def cleanup_spec
45
+ # ignore the link element for now
46
+ @tag2interfaces.delete("link")
47
+ @sorted_interfaces.reject! { |intf| intf.name == "HTMLLinkElement" }
48
+ end
49
+
50
+ def write_header
51
+ @io.puts "# Autogenerated from the HTML5 specification. Edits may be lost."
52
+ @io.puts "module Watir"
53
+ end
54
+
55
+ def write_class_defs
56
+ @sorted_interfaces.each do |interface|
57
+ @io.puts indent(generator.generate(interface))
58
+ end
59
+ end
60
+
61
+
62
+ def write_container_methods
63
+ @io.puts indent("module Container")
64
+
65
+ @tag2interfaces.sort.each do |tag, interfaces|
66
+ raise "multiple interfaces for tag #{tag.inspect}" unless interfaces.map { |e| e.name }.uniq.size == 1
67
+
68
+ tag_string = tag.inspect
69
+ singular = Util.paramify(tag)
70
+ plural = singular.pluralize
71
+ element_class = Util.classify(interfaces.first.name)
72
+ collection_class = "#{element_class}Collection"
73
+
74
+ # visitor.visit_tag(tag, interfaces.first.name) !?
75
+ @io.puts indent(<<-CODE, 3)
76
+ #
77
+ # @return [#{element_class}]
78
+ #
79
+
80
+ def #{singular}(*args)
81
+ #{element_class}.new(self, extract_selector(args).merge(:tag_name => #{tag_string}))
82
+ end
83
+
84
+ #
85
+ # @return [#{collection_class}]
86
+ #
87
+
88
+ def #{plural}(*args)
89
+ #{collection_class}.new(self, extract_selector(args).merge(:tag_name => #{tag_string}))
90
+ end
91
+
92
+ Watir.tag_to_class[#{tag.to_sym.inspect}] = #{element_class}
93
+
94
+ CODE
95
+ end
96
+
97
+ @io.puts indent("end # Container")
98
+ end
99
+
100
+ def write_footer
101
+ @io.puts "end # Watir"
102
+ end
103
+
104
+
105
+ def indent(code, indent = 1)
106
+ indent_string = " "*indent
107
+ code.split("\n").map { |line| indent_string + line }.join("\n")
108
+ end
109
+
110
+ end # Generator
111
+ end # HTML5
112
+ end # Watir
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'tsort'
4
+
5
+ module Watir
6
+ module HTML
7
+ class IDLSorter
8
+ include TSort
9
+
10
+ def initialize(interfaces)
11
+ @interfaces = {}
12
+
13
+ interfaces.each do |interface|
14
+ @interfaces[interface.name] ||= []
15
+ interface.inherits.each do |inherit|
16
+ (@interfaces[inherit.name] ||= []) << interface.name
17
+ end
18
+ end
19
+ end
20
+
21
+ def print
22
+ @visited = []
23
+ sort.each { |node| print_node(node) }
24
+ end
25
+
26
+ def sort
27
+ tsort.reverse
28
+ end
29
+
30
+ def tsort_each_node(&blk)
31
+ @interfaces.each_key(&blk)
32
+ end
33
+
34
+ def tsort_each_child(node, &blk)
35
+ @interfaces[node].each(&blk)
36
+ end
37
+
38
+ private
39
+
40
+ def print_node(node, indent = 0)
41
+ return if @visited.include?(node)
42
+ @visited << node
43
+ puts " "*indent + node
44
+ tsort_each_child(node) { |child| print_node(child, indent + 2)}
45
+ end
46
+
47
+ end # IDLSorter
48
+ end # HTML
49
+ end # Watir