watir 6.12.0 → 6.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.document +2 -3
- data/CHANGES.md +9 -0
- data/README.md +19 -28
- data/lib/watir.rb +1 -0
- data/lib/watir/adjacent.rb +2 -2
- data/lib/watir/browser.rb +1 -1
- data/lib/watir/element_collection.rb +3 -1
- data/lib/watir/elements/element.rb +6 -3
- data/lib/watir/elements/select.rb +2 -1
- data/lib/watir/generator/html/generator.rb +1 -1
- data/lib/watir/js_snippets/setText.js +3 -0
- data/lib/watir/locators/element/locator.rb +21 -11
- data/lib/watir/locators/element/selector_builder.rb +2 -1
- data/lib/watir/locators/row/selector_builder.rb +11 -5
- data/lib/watir/user_editable.rb +12 -1
- data/lib/watir/wait.rb +35 -4
- data/spec/watirspec/adjacent_spec.rb +22 -0
- data/spec/watirspec/browser_spec.rb +18 -16
- data/spec/watirspec/elements/collections_spec.rb +24 -0
- data/spec/watirspec/elements/div_spec.rb +8 -4
- data/spec/watirspec/elements/element_spec.rb +19 -3
- data/spec/watirspec/elements/text_field_spec.rb +0 -161
- data/spec/watirspec/html/forms_with_input_elements.html +2 -0
- data/spec/watirspec/html/nested_elements.html +11 -1
- data/spec/watirspec/html/wait.html +4 -2
- data/spec/watirspec/user_editable_spec.rb +202 -0
- data/spec/watirspec/wait_spec.rb +85 -0
- data/watir.gemspec +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee77498367fb399c13c754467a7e0b751cff3b3e
|
4
|
+
data.tar.gz: 38566fb0f06601dc54206268cc4904d184d193fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3538e96c26022ffc51d3a9e8bf3a40eedf4ac739001547059f015cc3d034b24c3dd9a99b3477a7a3c3125ee074edb94cdaa130f440ac8e5e6ff0c32f5f43de36
|
7
|
+
data.tar.gz: 480541837a063fa207523e68e32a72f6ad8d39dc18362d466c25adc410bf1686370e0a58b9fbf2e06dcbf4c03f4706ca93c55c486f0492795233086b45f5ce6d
|
data/.document
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
### 6.13.0 (2018-09-02)
|
2
|
+
|
3
|
+
* Allow wait methods to wait for values of any attribute
|
4
|
+
* Allow locating custom elements with adjacent methods
|
5
|
+
* Support how latest IEDrivers are handling stale elements
|
6
|
+
* Restore support for using of previously cached elements in collections
|
7
|
+
* Fix bug preventing clicking option when select list is not displayed
|
8
|
+
* Allow elements with content-editable attribute to use UserEditable module methods
|
9
|
+
|
1
10
|
### 6.12.0 (2018-07-24)
|
2
11
|
|
3
12
|
* Allow elements to be located with attributes that have underscores (thanks John Fitisoff)
|
data/README.md
CHANGED
@@ -17,21 +17,27 @@ require 'watir'
|
|
17
17
|
browser = Watir::Browser.new
|
18
18
|
|
19
19
|
browser.goto 'watir.com'
|
20
|
-
browser.link(text: '
|
20
|
+
browser.link(text: 'Guides').click
|
21
21
|
|
22
22
|
puts browser.title
|
23
|
-
# => '
|
23
|
+
# => 'Guides – Watir Project'
|
24
24
|
browser.close
|
25
25
|
```
|
26
26
|
|
27
|
-
##
|
27
|
+
## Using Watir
|
28
28
|
|
29
|
-
|
29
|
+
Everything you need is on the [Watir website](http://watir.com): news, guides, additional resources, support information and more.
|
30
|
+
|
31
|
+
If you are interested in contributing to the project or the ecosystem, continue reading this README.
|
32
|
+
|
33
|
+
## Implementation
|
34
|
+
|
35
|
+
The majority of element methods Watir provides is autogenerated from specifications.
|
30
36
|
This is done by extracting the IDL parts from the spec and processing them with the WebIDL gem (link below).
|
31
37
|
Currently supported specifications are:
|
32
38
|
|
33
|
-
* [HTML](https://www.
|
34
|
-
* [SVG](
|
39
|
+
* [HTML](https://www.w3.org/TR/2017/PR-html51-20170803/single-page.html) (`lib/watir/elements/html_elements.rb`)
|
40
|
+
* [SVG](https://www.w3.org/TR/2016/CR-SVG2-20160915/single-page.html) (`lib/watir/elements/svg_elements.rb`)
|
35
41
|
|
36
42
|
## Specs
|
37
43
|
|
@@ -65,7 +71,7 @@ After initialized, just follow the instructions to customize Watir implementatio
|
|
65
71
|
|
66
72
|
Specs specific to Watir are found in `spec/*_spec.rb`, with watirspec in `spec/watirspec/`.
|
67
73
|
|
68
|
-
|
74
|
+
### Doctests
|
69
75
|
|
70
76
|
Watir uses [yard-doctest](https://github.com/p0deje/yard-doctest) for testing documentation examples.
|
71
77
|
|
@@ -73,31 +79,16 @@ Watir uses [yard-doctest](https://github.com/p0deje/yard-doctest) for testing do
|
|
73
79
|
rake yard:doctest
|
74
80
|
```
|
75
81
|
|
76
|
-
## API Documentation
|
77
|
-
|
78
|
-
* http://rdoc.info/gems/watir/ (updated on every release)
|
79
|
-
|
80
|
-
## See Also
|
81
|
-
|
82
|
-
* http://watir.github.io
|
83
|
-
* http://github.com/jarib/webidl
|
84
|
-
* http://github.com/watir/watirspec
|
85
|
-
* https://github.com/seleniumhq/selenium
|
86
|
-
|
87
|
-
## Dependencies
|
88
|
-
|
89
|
-
* selenium-webdriver
|
90
|
-
* rack (for watirspec)
|
91
|
-
|
92
82
|
## Note on Patches/Pull Requests
|
93
83
|
|
94
84
|
* Fork the project.
|
85
|
+
* Clone onto your local machine.
|
86
|
+
* Create a new feature branch (bonus points for good names).
|
95
87
|
* Make your feature addition or bug fix.
|
96
|
-
* Add tests for it. This is important so
|
97
|
-
|
98
|
-
*
|
99
|
-
|
100
|
-
* Send me a pull request. Bonus points for topic branches.
|
88
|
+
* Add tests for it. This is important so we don't unintentionally break it in a future version.
|
89
|
+
* Commit, do not change Rakefile, gemspec, or CHANGES files.
|
90
|
+
* Push to your forked repository.
|
91
|
+
* Send a pull request.
|
101
92
|
|
102
93
|
## Copyright
|
103
94
|
|
data/lib/watir.rb
CHANGED
data/lib/watir/adjacent.rb
CHANGED
@@ -111,11 +111,11 @@ module Watir
|
|
111
111
|
plural = opt.delete(:plural)
|
112
112
|
opt[:index] ||= 0 unless plural || opt.values.any? { |e| e.is_a? Regexp }
|
113
113
|
klass = if !plural && opt[:tag_name]
|
114
|
-
Watir.
|
114
|
+
Watir.element_class_for(opt[:tag_name])
|
115
115
|
elsif !plural
|
116
116
|
HTMLElement
|
117
117
|
elsif opt[:tag_name]
|
118
|
-
Object.const_get("#{
|
118
|
+
Object.const_get("#{Watir.element_class_for(opt[:tag_name])}Collection")
|
119
119
|
else
|
120
120
|
HTMLElementCollection
|
121
121
|
end
|
data/lib/watir/browser.rb
CHANGED
@@ -127,7 +127,7 @@ module Watir
|
|
127
127
|
# @example
|
128
128
|
# browser.goto "watir.github.io"
|
129
129
|
# browser.title
|
130
|
-
# #=> "Watir
|
130
|
+
# #=> "Watir Project"
|
131
131
|
#
|
132
132
|
# @return [String]
|
133
133
|
#
|
@@ -51,6 +51,8 @@ module Watir
|
|
51
51
|
to_a[value]
|
52
52
|
elsif @selector.key? :adjacent
|
53
53
|
to_a[value] || element_class.new(@query_scope, {invalid_locator: true})
|
54
|
+
elsif @to_a && @to_a[value]
|
55
|
+
@to_a[value]
|
54
56
|
else
|
55
57
|
element_class.new(@query_scope, @selector.merge(index: value))
|
56
58
|
end
|
@@ -88,7 +90,7 @@ module Watir
|
|
88
90
|
elements.map.with_index do |e, idx|
|
89
91
|
element = element_class.new(@query_scope, @selector.merge(element: e, index: idx))
|
90
92
|
if [Watir::HTMLElement, Watir::Input].include? element.class
|
91
|
-
tag_name = element.tag_name.to_sym
|
93
|
+
tag_name = @selector[:tag_name] || element.tag_name.to_sym
|
92
94
|
hash[tag_name] ||= 0
|
93
95
|
hash[tag_name] += 1
|
94
96
|
Watir.element_class_for(tag_name).new(@query_scope, @selector.merge(element: e,
|
@@ -513,16 +513,15 @@ module Watir
|
|
513
513
|
|
514
514
|
def stale?
|
515
515
|
raise Watir::Exception::Error, "Can not check staleness of unused element" unless @element
|
516
|
-
return false unless stale_in_context?
|
517
516
|
@query_scope.ensure_context
|
518
|
-
stale_in_context?
|
517
|
+
@stale || stale_in_context?
|
519
518
|
end
|
520
519
|
|
521
520
|
def stale_in_context?
|
522
521
|
@element.enabled? # any wire call will check for staleness
|
523
522
|
false
|
524
523
|
rescue Selenium::WebDriver::Error::ObsoleteElementError
|
525
|
-
true
|
524
|
+
@stale = true
|
526
525
|
end
|
527
526
|
|
528
527
|
def reset!
|
@@ -703,6 +702,10 @@ module Watir
|
|
703
702
|
method = meth.to_s
|
704
703
|
if method =~ Locators::Element::SelectorBuilder::WILDCARD_ATTRIBUTE
|
705
704
|
attribute_value(method.tr('_', '-'), *args)
|
705
|
+
elsif UserEditable.instance_methods(false).include?(meth) && content_editable?
|
706
|
+
@content_editable = true
|
707
|
+
self.extend UserEditable
|
708
|
+
send(meth, *args, &blk)
|
706
709
|
else
|
707
710
|
super
|
708
711
|
end
|
@@ -14,12 +14,13 @@ module Watir
|
|
14
14
|
|
15
15
|
#
|
16
16
|
# Gets all the options in the select list
|
17
|
+
# Use Element#options rather than Select element attribute "options"
|
17
18
|
#
|
18
19
|
# @return [Watir::OptionCollection]
|
19
20
|
#
|
20
21
|
|
21
22
|
def options(*)
|
22
|
-
|
23
|
+
super
|
23
24
|
end
|
24
25
|
|
25
26
|
#
|
@@ -16,7 +16,7 @@ module Watir
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def ignored_attributes
|
19
|
-
%w(cells elements hash rows span text size selected? style width height tHead tFoot)
|
19
|
+
%w(cells elements hash rows span text size selected? style width height tHead tFoot link options)
|
20
20
|
end
|
21
21
|
|
22
22
|
def generator_implementation
|
@@ -115,10 +115,18 @@ module Watir
|
|
115
115
|
idx = idx.abs - 1
|
116
116
|
end
|
117
117
|
|
118
|
+
counter = 0
|
119
|
+
|
118
120
|
# Lazy evaluation to avoid fetching values for elements that will be discarded
|
119
|
-
matches = elements.lazy.select
|
120
|
-
|
121
|
+
matches = elements.lazy.select do |el|
|
122
|
+
counter += 1
|
123
|
+
matches_selector?(el, selector)
|
124
|
+
end
|
125
|
+
val = matches.take(idx + 1).to_a[idx]
|
126
|
+
Watir.logger.debug "Filtered through #{counter} elements to locate #{@selector.inspect}"
|
127
|
+
val
|
121
128
|
else
|
129
|
+
Watir.logger.debug "Iterated through #{elements.size} elements to locate all #{@selector.inspect}"
|
122
130
|
elements.select { |el| matches_selector?(el, selector) }
|
123
131
|
end
|
124
132
|
end
|
@@ -216,19 +224,21 @@ module Watir
|
|
216
224
|
end
|
217
225
|
end
|
218
226
|
|
219
|
-
if selector[:text]
|
220
|
-
text_content = Watir::Element.new(@query_scope, element: element).send(:execute_js, :getTextContent, element).strip
|
221
|
-
text_content_matches = selector[:text] === text_content
|
222
|
-
unless matches == text_content_matches
|
223
|
-
key = @selector.key?(:text) ? "text" : "label"
|
224
|
-
Watir.logger.deprecate("Using :#{key} locator with RegExp #{selector[:text].inspect} to match an element that includes hidden text", ":visible_#{key}",
|
225
|
-
ids: [:text_regexp])
|
226
|
-
end
|
227
|
-
end
|
227
|
+
text_regexp_deprecation(element, selector, matches) if selector[:text]
|
228
228
|
|
229
229
|
matches
|
230
230
|
end
|
231
231
|
|
232
|
+
def text_regexp_deprecation(element, selector, matches)
|
233
|
+
text_content = Watir::Element.new(@query_scope, element: element).send(:execute_js, :getTextContent, element).strip
|
234
|
+
text_content_matches = selector[:text] === text_content
|
235
|
+
unless matches == text_content_matches
|
236
|
+
key = @selector.key?(:text) ? "text" : "label"
|
237
|
+
Watir.logger.deprecate("Using :#{key} locator with RegExp #{selector[:text].inspect} to match an element that includes hidden text", ":visible_#{key}",
|
238
|
+
ids: [:text_regexp])
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
232
242
|
def can_convert_regexp_to_contains?
|
233
243
|
true
|
234
244
|
end
|
@@ -59,9 +59,10 @@ module Watir
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def build(selector)
|
62
|
+
inspect = selector.inspect
|
62
63
|
return given_xpath_or_css(selector) if selector.key?(:xpath) || selector.key?(:css)
|
63
64
|
built = build_wd_selector(selector)
|
64
|
-
Watir.logger.debug "Converted #{
|
65
|
+
Watir.logger.debug "Converted #{inspect} to #{built}"
|
65
66
|
built
|
66
67
|
end
|
67
68
|
|
@@ -6,11 +6,7 @@ module Watir
|
|
6
6
|
return if selectors.values.any? { |e| e.kind_of? Regexp }
|
7
7
|
selectors.delete(:tag_name) || raise("internal error: no tag_name?!")
|
8
8
|
|
9
|
-
|
10
|
-
expressions = %w[./tr]
|
11
|
-
unless %w[tbody tfoot thead].include?(tag_name)
|
12
|
-
expressions += %w[./tbody/tr ./thead/tr ./tfoot/tr]
|
13
|
-
end
|
9
|
+
expressions = generate_expressions(@query_scope.tag_name.downcase)
|
14
10
|
|
15
11
|
attr_expr = xpath_builder.attribute_expression(nil, selectors)
|
16
12
|
|
@@ -24,6 +20,16 @@ module Watir
|
|
24
20
|
|
25
21
|
[:xpath, xpath]
|
26
22
|
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def generate_expressions(tag_name)
|
27
|
+
expressions = %w[./tr]
|
28
|
+
unless %w[tbody tfoot thead].include?(tag_name)
|
29
|
+
expressions += %w[./tbody/tr ./thead/tr ./tfoot/tr]
|
30
|
+
end
|
31
|
+
expressions
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
data/lib/watir/user_editable.rb
CHANGED
@@ -26,9 +26,11 @@ module Watir
|
|
26
26
|
raise ArgumentError, "#set! does not support special keys, use #set instead" if args.any? { |v| v.kind_of?(::Symbol) }
|
27
27
|
input_value = args.join
|
28
28
|
set input_value[0]
|
29
|
+
return set_content_editable!(*args) if @content_editable
|
29
30
|
element_call { execute_js(:setValue, @element, input_value[0..-2]) }
|
30
31
|
append(input_value[-1])
|
31
|
-
|
32
|
+
return if value == input_value
|
33
|
+
raise Watir::Exception::Error, "#set! value: '#{value}' does not match expected input: '#{input_value}'"
|
32
34
|
end
|
33
35
|
|
34
36
|
#
|
@@ -38,6 +40,7 @@ module Watir
|
|
38
40
|
#
|
39
41
|
|
40
42
|
def append(*args)
|
43
|
+
raise NotImplementedError, "#append method is not supported with contenteditable element" if @content_editable
|
41
44
|
send_keys(*args)
|
42
45
|
end
|
43
46
|
alias_method :<<, :append
|
@@ -52,5 +55,13 @@ module Watir
|
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
58
|
+
private
|
59
|
+
|
60
|
+
def set_content_editable!(*args)
|
61
|
+
input_text = args.join
|
62
|
+
element_call { execute_js(:setText, @element, input_text) }
|
63
|
+
return if text == input_text
|
64
|
+
raise Watir::Exception::Error, "#set! text: '#{text}' does not match expected input: '#{input_text}'"
|
65
|
+
end
|
55
66
|
end # UserEditable
|
56
67
|
end # Watir
|
data/lib/watir/wait.rb
CHANGED
@@ -111,19 +111,24 @@ module Watir
|
|
111
111
|
# browser.text_field(name: "new_user_first_name").wait_until(&:present?).click
|
112
112
|
# browser.text_field(name: "new_user_first_name").wait_until(message: 'foo') { |field| field.present? }
|
113
113
|
# browser.text_field(name: "new_user_first_name").wait_until(timeout: 60, &:present?)
|
114
|
+
# browser.text_field(name: "new_user_first_name").wait_until(timeout: 60, name: 'new_user_first_name')
|
114
115
|
#
|
115
116
|
# @param [Integer] timeout seconds to wait before timing out
|
116
117
|
# @param [String] message error message for when times out
|
117
118
|
#
|
118
119
|
|
119
|
-
def wait_until(deprecated_timeout = nil, deprecated_message = nil, timeout: nil, message: nil, interval: nil, &blk)
|
120
|
+
def wait_until(deprecated_timeout = nil, deprecated_message = nil, timeout: nil, message: nil, interval: nil, **opt, &blk)
|
120
121
|
if deprecated_message || deprecated_timeout
|
121
122
|
Watir.logger.deprecate "Using arguments for #wait_until", "keywords", ids: [:timeout_arguments]
|
122
123
|
timeout = deprecated_timeout
|
123
124
|
message = deprecated_message
|
124
125
|
end
|
125
126
|
message ||= Proc.new { |obj| "waiting for true condition on #{obj.inspect}" }
|
126
|
-
|
127
|
+
|
128
|
+
raise ArgumentError, "Unknown keyword(s): #{opt.keys} " if block_given? && !opt.empty?
|
129
|
+
proc = block_given? ? blk : create_proc(opt)
|
130
|
+
|
131
|
+
Wait.until(timeout: timeout, message: message, interval: interval, object: self, &proc)
|
127
132
|
|
128
133
|
self
|
129
134
|
end
|
@@ -135,6 +140,7 @@ module Watir
|
|
135
140
|
# browser.wait_while(timeout: 2) do |browser|
|
136
141
|
# !browser.exists?
|
137
142
|
# end
|
143
|
+
# browser.wait_while(timeout: 2, title: 'No')
|
138
144
|
#
|
139
145
|
# @todo add element example
|
140
146
|
#
|
@@ -142,14 +148,18 @@ module Watir
|
|
142
148
|
# @param [String] message error message for when times out
|
143
149
|
#
|
144
150
|
|
145
|
-
def wait_while(deprecated_timeout = nil, deprecated_message = nil, timeout: nil, message: nil, interval: nil, &blk)
|
151
|
+
def wait_while(deprecated_timeout = nil, deprecated_message = nil, timeout: nil, message: nil, interval: nil, **opt, &blk)
|
146
152
|
if deprecated_message || deprecated_timeout
|
147
153
|
Watir.logger.deprecate "Using arguments for #wait_while", "keywords", ids: [:timeout_arguments]
|
148
154
|
timeout = deprecated_timeout
|
149
155
|
message = deprecated_message
|
150
156
|
end
|
151
157
|
message ||= Proc.new { |obj| "waiting for false condition on #{obj.inspect}" }
|
152
|
-
|
158
|
+
|
159
|
+
raise ArgumentError, "Unknown keyword(s): #{opt.keys} " if block_given? && !opt.empty?
|
160
|
+
proc = block_given? ? blk : create_proc(opt)
|
161
|
+
|
162
|
+
Wait.while(timeout: timeout, message: message, interval: interval, object: self, &proc)
|
153
163
|
|
154
164
|
self
|
155
165
|
end
|
@@ -216,5 +226,26 @@ module Watir
|
|
216
226
|
end
|
217
227
|
end
|
218
228
|
|
229
|
+
private
|
230
|
+
|
231
|
+
def create_proc(opt)
|
232
|
+
Proc.new do
|
233
|
+
opt.keys.all? do |key|
|
234
|
+
expected = opt[key]
|
235
|
+
actual = if self.is_a?(Watir::Element) && !self.respond_to?(key)
|
236
|
+
self.attribute_value(key)
|
237
|
+
else
|
238
|
+
self.send(key)
|
239
|
+
end
|
240
|
+
case expected
|
241
|
+
when Regexp
|
242
|
+
expected =~ actual
|
243
|
+
else
|
244
|
+
expected.to_s == actual
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
219
250
|
end # Waitable
|
220
251
|
end # Watir
|
@@ -21,6 +21,11 @@ describe "Adjacent Elements" do
|
|
21
21
|
expect(browser.div(id: "first_sibling").parent(tag_name: :div)).to be_a Watir::Div
|
22
22
|
end
|
23
23
|
|
24
|
+
it "accepts custom tag_name argument" do
|
25
|
+
expect(browser.div(id: "regular_child").parent(tag_name: :grandelement).id).to eq 'custom_grandparent'
|
26
|
+
expect(browser.div(id: "regular_child").parent(tag_name: :grandelement)).to be_a Watir::HTMLElement
|
27
|
+
end
|
28
|
+
|
24
29
|
it "accepts class_name argument" do
|
25
30
|
expect(browser.div(id: "first_sibling").parent(class_name: 'parent').id).to eq 'parent_span'
|
26
31
|
end
|
@@ -51,6 +56,12 @@ describe "Adjacent Elements" do
|
|
51
56
|
expect(siblings.all? { |sib| sib.is_a? Watir::Div }).to eq true
|
52
57
|
end
|
53
58
|
|
59
|
+
it "accepts custom tag name argument" do
|
60
|
+
siblings = browser.div(id: "regular_child").siblings(tag_name: :childelement)
|
61
|
+
expect(siblings.size).to eq 3
|
62
|
+
expect(siblings.all? { |sib| sib.is_a? Watir::HTMLElement }).to eq true
|
63
|
+
end
|
64
|
+
|
54
65
|
it "accepts a class_name argument" do
|
55
66
|
siblings = browser.div(id: "second_sibling").siblings(class_name: 'b')
|
56
67
|
expect(siblings.first).to be_a Watir::Div
|
@@ -191,6 +202,11 @@ describe "Adjacent Elements" do
|
|
191
202
|
expect(browser.div(id: "parent").child(tag_name: :span)).to be_a Watir::Span
|
192
203
|
end
|
193
204
|
|
205
|
+
it "accepts custom tag_name argument" do
|
206
|
+
expect(browser.element(id: "custom_parent").child(tag_name: :childelement).id).to eq 'custom_child'
|
207
|
+
expect(browser.element(id: "custom_parent").child(tag_name: :childelement)).to be_a Watir::HTMLElement
|
208
|
+
end
|
209
|
+
|
194
210
|
it "accepts class_name argument" do
|
195
211
|
expect(browser.div(id: "parent").child(class_name: 'b').id).to eq 'second_sibling'
|
196
212
|
end
|
@@ -221,6 +237,12 @@ describe "Adjacent Elements" do
|
|
221
237
|
expect(children.all? { |child| child.is_a? Watir::Div }).to eq true
|
222
238
|
end
|
223
239
|
|
240
|
+
it "accepts custom tag_name argument" do
|
241
|
+
children = browser.element(id: "custom_parent").children(tag_name: :childelement)
|
242
|
+
expect(children.size).to eq 3
|
243
|
+
expect(children.all? { |child| child.is_a? Watir::HTMLElement }).to eq true
|
244
|
+
end
|
245
|
+
|
224
246
|
it "accepts a class_name argument" do
|
225
247
|
children = browser.div(id: "parent").children(class_name: 'b')
|
226
248
|
expect(children.size).to eq 2
|
@@ -286,26 +286,28 @@ describe "Browser" do
|
|
286
286
|
end
|
287
287
|
|
288
288
|
compliant_on :chrome do
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
289
|
+
not_compliant_on :watigiri do
|
290
|
+
it "takes port and driver_opt as arguments" do
|
291
|
+
@original = WatirSpec.implementation.clone
|
292
|
+
browser.close
|
293
|
+
@opts = WatirSpec.implementation.browser_args.last
|
293
294
|
|
294
|
-
|
295
|
-
|
296
|
-
|
295
|
+
@opts.merge!(port: '2314',
|
296
|
+
driver_opts: {args: ['foo']},
|
297
|
+
listener: LocalConfig::SelectorListener.new)
|
297
298
|
|
298
|
-
|
299
|
+
@new_browser = WatirSpec.new_browser
|
299
300
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
301
|
+
bridge = @new_browser.wd.instance_variable_get('@bridge')
|
302
|
+
expect(bridge).to be_a Selenium::WebDriver::Support::EventFiringBridge
|
303
|
+
service = @new_browser.wd.instance_variable_get("@service")
|
304
|
+
expect(service.instance_variable_get("@extra_args")).to eq ["foo"]
|
305
|
+
expect(service.instance_variable_get("@port")).to eq 2314
|
305
306
|
|
306
|
-
|
307
|
-
|
308
|
-
|
307
|
+
@new_browser.close
|
308
|
+
WatirSpec.implementation = @original.clone
|
309
|
+
$browser = WatirSpec.new_browser
|
310
|
+
end
|
309
311
|
end
|
310
312
|
end
|
311
313
|
|
@@ -49,4 +49,28 @@ describe "Collections" do
|
|
49
49
|
expect(spans).to receive(:elements).and_return([])
|
50
50
|
expect(spans.locate).to be_a Watir::SpanCollection
|
51
51
|
end
|
52
|
+
|
53
|
+
it "lazy loads collections referenced with #[]" do
|
54
|
+
browser.goto(WatirSpec.url_for("collections.html"))
|
55
|
+
expect(browser.wd).to_not receive(:find_elements)
|
56
|
+
browser.spans[3]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "does not relocate collections when previously evaluated" do
|
60
|
+
browser.goto(WatirSpec.url_for("collections.html"))
|
61
|
+
elements = browser.spans.tap(&:to_a)
|
62
|
+
|
63
|
+
expect(browser.wd).to_not receive(:find_elements)
|
64
|
+
elements[1].id
|
65
|
+
end
|
66
|
+
|
67
|
+
it "relocates cached elements that go stale" do
|
68
|
+
browser.goto(WatirSpec.url_for("collections.html"))
|
69
|
+
elements = browser.spans.tap(&:to_a)
|
70
|
+
|
71
|
+
browser.refresh
|
72
|
+
expect(elements[1]).to be_stale
|
73
|
+
expect { elements[1] }.to_not raise_unknown_object_exception
|
74
|
+
end
|
75
|
+
|
52
76
|
end
|
@@ -151,12 +151,16 @@ describe "Div" do
|
|
151
151
|
expect { browser.div(text: /some visible/).exists? }.not_to have_deprecated_text_regexp
|
152
152
|
end
|
153
153
|
|
154
|
-
|
155
|
-
|
154
|
+
not_compliant_on :watigiri do
|
155
|
+
it "throws deprecation when no longer matched by text content" do
|
156
|
+
expect { browser.div(text: /some visible$/).exists? }.to have_deprecated_text_regexp
|
157
|
+
end
|
156
158
|
end
|
157
159
|
|
158
|
-
|
159
|
-
|
160
|
+
not_compliant_on :watigiri do
|
161
|
+
it "throws deprecation when begins to be matched by text content" do
|
162
|
+
expect { browser.div(text: /some hidden/).exists? }.to have_deprecated_text_regexp
|
163
|
+
end
|
160
164
|
end
|
161
165
|
|
162
166
|
it "does not throw deprecation when still not matched by text content" do
|
@@ -333,15 +333,31 @@ describe "Element" do
|
|
333
333
|
end
|
334
334
|
|
335
335
|
it "returns true if the element is enabled" do
|
336
|
-
expect(browser.
|
336
|
+
expect(browser.button(name: 'new_user_submit')).to be_enabled
|
337
337
|
end
|
338
338
|
|
339
339
|
it "returns false if the element is disabled" do
|
340
|
-
expect(browser.
|
340
|
+
expect(browser.button(name: 'new_user_submit_disabled')).to_not be_enabled
|
341
341
|
end
|
342
342
|
|
343
343
|
it "raises UnknownObjectException if the element doesn't exist" do
|
344
|
-
expect { browser.
|
344
|
+
expect { browser.button(name: "no_such_name").enabled? }.to raise_unknown_object_exception
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
describe "#stale?" do
|
349
|
+
it "returns true if the element is stale" do
|
350
|
+
element = browser.button(name: 'new_user_submit_disabled').tap(&:exists?)
|
351
|
+
|
352
|
+
browser.refresh
|
353
|
+
|
354
|
+
expect(element).to be_stale
|
355
|
+
end
|
356
|
+
|
357
|
+
it "returns false if the element is not stale" do
|
358
|
+
element = browser.button(name: 'new_user_submit_disabled').tap(&:exists?)
|
359
|
+
|
360
|
+
expect(element).to_not be_stale
|
345
361
|
end
|
346
362
|
end
|
347
363
|
|
@@ -207,165 +207,4 @@ describe "TextField" do
|
|
207
207
|
expect { browser.text_field(id: 'new_user_code').set 'foo' }.to raise_object_read_only_exception
|
208
208
|
end
|
209
209
|
end
|
210
|
-
|
211
|
-
# Manipulation methods
|
212
|
-
not_compliant_on :safari do
|
213
|
-
describe "#append" do
|
214
|
-
it "appends the text to the text field" do
|
215
|
-
browser.text_field(name: "new_user_occupation").append(" Append This")
|
216
|
-
expect(browser.text_field(name: "new_user_occupation").value).to eq "Developer Append This"
|
217
|
-
end
|
218
|
-
|
219
|
-
it "appends multi-byte characters" do
|
220
|
-
browser.text_field(name: "new_user_occupation").append(" ijij")
|
221
|
-
expect(browser.text_field(name: "new_user_occupation").value).to eq "Developer ijij"
|
222
|
-
end
|
223
|
-
|
224
|
-
it "raises ObjectReadOnlyException if the object is read only" do
|
225
|
-
expect { browser.text_field(id: "new_user_code").append("Append This") }.to raise_object_read_only_exception
|
226
|
-
end
|
227
|
-
|
228
|
-
it "raises ObjectDisabledException if the object is disabled" do
|
229
|
-
expect { browser.text_field(name: "new_user_species").append("Append This") }.to raise_object_disabled_exception
|
230
|
-
end
|
231
|
-
|
232
|
-
it "raises UnknownObjectException if the object doesn't exist" do
|
233
|
-
expect { browser.text_field(name: "no_such_name").append("Append This") }.to raise_unknown_object_exception
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
describe "#clear" do
|
239
|
-
it "removes all text from the text field" do
|
240
|
-
browser.text_field(name: "new_user_occupation").clear
|
241
|
-
expect(browser.text_field(name: "new_user_occupation").value).to be_empty
|
242
|
-
browser.textarea(id: "delete_user_comment").clear
|
243
|
-
expect(browser.textarea(id: "delete_user_comment").value).to be_empty
|
244
|
-
end
|
245
|
-
|
246
|
-
it "raises UnknownObjectException if the text field doesn't exist" do
|
247
|
-
expect { browser.text_field(id: "no_such_id").clear }.to raise_unknown_object_exception
|
248
|
-
end
|
249
|
-
|
250
|
-
it "raises ObjectReadOnlyException if the object is read only" do
|
251
|
-
expect { browser.text_field(id: "new_user_code").clear }.to raise_object_read_only_exception
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
describe "#value=" do
|
256
|
-
it "sets the value of the element" do
|
257
|
-
browser.text_field(id: 'new_user_email').value = 'Hello Cruel World'
|
258
|
-
expect(browser.text_field(id: "new_user_email").value).to eq 'Hello Cruel World'
|
259
|
-
end
|
260
|
-
|
261
|
-
it "is able to set multi-byte characters" do
|
262
|
-
browser.text_field(name: "new_user_occupation").value = "ijij"
|
263
|
-
expect(browser.text_field(name: "new_user_occupation").value).to eq "ijij"
|
264
|
-
end
|
265
|
-
|
266
|
-
it "sets the value of a textarea element" do
|
267
|
-
browser.textarea(id: 'delete_user_comment').value = 'Hello Cruel World'
|
268
|
-
expect(browser.textarea(id: "delete_user_comment").value).to eq 'Hello Cruel World'
|
269
|
-
end
|
270
|
-
|
271
|
-
it "raises UnknownObjectException if the text field doesn't exist" do
|
272
|
-
expect { browser.text_field(name: "no_such_name").value = 'yo' }.to raise_unknown_object_exception
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
describe "#set" do
|
277
|
-
it "sets the value of the element" do
|
278
|
-
browser.text_field(id: 'new_user_email').set('Bye Cruel World')
|
279
|
-
expect(browser.text_field(id: "new_user_email").value).to eq 'Bye Cruel World'
|
280
|
-
end
|
281
|
-
|
282
|
-
it "sets the value of a textarea element" do
|
283
|
-
browser.textarea(id: 'delete_user_comment').set('Hello Cruel World')
|
284
|
-
expect(browser.textarea(id: "delete_user_comment").value).to eq 'Hello Cruel World'
|
285
|
-
end
|
286
|
-
|
287
|
-
it "fires events" do
|
288
|
-
browser.text_field(id: "new_user_username").set("Hello World")
|
289
|
-
expect(browser.span(id: "current_length").text).to eq "11"
|
290
|
-
end
|
291
|
-
|
292
|
-
it "sets the value of a password field" do
|
293
|
-
browser.text_field(name: 'new_user_password').set('secret')
|
294
|
-
expect(browser.text_field(name: 'new_user_password').value).to eq 'secret'
|
295
|
-
end
|
296
|
-
|
297
|
-
it "sets the value when accessed through the enclosing Form" do
|
298
|
-
browser.form(id: 'new_user').text_field(name: 'new_user_password').set('secret')
|
299
|
-
expect(browser.form(id: 'new_user').text_field(name: 'new_user_password').value).to eq 'secret'
|
300
|
-
end
|
301
|
-
|
302
|
-
it "is able to set multi-byte characters" do
|
303
|
-
browser.text_field(name: "new_user_occupation").set("ijij")
|
304
|
-
expect(browser.text_field(name: "new_user_occupation").value).to eq "ijij"
|
305
|
-
end
|
306
|
-
|
307
|
-
it "sets the value to a concatenation of multiple arguments" do
|
308
|
-
browser.text_field(id: 'new_user_email').set('Bye', 'Cruel', 'World')
|
309
|
-
expect(browser.text_field(id: "new_user_email").value).to eq 'ByeCruelWorld'
|
310
|
-
end
|
311
|
-
|
312
|
-
it "sets the value to blank when no arguments are provided" do
|
313
|
-
browser.text_field(id: 'new_user_email').set
|
314
|
-
expect(browser.text_field(id: "new_user_email").value).to eq ''
|
315
|
-
end
|
316
|
-
|
317
|
-
it "raises UnknownObjectException if the text field doesn't exist" do
|
318
|
-
expect { browser.text_field(id: "no_such_id").set('secret') }.to raise_unknown_object_exception
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
describe "#set!" do
|
323
|
-
it "sets the value of the element" do
|
324
|
-
browser.text_field(id: 'new_user_email').set!('Bye Cruel World')
|
325
|
-
expect(browser.text_field(id: "new_user_email").value).to eq 'Bye Cruel World'
|
326
|
-
end
|
327
|
-
|
328
|
-
it "sets the value of a textarea element" do
|
329
|
-
browser.textarea(id: 'delete_user_comment').set!('Hello Cruel World')
|
330
|
-
expect(browser.textarea(id: "delete_user_comment").value).to eq 'Hello Cruel World'
|
331
|
-
end
|
332
|
-
|
333
|
-
it "fires events" do
|
334
|
-
browser.text_field(id: "new_user_username").set!("Hello World")
|
335
|
-
expect(browser.span(id: "current_length").text).to eq "11"
|
336
|
-
end
|
337
|
-
|
338
|
-
it "sets the value of a password field" do
|
339
|
-
browser.text_field(name: 'new_user_password').set!('secret')
|
340
|
-
expect(browser.text_field(name: 'new_user_password').value).to eq 'secret'
|
341
|
-
end
|
342
|
-
|
343
|
-
it "sets the value when accessed through the enclosing Form" do
|
344
|
-
browser.form(id: 'new_user').text_field(name: 'new_user_password').set!('secret')
|
345
|
-
expect(browser.form(id: 'new_user').text_field(name: 'new_user_password').value).to eq 'secret'
|
346
|
-
end
|
347
|
-
|
348
|
-
it "is able to set multi-byte characters" do
|
349
|
-
browser.text_field(name: "new_user_occupation").set!("ijij")
|
350
|
-
expect(browser.text_field(name: "new_user_occupation").value).to eq "ijij"
|
351
|
-
end
|
352
|
-
|
353
|
-
it "sets the value to a concatenation of multiple arguments" do
|
354
|
-
browser.text_field(id: 'new_user_email').set!('Bye', 'Cruel', 'World')
|
355
|
-
expect(browser.text_field(id: "new_user_email").value).to eq 'ByeCruelWorld'
|
356
|
-
end
|
357
|
-
|
358
|
-
it "sets the value to blank when no arguments are provided" do
|
359
|
-
browser.text_field(id: 'new_user_email').set!
|
360
|
-
expect(browser.text_field(id: "new_user_email").value).to eq ''
|
361
|
-
end
|
362
|
-
|
363
|
-
it "raises ArgumentError for special keys" do
|
364
|
-
expect { browser.text_field(id: 'new_user_email').set!('a', :tab) }.to raise_error(ArgumentError)
|
365
|
-
end
|
366
|
-
|
367
|
-
it "raises UnknownObjectException if the text field doesn't exist" do
|
368
|
-
expect { browser.text_field(id: "no_such_id").set!('secret') }.to raise_unknown_object_exception
|
369
|
-
end
|
370
|
-
end
|
371
210
|
end
|
@@ -161,6 +161,8 @@
|
|
161
161
|
<div id="wants_newsletter" style="display: none;"></div>
|
162
162
|
<div id="onfocus_test"></div>
|
163
163
|
|
164
|
+
<div id="contenteditable" contenteditable="true">Foo</div>
|
165
|
+
|
164
166
|
<!-- option disappears onchange -->
|
165
167
|
<select id="obsolete" onchange="this.innerHTML = '';">
|
166
168
|
<option value="norway">norway</option>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
</head>
|
7
7
|
|
8
8
|
<body>
|
9
|
-
<span id="grandparent_span">
|
9
|
+
<span id="grandparent_span">
|
10
10
|
<div id="grandparent">
|
11
11
|
<span class="parent" id="parent_span">
|
12
12
|
<div id="parent">
|
@@ -30,5 +30,15 @@
|
|
30
30
|
</span>
|
31
31
|
</div>
|
32
32
|
</span>
|
33
|
+
<div>
|
34
|
+
<grandelement id="custom_grandparent">
|
35
|
+
<parentelement id="custom_parent">
|
36
|
+
<div id="regular_child"></div>
|
37
|
+
<childelement id="custom_child" class="custom_child a"></childelement>
|
38
|
+
<childelement class="custom_child b"></childelement>
|
39
|
+
<childelement class="custom_child c"></childelement>
|
40
|
+
</parentelement>
|
41
|
+
</grandelement>
|
42
|
+
</div>
|
33
43
|
</body>
|
34
44
|
</html>
|
@@ -11,7 +11,9 @@
|
|
11
11
|
|
12
12
|
function setTimeoutDisplay(id, display, timeout) {
|
13
13
|
setTimeout(function() {
|
14
|
-
document.getElementById(id)
|
14
|
+
var el = document.getElementById(id)
|
15
|
+
el.style.display = display;
|
16
|
+
el.setAttribute("custom", id)
|
15
17
|
}, timeout);
|
16
18
|
}
|
17
19
|
|
@@ -54,7 +56,7 @@
|
|
54
56
|
</head>
|
55
57
|
|
56
58
|
<body>
|
57
|
-
<div id="foo" style="display:block;">foo</div>
|
59
|
+
<div id="foo" custom="" style="display:block;">foo</div>
|
58
60
|
<div id="bar" style="display:none;" onclick='this.innerHTML = "changed"'>bar</div>
|
59
61
|
<a id="show_bar" href="#" onclick="setTimeoutDisplay('bar', 'block', 500);">show bar</a>
|
60
62
|
<a id="hide_foo" href="#" onclick="setTimeoutDisplay('foo', 'none', 500);">hide foo</a>
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require "watirspec_helper"
|
2
|
+
|
3
|
+
describe Watir::UserEditable do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
browser.goto(WatirSpec.url_for("forms_with_input_elements.html"))
|
7
|
+
end
|
8
|
+
|
9
|
+
not_compliant_on :safari do
|
10
|
+
describe "#append" do
|
11
|
+
it "appends the text to the text field" do
|
12
|
+
browser.text_field(name: "new_user_occupation").append(" Append This")
|
13
|
+
expect(browser.text_field(name: "new_user_occupation").value).to eq "Developer Append This"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "appends multi-byte characters" do
|
17
|
+
browser.text_field(name: "new_user_occupation").append(" ijij")
|
18
|
+
expect(browser.text_field(name: "new_user_occupation").value).to eq "Developer ijij"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "raises NotImplementedError if the object is content editable element" do
|
22
|
+
msg = "#append method is not supported with contenteditable element"
|
23
|
+
expect { browser.div(id: 'contenteditable').append("bar") }.to raise_exception(NotImplementedError, msg)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises ObjectReadOnlyException if the object is read only" do
|
27
|
+
expect { browser.text_field(id: "new_user_code").append("Append This") }.to raise_object_read_only_exception
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises ObjectDisabledException if the object is disabled" do
|
31
|
+
expect { browser.text_field(name: "new_user_species").append("Append This") }.to raise_object_disabled_exception
|
32
|
+
end
|
33
|
+
|
34
|
+
it "raises UnknownObjectException if the object doesn't exist" do
|
35
|
+
expect { browser.text_field(name: "no_such_name").append("Append This") }.to raise_unknown_object_exception
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#clear" do
|
41
|
+
it "removes all text from the text field" do
|
42
|
+
browser.text_field(name: "new_user_occupation").clear
|
43
|
+
expect(browser.text_field(name: "new_user_occupation").value).to be_empty
|
44
|
+
browser.textarea(id: "delete_user_comment").clear
|
45
|
+
expect(browser.textarea(id: "delete_user_comment").value).to be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
it "removes all text from the content editable element" do
|
49
|
+
browser.div(id: 'contenteditable').clear
|
50
|
+
expect(browser.div(id: 'contenteditable').text).to eq ""
|
51
|
+
end
|
52
|
+
|
53
|
+
it "raises UnknownObjectException if the text field doesn't exist" do
|
54
|
+
expect { browser.text_field(id: "no_such_id").clear }.to raise_unknown_object_exception
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raises ObjectReadOnlyException if the object is read only" do
|
58
|
+
expect { browser.text_field(id: "new_user_code").clear }.to raise_object_read_only_exception
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#value=" do
|
63
|
+
it "sets the value of the element" do
|
64
|
+
browser.text_field(id: 'new_user_email').value = 'Hello Cruel World'
|
65
|
+
expect(browser.text_field(id: "new_user_email").value).to eq 'Hello Cruel World'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "is able to set multi-byte characters" do
|
69
|
+
browser.text_field(name: "new_user_occupation").value = "ijij"
|
70
|
+
expect(browser.text_field(name: "new_user_occupation").value).to eq "ijij"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "sets the value of a textarea element" do
|
74
|
+
browser.textarea(id: 'delete_user_comment').value = 'Hello Cruel World'
|
75
|
+
expect(browser.textarea(id: "delete_user_comment").value).to eq 'Hello Cruel World'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "raises UnknownObjectException if the text field doesn't exist" do
|
79
|
+
expect { browser.text_field(name: "no_such_name").value = 'yo' }.to raise_unknown_object_exception
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#set" do
|
84
|
+
it "sets the value of the element" do
|
85
|
+
browser.text_field(id: 'new_user_email').set('Bye Cruel World')
|
86
|
+
expect(browser.text_field(id: "new_user_email").value).to eq 'Bye Cruel World'
|
87
|
+
end
|
88
|
+
|
89
|
+
it "sets the value of a textarea element" do
|
90
|
+
browser.textarea(id: 'delete_user_comment').set('Hello Cruel World')
|
91
|
+
expect(browser.textarea(id: "delete_user_comment").value).to eq 'Hello Cruel World'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "sets the value of a content editable element" do
|
95
|
+
browser.div(id: 'contenteditable').set("Bar")
|
96
|
+
expect(browser.div(id: 'contenteditable').text).to eq "Bar"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "fires events" do
|
100
|
+
browser.text_field(id: "new_user_username").set("Hello World")
|
101
|
+
expect(browser.span(id: "current_length").text).to eq "11"
|
102
|
+
end
|
103
|
+
|
104
|
+
it "sets the value of a password field" do
|
105
|
+
browser.text_field(name: 'new_user_password').set('secret')
|
106
|
+
expect(browser.text_field(name: 'new_user_password').value).to eq 'secret'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "sets the value when accessed through the enclosing Form" do
|
110
|
+
browser.form(id: 'new_user').text_field(name: 'new_user_password').set('secret')
|
111
|
+
expect(browser.form(id: 'new_user').text_field(name: 'new_user_password').value).to eq 'secret'
|
112
|
+
end
|
113
|
+
|
114
|
+
it "is able to set multi-byte characters" do
|
115
|
+
browser.text_field(name: "new_user_occupation").set("ijij")
|
116
|
+
expect(browser.text_field(name: "new_user_occupation").value).to eq "ijij"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "sets the value to a concatenation of multiple arguments" do
|
120
|
+
browser.text_field(id: 'new_user_email').set('Bye', 'Cruel', 'World')
|
121
|
+
expect(browser.text_field(id: "new_user_email").value).to eq 'ByeCruelWorld'
|
122
|
+
end
|
123
|
+
|
124
|
+
it "sets the value to blank when no arguments are provided" do
|
125
|
+
browser.text_field(id: 'new_user_email').set
|
126
|
+
expect(browser.text_field(id: "new_user_email").value).to eq ''
|
127
|
+
end
|
128
|
+
|
129
|
+
it "raises UnknownObjectException if the text field doesn't exist" do
|
130
|
+
expect { browser.text_field(id: "no_such_id").set('secret') }.to raise_unknown_object_exception
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "#set!" do
|
135
|
+
it "sets the value of the element" do
|
136
|
+
browser.text_field(id: 'new_user_email').set!('Bye Cruel World')
|
137
|
+
expect(browser.text_field(id: "new_user_email").value).to eq 'Bye Cruel World'
|
138
|
+
end
|
139
|
+
|
140
|
+
it "sets the value of a textarea element" do
|
141
|
+
browser.textarea(id: 'delete_user_comment').set!('Hello Cruel World')
|
142
|
+
expect(browser.textarea(id: "delete_user_comment").value).to eq 'Hello Cruel World'
|
143
|
+
end
|
144
|
+
|
145
|
+
it "sets the value of a content editable element" do
|
146
|
+
browser.div(id: 'contenteditable').set!("foo")
|
147
|
+
expect(browser.div(id: 'contenteditable').text).to eq "foo"
|
148
|
+
end
|
149
|
+
|
150
|
+
it "fires events" do
|
151
|
+
browser.text_field(id: "new_user_username").set!("Hello World")
|
152
|
+
expect(browser.span(id: "current_length").text).to eq "11"
|
153
|
+
end
|
154
|
+
|
155
|
+
it "sets the value of a password field" do
|
156
|
+
browser.text_field(name: 'new_user_password').set!('secret')
|
157
|
+
expect(browser.text_field(name: 'new_user_password').value).to eq 'secret'
|
158
|
+
end
|
159
|
+
|
160
|
+
it "sets the value when accessed through the enclosing Form" do
|
161
|
+
browser.form(id: 'new_user').text_field(name: 'new_user_password').set!('secret')
|
162
|
+
expect(browser.form(id: 'new_user').text_field(name: 'new_user_password').value).to eq 'secret'
|
163
|
+
end
|
164
|
+
|
165
|
+
it "is able to set multi-byte characters" do
|
166
|
+
browser.text_field(name: "new_user_occupation").set!("ijij")
|
167
|
+
expect(browser.text_field(name: "new_user_occupation").value).to eq "ijij"
|
168
|
+
end
|
169
|
+
|
170
|
+
it "sets the value to a concatenation of multiple arguments" do
|
171
|
+
browser.text_field(id: 'new_user_email').set!('Bye', 'Cruel', 'World')
|
172
|
+
expect(browser.text_field(id: "new_user_email").value).to eq 'ByeCruelWorld'
|
173
|
+
end
|
174
|
+
|
175
|
+
it "sets the value to blank when no arguments are provided" do
|
176
|
+
browser.text_field(id: 'new_user_email').set!
|
177
|
+
expect(browser.text_field(id: "new_user_email").value).to eq ''
|
178
|
+
end
|
179
|
+
|
180
|
+
it "raises ArgumentError for special keys" do
|
181
|
+
expect { browser.text_field(id: 'new_user_email').set!('a', :tab) }.to raise_error(ArgumentError)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "raises UnknownObjectException if the text field doesn't exist" do
|
185
|
+
expect { browser.text_field(id: "no_such_id").set!('secret') }.to raise_unknown_object_exception
|
186
|
+
end
|
187
|
+
|
188
|
+
it "raises Exception if the value of text field doesn't match" do
|
189
|
+
element = browser.text_field(id: "new_user_password")
|
190
|
+
allow(element).to receive(:value).and_return("wrong")
|
191
|
+
msg = "#set! value: 'wrong' does not match expected input: 'secret'"
|
192
|
+
expect { element.set!('secret') }.to raise_exception(Watir::Exception::Error, msg)
|
193
|
+
end
|
194
|
+
|
195
|
+
it "raises Exception if the text of content editable element doesn't match" do
|
196
|
+
element = browser.div(id: "contenteditable")
|
197
|
+
allow(element).to receive(:text).and_return("wrong")
|
198
|
+
msg = "#set! text: 'wrong' does not match expected input: 'secret'"
|
199
|
+
expect { element.set!('secret') }.to raise_exception(Watir::Exception::Error, msg)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
data/spec/watirspec/wait_spec.rb
CHANGED
@@ -204,6 +204,49 @@ describe Watir::Element do
|
|
204
204
|
element = browser.div(id: 'bar')
|
205
205
|
expect { element.wait_until(interval: 0.1) { true } }.to_not raise_exception
|
206
206
|
end
|
207
|
+
|
208
|
+
context "accepts keywords instead of block" do
|
209
|
+
before { browser.refresh }
|
210
|
+
|
211
|
+
it "accepts text keyword" do
|
212
|
+
element = browser.div(id: 'bar')
|
213
|
+
browser.a(id: 'show_bar').click
|
214
|
+
expect { element.wait_until(text: 'bar') }.to_not raise_exception
|
215
|
+
end
|
216
|
+
|
217
|
+
it "accepts regular expression value" do
|
218
|
+
element = browser.div(id: 'bar')
|
219
|
+
browser.a(id: 'show_bar').click
|
220
|
+
expect { element.wait_until(style: /block/) }.to_not raise_exception
|
221
|
+
end
|
222
|
+
|
223
|
+
it "accepts multiple keywords" do
|
224
|
+
element = browser.div(id: 'bar')
|
225
|
+
browser.a(id: 'show_bar').click
|
226
|
+
expect { element.wait_until(text: 'bar', style: /block/) }.to_not raise_exception
|
227
|
+
end
|
228
|
+
|
229
|
+
it "accepts custom keyword" do
|
230
|
+
element = browser.div(id: 'bar')
|
231
|
+
browser.a(id: 'show_bar').click
|
232
|
+
expect { element.wait_until(custom: 'bar') }.to_not raise_exception
|
233
|
+
end
|
234
|
+
|
235
|
+
it "times out when single keyword not met" do
|
236
|
+
element = browser.div(id: 'bar')
|
237
|
+
expect { element.wait_until(id: 'foo') }.to raise_timeout_exception
|
238
|
+
end
|
239
|
+
|
240
|
+
it "times out when one of multiple keywords not met" do
|
241
|
+
element = browser.div(id: 'bar')
|
242
|
+
expect { element.wait_until(id: 'bar', text: 'foo') }.to raise_timeout_exception
|
243
|
+
end
|
244
|
+
|
245
|
+
it "times out when a custom keywords not met" do
|
246
|
+
element = browser.div(id: 'bar')
|
247
|
+
expect { element.wait_until(custom: 'foo') }.to raise_timeout_exception
|
248
|
+
end
|
249
|
+
end
|
207
250
|
end
|
208
251
|
|
209
252
|
describe "#wait_while" do
|
@@ -240,6 +283,48 @@ describe Watir::Element do
|
|
240
283
|
element = browser.div(id: 'foo')
|
241
284
|
expect { element.wait_while(interval: 0.1) { false } }.to_not raise_exception
|
242
285
|
end
|
286
|
+
|
287
|
+
context "accepts keywords instead of block" do
|
288
|
+
it "accepts text keyword" do
|
289
|
+
element = browser.div(id: 'foo')
|
290
|
+
browser.a(id: 'hide_foo').click
|
291
|
+
expect { element.wait_while(text: 'foo') }.to_not raise_exception
|
292
|
+
end
|
293
|
+
|
294
|
+
it "accepts regular expression value" do
|
295
|
+
element = browser.div(id: 'foo')
|
296
|
+
browser.a(id: 'hide_foo').click
|
297
|
+
expect { element.wait_while(style: /block/) }.to_not raise_exception
|
298
|
+
end
|
299
|
+
|
300
|
+
it "accepts multiple keywords" do
|
301
|
+
element = browser.div(id: 'foo')
|
302
|
+
browser.a(id: 'hide_foo').click
|
303
|
+
expect { element.wait_while(text: 'foo', style: /block/) }.to_not raise_exception
|
304
|
+
end
|
305
|
+
|
306
|
+
it "accepts custom attributes" do
|
307
|
+
element = browser.div(id: 'foo')
|
308
|
+
browser.a(id: 'hide_foo').click
|
309
|
+
expect { element.wait_while(custom: '') }.to_not raise_exception
|
310
|
+
end
|
311
|
+
|
312
|
+
it "times out when single keyword not met" do
|
313
|
+
element = browser.div(id: 'foo')
|
314
|
+
expect { element.wait_while(id: 'foo') }.to raise_timeout_exception
|
315
|
+
end
|
316
|
+
|
317
|
+
it "times out when one of multiple keywords not met" do
|
318
|
+
element = browser.div(id: 'foo')
|
319
|
+
browser.a(id: 'hide_foo').click
|
320
|
+
expect { element.wait_while(id: 'foo', style: /block/) }.to raise_timeout_exception
|
321
|
+
end
|
322
|
+
|
323
|
+
it "times out when one of custom keywords not met" do
|
324
|
+
element = browser.div(id: 'foo')
|
325
|
+
expect { element.wait_while(custom: '') }.to raise_timeout_exception
|
326
|
+
end
|
327
|
+
end
|
243
328
|
end
|
244
329
|
end
|
245
330
|
|
data/watir.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: watir
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Rodionov
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-09-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: selenium-webdriver
|
@@ -292,6 +292,7 @@ files:
|
|
292
292
|
- lib/watir/js_snippets/selectOptionsValue.js
|
293
293
|
- lib/watir/js_snippets/selectText.js
|
294
294
|
- lib/watir/js_snippets/selectedOptions.js
|
295
|
+
- lib/watir/js_snippets/setText.js
|
295
296
|
- lib/watir/js_snippets/setValue.js
|
296
297
|
- lib/watir/legacy_wait.rb
|
297
298
|
- lib/watir/locators.rb
|
@@ -497,6 +498,7 @@ files:
|
|
497
498
|
- spec/watirspec/screenshot_spec.rb
|
498
499
|
- spec/watirspec/special_chars_spec.rb
|
499
500
|
- spec/watirspec/support/rspec_matchers.rb
|
501
|
+
- spec/watirspec/user_editable_spec.rb
|
500
502
|
- spec/watirspec/wait_spec.rb
|
501
503
|
- spec/watirspec/window_switching_spec.rb
|
502
504
|
- spec/watirspec_helper.rb
|
@@ -697,6 +699,7 @@ test_files:
|
|
697
699
|
- spec/watirspec/screenshot_spec.rb
|
698
700
|
- spec/watirspec/special_chars_spec.rb
|
699
701
|
- spec/watirspec/support/rspec_matchers.rb
|
702
|
+
- spec/watirspec/user_editable_spec.rb
|
700
703
|
- spec/watirspec/wait_spec.rb
|
701
704
|
- spec/watirspec/window_switching_spec.rb
|
702
705
|
- spec/watirspec_helper.rb
|