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.
- data/Rakefile +53 -31
- data/VERSION +1 -1
- data/lib/watir-webdriver.rb +6 -8
- data/lib/watir-webdriver/attribute_helper.rb +121 -0
- data/lib/watir-webdriver/browser.rb +13 -6
- data/lib/watir-webdriver/collections/element_collection.rb +21 -15
- data/lib/watir-webdriver/collections/table_row_collection.rb +11 -0
- data/lib/watir-webdriver/container.rb +17 -11
- data/lib/watir-webdriver/element.rb +201 -0
- data/lib/watir-webdriver/elements/button.rb +19 -2
- data/lib/watir-webdriver/elements/checkbox.rb +24 -4
- data/lib/watir-webdriver/elements/file_field.rb +24 -4
- data/lib/watir-webdriver/elements/font.rb +10 -11
- data/lib/watir-webdriver/elements/frame.rb +11 -3
- data/lib/watir-webdriver/elements/generated.rb +2491 -1313
- data/lib/watir-webdriver/elements/hidden.rb +16 -5
- data/lib/watir-webdriver/elements/input.rb +44 -5
- data/lib/watir-webdriver/elements/link.rb +6 -8
- data/lib/watir-webdriver/elements/radio.rb +25 -6
- data/lib/watir-webdriver/elements/{select_list.rb → select.rb} +8 -9
- data/lib/watir-webdriver/elements/text_field.rb +32 -3
- data/lib/watir-webdriver/html.rb +18 -0
- data/lib/watir-webdriver/html/generator.rb +112 -0
- data/lib/watir-webdriver/html/idl_sorter.rb +49 -0
- data/lib/watir-webdriver/html/spec_extractor.rb +111 -0
- data/lib/watir-webdriver/html/util.rb +31 -0
- data/lib/watir-webdriver/html/visitor.rb +186 -0
- data/lib/watir-webdriver/locators/element_locator.rb +4 -0
- data/lib/watir-webdriver/locators/text_field_locator.rb +2 -2
- data/lib/watir-webdriver/xpath_support.rb +3 -5
- data/lib/yard/handlers/watir.rb +57 -0
- data/spec/{base_element_spec.rb → element_spec.rb} +3 -2
- data/spec/input_spec.rb +65 -0
- data/spec/spec_helper.rb +9 -2
- data/spec/watirspec/area_spec.rb +9 -13
- data/spec/watirspec/areas_spec.rb +7 -1
- data/spec/watirspec/browser_spec.rb +68 -72
- data/spec/watirspec/button_spec.rb +16 -9
- data/spec/watirspec/buttons_spec.rb +11 -9
- data/spec/watirspec/checkbox_spec.rb +1 -1
- data/spec/watirspec/checkboxes_spec.rb +7 -1
- data/spec/watirspec/collections_spec.rb +18 -0
- data/spec/watirspec/dd_spec.rb +1 -1
- data/spec/watirspec/dds_spec.rb +7 -1
- data/spec/watirspec/del_spec.rb +141 -0
- data/spec/watirspec/dels_spec.rb +37 -0
- data/spec/watirspec/div_spec.rb +6 -22
- data/spec/watirspec/divs_spec.rb +8 -2
- data/spec/watirspec/dl_spec.rb +1 -1
- data/spec/watirspec/dls_spec.rb +7 -1
- data/spec/watirspec/dt_spec.rb +1 -1
- data/spec/watirspec/dts_spec.rb +7 -1
- data/spec/watirspec/element_spec.rb +11 -20
- data/spec/watirspec/em_spec.rb +1 -1
- data/spec/watirspec/ems_spec.rb +7 -1
- data/spec/watirspec/filefield_spec.rb +8 -11
- data/spec/watirspec/filefields_spec.rb +7 -1
- data/spec/watirspec/font_spec.rb +2 -2
- data/spec/watirspec/form_spec.rb +10 -18
- data/spec/watirspec/forms_spec.rb +7 -1
- data/spec/watirspec/frame_spec.rb +69 -73
- data/spec/watirspec/frames_spec.rb +15 -2
- data/spec/watirspec/hidden_spec.rb +1 -1
- data/spec/watirspec/hiddens_spec.rb +7 -1
- data/spec/watirspec/hn_spec.rb +1 -1
- data/spec/watirspec/hns_spec.rb +23 -27
- data/spec/watirspec/image_spec.rb +9 -15
- data/spec/watirspec/images_spec.rb +7 -1
- data/spec/watirspec/ins_spec.rb +142 -0
- data/spec/watirspec/inses_spec.rb +37 -0
- data/spec/watirspec/label_spec.rb +1 -1
- data/spec/watirspec/labels_spec.rb +7 -1
- data/spec/watirspec/li_spec.rb +1 -1
- data/spec/watirspec/lib/guards.rb +12 -12
- data/spec/watirspec/lib/implementation.rb +48 -0
- data/spec/watirspec/lib/watirspec.rb +17 -12
- data/spec/watirspec/link_spec.rb +6 -11
- data/spec/watirspec/links_spec.rb +1 -1
- data/spec/watirspec/lis_spec.rb +7 -1
- data/spec/watirspec/map_spec.rb +1 -1
- data/spec/watirspec/maps_spec.rb +7 -1
- data/spec/watirspec/meta_spec.rb +13 -15
- data/spec/watirspec/metas_spec.rb +6 -1
- data/spec/watirspec/ol_spec.rb +57 -59
- data/spec/watirspec/ols_spec.rb +10 -4
- data/spec/watirspec/option_spec.rb +50 -83
- data/spec/watirspec/p_spec.rb +1 -1
- data/spec/watirspec/pre_spec.rb +1 -1
- data/spec/watirspec/pres_spec.rb +7 -1
- data/spec/watirspec/ps_spec.rb +7 -1
- data/spec/watirspec/radio_spec.rb +9 -11
- data/spec/watirspec/radios_spec.rb +1 -1
- data/spec/watirspec/select_list_spec.rb +27 -40
- data/spec/watirspec/select_lists_spec.rb +1 -1
- data/spec/watirspec/span_spec.rb +1 -1
- data/spec/watirspec/spans_spec.rb +7 -1
- data/spec/watirspec/spec_helper.rb +1 -0
- data/spec/watirspec/strong_spec.rb +1 -1
- data/spec/watirspec/strongs_spec.rb +7 -1
- data/spec/watirspec/table_bodies_spec.rb +22 -10
- data/spec/watirspec/table_body_spec.rb +33 -40
- data/spec/watirspec/table_cell_spec.rb +1 -1
- data/spec/watirspec/table_cells_spec.rb +36 -15
- data/spec/watirspec/table_footer_spec.rb +43 -40
- data/spec/watirspec/table_footers_spec.rb +35 -19
- data/spec/watirspec/table_header_spec.rb +44 -39
- data/spec/watirspec/table_headers_spec.rb +37 -19
- data/spec/watirspec/table_row_spec.rb +13 -9
- data/spec/watirspec/table_rows_spec.rb +16 -6
- data/spec/watirspec/table_spec.rb +83 -62
- data/spec/watirspec/tables_spec.rb +7 -1
- data/spec/watirspec/text_field_spec.rb +4 -6
- data/spec/watirspec/text_fields_spec.rb +1 -1
- data/spec/watirspec/ul_spec.rb +1 -1
- data/spec/watirspec/uls_spec.rb +25 -22
- data/support/html5.html +89235 -0
- data/watir-webdriver.gemspec +31 -21
- metadata +52 -23
- data/TODO +0 -15
- data/lib/watir-webdriver/base_element.rb +0 -361
- data/lib/watir-webdriver/collections/buttons_collection.rb +0 -15
- data/lib/watir-webdriver/collections/table_rows_collection.rb +0 -16
- data/lib/watir-webdriver/collections/text_fields_collection.rb +0 -15
- data/lib/watir-webdriver/elements/headings.rb +0 -48
- data/support/html5/html5.idl +0 -1274
- data/support/html5/old/html5.idl +0 -962
- data/support/html5/old/html5_extras.idl +0 -145
- data/support/html5/watir_visitor.rb +0 -173
- 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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
84
|
+
#
|
85
|
+
# @return [Watir::FileField]
|
86
|
+
#
|
87
|
+
|
88
|
+
def to_file_field
|
50
89
|
assert_exists
|
51
|
-
|
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
|
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
|
-
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
30
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|