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
@@ -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
|
@@ -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)
|
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
|
12
|
+
Watir.element_class_for(e.tag_name).new(self, :element => e)
|
13
13
|
rescue WebDriver::Error::NoSuchElementError
|
14
|
-
|
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
|
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.
|
1
|
+
require File.expand_path 'watirspec/spec_helper', File.dirname(__FILE__)
|
2
2
|
|
3
|
-
|
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__)))
|