watir 6.12.0 → 6.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|