watir 7.2.2 → 7.3.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/.github/workflows/chrome.yml +9 -1
- data/.github/workflows/edge.yml +10 -2
- data/.github/workflows/firefox.yml +10 -2
- data/.github/workflows/ie.yml +1 -1
- data/.github/workflows/safari.yml +1 -1
- data/.github/workflows/unit.yml +3 -3
- data/.rubocop.yml +11 -2
- data/CHANGES.md +7 -0
- data/lib/watir/capabilities.rb +1 -8
- data/lib/watir/cookies.rb +7 -2
- data/lib/watir/elements/date_field.rb +2 -2
- data/lib/watir/elements/date_time_field.rb +2 -2
- data/lib/watir/elements/select.rb +3 -3
- data/lib/watir/locators/element/selector_builder.rb +1 -1
- data/lib/watir/locators/text_field/matcher.rb +1 -1
- data/lib/watir/version.rb +1 -1
- data/lib/watir.rb +1 -0
- data/lib/watirspec/implementation.rb +1 -1
- data/lib/watirspec.rb +1 -1
- data/spec/locator_spec_helper.rb +3 -7
- data/spec/unit/capabilities_spec.rb +7 -8
- data/spec/unit/selector_builder/element_spec.rb +2 -4
- data/spec/watirspec/browser_spec.rb +5 -3
- data/spec/watirspec/capabilities_spec.rb +5 -15
- data/spec/watirspec/cookies_spec.rb +28 -1
- data/spec/watirspec/elements/date_field_spec.rb +18 -1
- data/spec/watirspec/elements/date_time_field_spec.rb +20 -1
- data/spec/watirspec/shadow_root_spec.rb +3 -1
- data/spec/watirspec/support/rspec_matchers.rb +34 -25
- data/spec/watirspec/window_switching_spec.rb +2 -1
- data/watir.gemspec +2 -2
- metadata +5 -6
- data/support/travis.sh +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0bd050e4d97703802051446eb12d01751b5e63a10fe70353f0f955ac2bb9424
|
4
|
+
data.tar.gz: e573957fe4cd87d311af62b9a77ec8c6383f65f1e4ead17e5f117c40f31f87f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9409ddc8d5914e07ce3f8ef316be713d09bdbea6d130dc1bdf6be693930825b25baefd9dc200f5386a1a53955b2bbef7f48375e911897db2db33be4a337b85f3
|
7
|
+
data.tar.gz: fe6668eae425bc81e1a396dd81f41196d72d217eedca95a752e20c038fa43e55c87a951620ae37fc834517cbadf4b7e42b360b86adcdbba0798f929caf2ec866
|
@@ -13,7 +13,7 @@ jobs:
|
|
13
13
|
fail-fast: false
|
14
14
|
matrix:
|
15
15
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
16
|
-
ruby: [
|
16
|
+
ruby: [ 3.0, 3.2 ]
|
17
17
|
steps:
|
18
18
|
- name: Checkout source tree
|
19
19
|
uses: actions/checkout@v2
|
@@ -41,6 +41,14 @@ jobs:
|
|
41
41
|
ruby-version: ${{ matrix.ruby }}
|
42
42
|
- name: Install gems
|
43
43
|
run: bundle install
|
44
|
+
- name: Remove driver directories Windows
|
45
|
+
if: matrix.os == 'windows-latest'
|
46
|
+
run: |
|
47
|
+
rm "$env:ChromeWebDriver" -r -v
|
48
|
+
- name: Remove driver directories Non-Windows
|
49
|
+
if: matrix.os != 'windows-latest'
|
50
|
+
run: |
|
51
|
+
sudo rm -rf $CHROMEWEBDRIVER
|
44
52
|
- name: Run tests
|
45
53
|
run: bundle exec rake spec:chrome
|
46
54
|
env:
|
data/.github/workflows/edge.yml
CHANGED
@@ -13,7 +13,7 @@ jobs:
|
|
13
13
|
fail-fast: false
|
14
14
|
matrix:
|
15
15
|
os: [macos-latest, windows-latest]
|
16
|
-
ruby: [
|
16
|
+
ruby: [ 3.0, 3.2 ]
|
17
17
|
steps:
|
18
18
|
- name: Checkout source tree
|
19
19
|
uses: actions/checkout@v2
|
@@ -32,5 +32,13 @@ jobs:
|
|
32
32
|
ruby-version: ${{ matrix.ruby }}
|
33
33
|
- name: Install gems
|
34
34
|
run: bundle install
|
35
|
+
- name: Remove driver directories Windows
|
36
|
+
if: matrix.os == 'windows-latest'
|
37
|
+
run: |
|
38
|
+
rm "$env:EdgeWebDriver" -r -v
|
39
|
+
- name: Remove driver directories Non-Windows
|
40
|
+
if: matrix.os != 'windows-latest'
|
41
|
+
run: |
|
42
|
+
sudo rm -rf $EDGEWEBDRIVER
|
35
43
|
- name: Run tests
|
36
|
-
run: bundle exec rake spec:
|
44
|
+
run: bundle exec rake spec:edge
|
@@ -13,7 +13,7 @@ jobs:
|
|
13
13
|
fail-fast: false
|
14
14
|
matrix:
|
15
15
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
16
|
-
ruby: [
|
16
|
+
ruby: [ 3.0, 3.2 ]
|
17
17
|
steps:
|
18
18
|
- name: Checkout source tree
|
19
19
|
uses: actions/checkout@v2
|
@@ -41,7 +41,15 @@ jobs:
|
|
41
41
|
ruby-version: ${{ matrix.ruby }}
|
42
42
|
- name: Install gems
|
43
43
|
run: bundle install
|
44
|
+
- name: Remove driver directories Windows
|
45
|
+
if: matrix.os == 'windows-latest'
|
46
|
+
run: |
|
47
|
+
rm "$env:GeckoWebDriver" -r -v
|
48
|
+
- name: Remove driver directories Non-Windows
|
49
|
+
if: matrix.os != 'windows-latest'
|
50
|
+
run: |
|
51
|
+
sudo rm -rf $GECKOWEBDRIVER
|
44
52
|
- name: Run tests
|
45
|
-
run: bundle exec rake spec:
|
53
|
+
run: bundle exec rake spec:firefox
|
46
54
|
env:
|
47
55
|
DISPLAY: :99
|
data/.github/workflows/ie.yml
CHANGED
data/.github/workflows/unit.yml
CHANGED
@@ -21,7 +21,7 @@ jobs:
|
|
21
21
|
- name: Install Ruby
|
22
22
|
uses: ruby/setup-ruby@v1
|
23
23
|
with:
|
24
|
-
ruby-version:
|
24
|
+
ruby-version: 3.0
|
25
25
|
- name: Install gems
|
26
26
|
run: bundle install
|
27
27
|
- name: Run tests
|
@@ -33,7 +33,7 @@ jobs:
|
|
33
33
|
strategy:
|
34
34
|
fail-fast: false
|
35
35
|
matrix:
|
36
|
-
ruby: ['
|
36
|
+
ruby: ['3.0', '3.1', '3.2', 'jruby-9.4.0.0', 'truffleruby-22.3.0']
|
37
37
|
steps:
|
38
38
|
- name: Checkout source tree
|
39
39
|
uses: actions/checkout@v2
|
@@ -54,7 +54,7 @@ jobs:
|
|
54
54
|
- name: Install Ruby
|
55
55
|
uses: ruby/setup-ruby@v1
|
56
56
|
with:
|
57
|
-
ruby-version:
|
57
|
+
ruby-version: 3.0
|
58
58
|
- name: Install gems
|
59
59
|
run: bundle install
|
60
60
|
- run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
@@ -6,17 +6,20 @@ require:
|
|
6
6
|
- rubocop-rspec
|
7
7
|
|
8
8
|
AllCops:
|
9
|
-
TargetRubyVersion:
|
9
|
+
TargetRubyVersion: 3.0
|
10
10
|
NewCops: enable
|
11
11
|
Exclude:
|
12
12
|
- 'lib/watir/elements/html_elements.rb'
|
13
13
|
- 'lib/watir/elements/svg_elements.rb'
|
14
14
|
|
15
|
+
Gemspec/DevelopmentDependencies:
|
16
|
+
Enabled: false
|
17
|
+
|
15
18
|
Layout/SpaceInsideHashLiteralBraces:
|
16
19
|
EnforcedStyle: no_space
|
17
20
|
|
18
21
|
Metrics/AbcSize:
|
19
|
-
Max:
|
22
|
+
Max: 23
|
20
23
|
Exclude:
|
21
24
|
- 'lib/watir/locators/element/selector_builder.rb'
|
22
25
|
- 'lib/watir/locators/element/selector_builder/*.rb'
|
@@ -72,6 +75,9 @@ RSpec/BeforeAfterAll:
|
|
72
75
|
RSpec/ExampleLength:
|
73
76
|
Enabled: false
|
74
77
|
|
78
|
+
RSpec/IndexedLet:
|
79
|
+
Enabled: false
|
80
|
+
|
75
81
|
RSpec/MultipleExpectations:
|
76
82
|
Enabled: false
|
77
83
|
|
@@ -83,6 +89,9 @@ RSpec/NoExpectationExample:
|
|
83
89
|
Exclude:
|
84
90
|
- 'spec/watirspec/cookies_spec.rb'
|
85
91
|
|
92
|
+
Style/ArgumentsForwarding:
|
93
|
+
Enabled: false
|
94
|
+
|
86
95
|
Style/BlockDelimiters:
|
87
96
|
EnforcedStyle: braces_for_chaining
|
88
97
|
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
### 7.3.0 (2023-08-04)
|
2
|
+
|
3
|
+
* Fix implementation of headless to work with Selenium 4.11
|
4
|
+
* Remove support for Ruby 2.7
|
5
|
+
* `DateField` and `DateTimeField` accept inputs that behave like Date (#969)
|
6
|
+
* Add support for `http_only` and `same_site` cookie values (thanks Alexandre ZANNI #968)
|
7
|
+
|
1
8
|
### 7.2.2 (2023-01-03)
|
2
9
|
|
3
10
|
* Fix bug with processing vendor name-spaced capabilities
|
data/lib/watir/capabilities.rb
CHANGED
@@ -105,13 +105,6 @@ module Watir
|
|
105
105
|
options.proxy = proxy
|
106
106
|
end
|
107
107
|
|
108
|
-
def process_vendor_options(opts)
|
109
|
-
return [] unless opts.is_a? Hash
|
110
|
-
|
111
|
-
vendor = opts.select { |key, _val| key.to_s.include?(':') && opts.delete(key) }
|
112
|
-
vendor.map { |k, v| Selenium::WebDriver::Remote::Capabilities.new(k => v) }
|
113
|
-
end
|
114
|
-
|
115
108
|
def convert_timeouts(browser_options)
|
116
109
|
browser_options[:timeouts] ||= {}
|
117
110
|
browser_options[:timeouts].each_key do |key|
|
@@ -139,7 +132,7 @@ module Watir
|
|
139
132
|
options.args << '--no-sandbox'
|
140
133
|
end
|
141
134
|
when :firefox
|
142
|
-
options.headless
|
135
|
+
options.args << '-headless' if @options.delete(:headless)
|
143
136
|
when :safari
|
144
137
|
Selenium::WebDriver::Safari.technology_preview! if @options.delete(:technology_preview)
|
145
138
|
end
|
data/lib/watir/cookies.rb
CHANGED
@@ -43,16 +43,19 @@ module Watir
|
|
43
43
|
# Adds new cookie.
|
44
44
|
#
|
45
45
|
# @example
|
46
|
-
# browser.cookies.add 'my_session', 'BAh7B0kiD3Nlc3Npb25faWQGOgZFRkk', secure: true
|
46
|
+
# browser.cookies.add 'my_session', 'BAh7B0kiD3Nlc3Npb25faWQGOgZFRkk', secure: true, http_only: true
|
47
47
|
#
|
48
48
|
# @param [String] name
|
49
49
|
# @param [String] value
|
50
50
|
# @param [Hash] opts
|
51
51
|
# @option opts [Boolean] :secure
|
52
|
+
# @option opts [Boolean] :http_only
|
52
53
|
# @option opts [String] :path
|
54
|
+
# @option opts [String] :same_site
|
53
55
|
# @option opts [Time, DateTime, NilClass] :expires
|
54
56
|
# @option opts [String] :domain
|
55
57
|
#
|
58
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
|
56
59
|
|
57
60
|
def add(name, value, opts = {})
|
58
61
|
cookie = {
|
@@ -60,7 +63,9 @@ module Watir
|
|
60
63
|
value: value
|
61
64
|
}
|
62
65
|
cookie[:secure] = opts[:secure] if opts.key?(:secure)
|
66
|
+
cookie[:http_only] = opts[:http_only] if opts.key?(:http_only)
|
63
67
|
cookie[:path] = opts[:path] if opts.key?(:path)
|
68
|
+
cookie[:same_site] = opts[:same_site] if opts.key?(:same_site)
|
64
69
|
expires = opts[:expires]
|
65
70
|
if expires
|
66
71
|
cookie[:expires] = expires.is_a?(String) ? ::Time.parse(expires) : expires
|
@@ -117,7 +122,7 @@ module Watir
|
|
117
122
|
#
|
118
123
|
|
119
124
|
def load(file = '.cookies')
|
120
|
-
YAML.
|
125
|
+
YAML.safe_load_file(file, permitted_classes: [::Symbol, ::Time]).each do |c|
|
121
126
|
add(c.delete(:name), c.delete(:value), c)
|
122
127
|
end
|
123
128
|
end
|
@@ -9,8 +9,8 @@ module Watir
|
|
9
9
|
def set!(date)
|
10
10
|
date = Date.parse date if date.is_a?(String)
|
11
11
|
|
12
|
-
message = "DateField##{__callee__} only accepts instances
|
13
|
-
raise ArgumentError, message unless
|
12
|
+
message = "DateField##{__callee__} only accepts instances that respond to #strftime"
|
13
|
+
raise ArgumentError, message unless date.respond_to?(:strftime)
|
14
14
|
|
15
15
|
date_string = date.strftime('%Y-%m-%d')
|
16
16
|
element_call(:wait_for_writable) do
|
@@ -9,8 +9,8 @@ module Watir
|
|
9
9
|
def set!(date)
|
10
10
|
date = ::Time.parse date if date.is_a?(String)
|
11
11
|
|
12
|
-
message = "DateTimeField##{__callee__} only accepts instances
|
13
|
-
raise ArgumentError, message unless
|
12
|
+
message = "DateTimeField##{__callee__} only accepts instances that respond to #strftime"
|
13
|
+
raise ArgumentError, message unless date.respond_to?(:strftime)
|
14
14
|
|
15
15
|
date_time_string = date.strftime('%Y-%m-%dT%H:%M')
|
16
16
|
element_call(:wait_for_writable) do
|
@@ -114,9 +114,9 @@ module Watir
|
|
114
114
|
def parse_select_args(str_or_rx, text, value, label)
|
115
115
|
selectors = {}
|
116
116
|
selectors[:any] = str_or_rx unless str_or_rx.empty?
|
117
|
-
selectors[:text] =
|
118
|
-
selectors[:value] =
|
119
|
-
selectors[:label] =
|
117
|
+
selectors[:text] = [text] if text
|
118
|
+
selectors[:value] = [value] if value
|
119
|
+
selectors[:label] = [label] if label
|
120
120
|
|
121
121
|
raise ArgumentError, "too many arguments used for Select#select: #{selectors}" if selectors.size > 1
|
122
122
|
|
@@ -7,7 +7,7 @@ module Watir
|
|
7
7
|
include Exception
|
8
8
|
attr_reader :custom_attributes, :built
|
9
9
|
|
10
|
-
WILDCARD_ATTRIBUTE = /^(aria|data)_(.+)
|
10
|
+
WILDCARD_ATTRIBUTE = /^(aria|data)_(.+)$/
|
11
11
|
VALID_WHATS = Hash.new([String, Regexp, TrueClass, FalseClass]).merge(adjacent: [::Symbol],
|
12
12
|
xpath: [String],
|
13
13
|
css: [String],
|
data/lib/watir/version.rb
CHANGED
data/lib/watir.rb
CHANGED
data/lib/watirspec.rb
CHANGED
data/spec/locator_spec_helper.rb
CHANGED
@@ -3,9 +3,8 @@
|
|
3
3
|
module LocatorSpecHelper
|
4
4
|
def browser
|
5
5
|
@browser ||= instance_double(Watir::Browser, wd: driver)
|
6
|
-
allow(@browser).to
|
6
|
+
allow(@browser).to receive_messages(browser: @browser, locator_namespace: @locator_namespace || Watir::Locators)
|
7
7
|
allow(@browser).to receive(:is_a?).with(Watir::Browser).and_return(true)
|
8
|
-
allow(@browser).to receive(:locator_namespace).and_return(@locator_namespace || Watir::Locators)
|
9
8
|
@browser
|
10
9
|
end
|
11
10
|
|
@@ -30,8 +29,7 @@ module LocatorSpecHelper
|
|
30
29
|
|
31
30
|
def element_matcher
|
32
31
|
@element_matcher ||= instance_double(Watir::Locators::Element::Matcher)
|
33
|
-
allow(@element_matcher).to
|
34
|
-
allow(@element_matcher).to receive(:selector).and_return(@locator || {})
|
32
|
+
allow(@element_matcher).to receive_messages(query_scope: browser, selector: @locator || {})
|
35
33
|
@element_matcher
|
36
34
|
end
|
37
35
|
|
@@ -59,10 +57,8 @@ module LocatorSpecHelper
|
|
59
57
|
klass = opts.delete(:watir_element) || Watir::HTMLElement
|
60
58
|
el = instance_double(klass, opts)
|
61
59
|
|
62
|
-
allow(el).to
|
63
|
-
allow(el).to receive(:selector_builder).and_return(selector_builder)
|
60
|
+
allow(el).to receive_messages(enabled?: true, selector_builder: selector_builder, selector: @selector || {})
|
64
61
|
allow(el).to receive(:wd).and_return wd_element unless opts.key?(:wd)
|
65
|
-
allow(el).to receive(:selector).and_return(@selector || {})
|
66
62
|
el
|
67
63
|
end
|
68
64
|
|
@@ -31,8 +31,7 @@ module Watir
|
|
31
31
|
|
32
32
|
def halt_service(browser)
|
33
33
|
allow(Selenium::WebDriver::Platform).to receive(:find_binary).and_return(true)
|
34
|
-
allow(File).to
|
35
|
-
allow(File).to receive(:executable?).and_return(true)
|
34
|
+
allow(File).to receive_messages(file?: true, executable?: true)
|
36
35
|
service_class(browser).driver_path = nil
|
37
36
|
end
|
38
37
|
|
@@ -75,7 +74,7 @@ module Watir
|
|
75
74
|
end
|
76
75
|
|
77
76
|
it 'just capabilities has client & capabilities but not service' do
|
78
|
-
caps = Selenium::WebDriver::Remote::Capabilities.
|
77
|
+
caps = Selenium::WebDriver::Remote::Capabilities.new(browser_name: expected_browser(browser_symbol))
|
79
78
|
capabilities = described_class.new(capabilities: caps)
|
80
79
|
args = []
|
81
80
|
expect {
|
@@ -110,7 +109,7 @@ module Watir
|
|
110
109
|
actual_service = args.last[:service]
|
111
110
|
expect(actual_service.instance_variable_get(:@port)).to eq 1234
|
112
111
|
expect(actual_service.instance_variable_get(:@executable_path)).to eq '/path/to/driver'
|
113
|
-
expect(actual_service.instance_variable_get(:@
|
112
|
+
expect(actual_service.instance_variable_get(:@args)).to include '--foo', '--bar'
|
114
113
|
end
|
115
114
|
|
116
115
|
it 'is a bad argument to service' do
|
@@ -159,7 +158,7 @@ module Watir
|
|
159
158
|
end
|
160
159
|
|
161
160
|
it 'accepts both capabilities and Options' do
|
162
|
-
caps = Selenium::WebDriver::Remote::Capabilities.
|
161
|
+
caps = Selenium::WebDriver::Remote::Capabilities.new(browser_name: expected_browser(browser_symbol))
|
163
162
|
opts = options_class(browser_symbol).new
|
164
163
|
|
165
164
|
expect {
|
@@ -392,7 +391,7 @@ module Watir
|
|
392
391
|
it 'accepts capabilities object' do
|
393
392
|
caps = described_class.new(:chrome,
|
394
393
|
url: 'https://example.com/wd/hub',
|
395
|
-
capabilities: Selenium::WebDriver::Remote::Capabilities.chrome)
|
394
|
+
capabilities: Selenium::WebDriver::Remote::Capabilities.new(browser_name: 'chrome'))
|
396
395
|
args = []
|
397
396
|
expect {
|
398
397
|
args = caps.to_args
|
@@ -408,7 +407,7 @@ module Watir
|
|
408
407
|
client = HttpClient.new
|
409
408
|
caps = described_class.new(:chrome,
|
410
409
|
url: 'https://example.com/wd/hub',
|
411
|
-
capabilities: Selenium::WebDriver::Remote::Capabilities.chrome,
|
410
|
+
capabilities: Selenium::WebDriver::Remote::Capabilities.new(browser_name: 'chrome'),
|
412
411
|
http_client: client)
|
413
412
|
args = []
|
414
413
|
expect {
|
@@ -451,7 +450,7 @@ module Watir
|
|
451
450
|
expect {
|
452
451
|
described_class.new(:chrome,
|
453
452
|
url: 'https://example.com/wd/hub',
|
454
|
-
capabilities: Selenium::WebDriver::Remote::Capabilities.chrome,
|
453
|
+
capabilities: Selenium::WebDriver::Remote::Capabilities.new(browser_name: 'chrome'),
|
455
454
|
options: options)
|
456
455
|
}.to raise_exception(ArgumentError, ':capabilities and :options are not both allowed')
|
457
456
|
end
|
@@ -666,8 +666,7 @@ module Watir
|
|
666
666
|
let(:scope_built) { {xpath: ".//*[local-name()='div'][@id='table-rows-test']"} }
|
667
667
|
|
668
668
|
before do
|
669
|
-
allow(query_scope).to
|
670
|
-
allow(query_scope).to receive(:browser).and_return(browser)
|
669
|
+
allow(query_scope).to receive_messages(selector_builder: selector_builder, browser: browser)
|
671
670
|
allow(selector_builder).to receive(:built).and_return(scope_built)
|
672
671
|
end
|
673
672
|
|
@@ -742,8 +741,7 @@ module Watir
|
|
742
741
|
selector_builder = described_class.new(attributes, query_scope)
|
743
742
|
|
744
743
|
allow(selector_builder).to receive(:built).and_return(scope_built)
|
745
|
-
allow(query_scope).to
|
746
|
-
allow(query_scope).to receive(:browser).and_return(browser)
|
744
|
+
allow(query_scope).to receive_messages(selector_builder: selector_builder, browser: browser)
|
747
745
|
allow(query_scope).to receive(:is_a?).with(Watir::Browser).and_return(false)
|
748
746
|
allow(query_scope).to receive(:is_a?).with(Watir::ShadowRoot).and_return(false)
|
749
747
|
allow(query_scope).to receive(:is_a?).with(Watir::IFrame).and_return(true)
|
@@ -353,7 +353,7 @@ module Watir
|
|
353
353
|
|
354
354
|
it 'updates the page when location is changed with setTimeout + window.location' do
|
355
355
|
browser.goto(WatirSpec.url_for('timeout_window_location.html'))
|
356
|
-
browser.wait_while { |b| b.url.
|
356
|
+
browser.wait_while { |b| b.url.match?(/timeout_window_location|blank/) }
|
357
357
|
expect(browser.url).to include('non_control_elements.html')
|
358
358
|
end
|
359
359
|
end
|
@@ -387,7 +387,7 @@ module Watir
|
|
387
387
|
|
388
388
|
it 'returns correct Ruby objects' do
|
389
389
|
expect(browser.execute_script('return {a: 1, "b": 2}')).to eq({'a' => 1, 'b' => 2})
|
390
|
-
expect(browser.execute_script('return [1, 2, "3"]')).to
|
390
|
+
expect(browser.execute_script('return [1, 2, "3"]')).to contain_exactly(1, 2, '3')
|
391
391
|
expect(browser.execute_script('return 1.2 + 1.3')).to eq 2.5
|
392
392
|
expect(browser.execute_script('return 2 + 2')).to eq 4
|
393
393
|
expect(browser.execute_script('return "hello"')).to eq 'hello'
|
@@ -424,7 +424,9 @@ module Watir
|
|
424
424
|
expect(hash['element']).to be_a(Watir::Body)
|
425
425
|
end
|
426
426
|
|
427
|
-
it 'wraps elements in a deep object'
|
427
|
+
it 'wraps elements in a deep object',
|
428
|
+
except: {browser: %i[chrome edge],
|
429
|
+
reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=4536'} do
|
428
430
|
hash = browser.execute_script('return {elements: [document.body], body: {element: document.body }}')
|
429
431
|
|
430
432
|
expect(hash['elements'].first).to be_a(Watir::Body)
|
@@ -21,7 +21,7 @@ module Watir
|
|
21
21
|
let(:browser_symbol) { WatirSpec.implementation.browser_args.first }
|
22
22
|
let(:actual_capabilities) { @browser.wd.capabilities }
|
23
23
|
let(:actual_http) { @browser.wd.instance_variable_get(:@bridge).instance_variable_get(:@http) }
|
24
|
-
let(:actual_service) { @browser.wd.instance_variable_get(:@
|
24
|
+
let(:actual_service) { @browser.wd.instance_variable_get(:@service_manager) }
|
25
25
|
let(:actual_listener) { @browser.wd.instance_variable_get(:@bridge).instance_variable_get(:@listener) }
|
26
26
|
|
27
27
|
before(:all) do
|
@@ -83,7 +83,8 @@ module Watir
|
|
83
83
|
end
|
84
84
|
|
85
85
|
describe 'capabilities' do
|
86
|
-
it 'accepts namespaced value'
|
86
|
+
it 'accepts namespaced value', except: {browser: :ie,
|
87
|
+
reason: 'IE is more strict'} do
|
87
88
|
options = {'key:value' => 'something'}
|
88
89
|
@browser = described_class.new(browser_symbol, options: options)
|
89
90
|
|
@@ -110,18 +111,6 @@ module Watir
|
|
110
111
|
expect(actual_http).to eq client
|
111
112
|
end
|
112
113
|
|
113
|
-
it 'just capabilities has capabilities and watir client without service' do
|
114
|
-
caps = Remote::Capabilities.new(browser_name: browser_name)
|
115
|
-
|
116
|
-
expect {
|
117
|
-
@browser = described_class.new(capabilities: caps)
|
118
|
-
}.to have_deprecated(:capabilities)
|
119
|
-
|
120
|
-
expect(selenium_args[:capabilities]).to eq(caps)
|
121
|
-
expect(selenium_args).not_to include(:service)
|
122
|
-
expect(actual_http).to be_a HttpClient
|
123
|
-
end
|
124
|
-
|
125
114
|
it 'accepts page load and script timeouts in seconds' do
|
126
115
|
options = {page_load_timeout: 11,
|
127
116
|
script_timeout: 12}
|
@@ -205,7 +194,8 @@ module Watir
|
|
205
194
|
expect(actual_listener).to eq listener
|
206
195
|
end
|
207
196
|
|
208
|
-
describe 'proxy'
|
197
|
+
describe 'proxy', except: {browser: :ie,
|
198
|
+
reason: 'Bug in Selenium 4.11 Selenium Manager'} do
|
209
199
|
it 'adds Selenium Proxy to empty Options', except: {browser: :safari,
|
210
200
|
reason: 'Safari does not like proxies'} do
|
211
201
|
proxy = Selenium::WebDriver::Proxy.new(http: '127.0.0.1:8080', ssl: '127.0.0.1:443')
|
@@ -80,6 +80,33 @@ module Watir
|
|
80
80
|
expect(cookie[:path]).to eq '/set_cookie'
|
81
81
|
end
|
82
82
|
|
83
|
+
it 'adds a cookie with samesite value' do
|
84
|
+
browser.goto WatirSpec.url_for 'index.html'
|
85
|
+
|
86
|
+
options = {same_site: 'Strict'}
|
87
|
+
browser.cookies.add 'samesite', 'strict', options
|
88
|
+
|
89
|
+
cookie = browser.cookies.to_a.find { |e| e[:name] == 'samesite' }
|
90
|
+
|
91
|
+
expect(cookie[:name]).to eq 'samesite'
|
92
|
+
expect(cookie[:value]).to eq 'strict'
|
93
|
+
expect(cookie[:same_site]).to eq 'Strict'
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'adds a cookie with httponly value' do
|
97
|
+
browser.goto WatirSpec.url_for 'index.html'
|
98
|
+
|
99
|
+
options = {http_only: true}
|
100
|
+
browser.cookies.add 'httponly', 'true', options
|
101
|
+
|
102
|
+
cookie = browser.cookies.to_a.find { |e| e[:name] == 'httponly' }
|
103
|
+
|
104
|
+
expect(cookie[:name]).to eq 'httponly'
|
105
|
+
expect(cookie[:value]).to eq 'true'
|
106
|
+
expect(cookie[:http_only]).to be true
|
107
|
+
expect(browser.execute_script('return document.cookie')).to be_empty
|
108
|
+
end
|
109
|
+
|
83
110
|
it 'adds a cookie with expiration' do
|
84
111
|
browser.goto WatirSpec.url_for 'index.html'
|
85
112
|
|
@@ -145,7 +172,7 @@ module Watir
|
|
145
172
|
browser.cookies.clear
|
146
173
|
browser.cookies.load file
|
147
174
|
expected = browser.cookies.to_a
|
148
|
-
actual = YAML.
|
175
|
+
actual = YAML.safe_load_file(file, permitted_classes: [::Symbol])
|
149
176
|
|
150
177
|
expected.each { |cookie| cookie.delete(:expires) }
|
151
178
|
actual.each { |cookie| cookie.delete(:expires) }
|
@@ -124,12 +124,29 @@ module Watir
|
|
124
124
|
|
125
125
|
# Manipulation methods
|
126
126
|
describe '#value=' do
|
127
|
-
it 'sets the value of the element' do
|
127
|
+
it 'sets the value of the element to a Date' do
|
128
128
|
date = browser.date_field(id: 'html5_date')
|
129
129
|
date.value = Date.today
|
130
130
|
expect(Date.parse(date.value)).to eq Date.today
|
131
131
|
end
|
132
132
|
|
133
|
+
it 'sets the value of the element to a Time' do
|
134
|
+
date = browser.date_field(id: 'html5_date')
|
135
|
+
date.value = ::Time.now
|
136
|
+
expect(Date.parse(date.value)).to eq Date.today
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'sets the value of the element to an arbitrary class that responds to #strftime' do
|
140
|
+
instance_like_date = ::Object.new
|
141
|
+
def instance_like_date.strftime(_)
|
142
|
+
'2022-10-11'
|
143
|
+
end
|
144
|
+
|
145
|
+
date = browser.date_field(id: 'html5_date')
|
146
|
+
date.value = instance_like_date
|
147
|
+
expect(date.value).to eq '2022-10-11'
|
148
|
+
end
|
149
|
+
|
133
150
|
it 'sets the value when accessed through the enclosing Form' do
|
134
151
|
date_field = browser.form(id: 'new_user').date_field(id: 'html5_date')
|
135
152
|
date_field.value = Date.today
|
@@ -124,7 +124,7 @@ module Watir
|
|
124
124
|
|
125
125
|
# Manipulation methods
|
126
126
|
describe '#value=' do
|
127
|
-
it 'sets the value of the element' do
|
127
|
+
it 'sets the value of the element to a Time' do
|
128
128
|
date_time = ::Time.now
|
129
129
|
date_time_field = browser.date_time_field(id: 'html5_datetime-local')
|
130
130
|
date_time_field.value = date_time
|
@@ -132,6 +132,25 @@ module Watir
|
|
132
132
|
.to eq date_time.strftime('%Y-%m-%dT%H:%M')
|
133
133
|
end
|
134
134
|
|
135
|
+
it 'sets the value of the element to a DateTime' do
|
136
|
+
date_time = DateTime.now
|
137
|
+
date_time_field = browser.date_time_field(id: 'html5_datetime-local')
|
138
|
+
date_time_field.value = date_time
|
139
|
+
expect(::Time.parse(date_time_field.value).strftime('%Y-%m-%dT%H:%M'))
|
140
|
+
.to eq date_time.strftime('%Y-%m-%dT%H:%M')
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'sets the value of the element to an arbitrary class that responds to #strftime' do
|
144
|
+
date_time = ::Object.new
|
145
|
+
def date_time.strftime(_)
|
146
|
+
'2022-10-11T12:13'
|
147
|
+
end
|
148
|
+
|
149
|
+
date_time_field = browser.date_time_field(id: 'html5_datetime-local')
|
150
|
+
date_time_field.value = date_time
|
151
|
+
expect(date_time_field.value).to eq '2022-10-11T12:13'
|
152
|
+
end
|
153
|
+
|
135
154
|
it 'sets the value when accessed through the enclosing Form' do
|
136
155
|
date_time = ::Time.now
|
137
156
|
date_time_field = browser.form(id: 'new_user').date_time_field(id: 'html5_datetime-local')
|
@@ -39,7 +39,7 @@ module Watir
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
describe 'locating'
|
42
|
+
describe 'locating' do
|
43
43
|
it 'locates a nested element' do
|
44
44
|
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
45
45
|
expect(shadow_root.element.id).to eq('shadow_content')
|
@@ -85,6 +85,8 @@ module Watir
|
|
85
85
|
it 'click! elements within the shadow dom' do
|
86
86
|
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
87
87
|
shadow_root.link.click!
|
88
|
+
|
89
|
+
browser.wait_while(url: /shadow_dom|blank/)
|
88
90
|
expect(browser.url).to include('scroll.html')
|
89
91
|
end
|
90
92
|
|
@@ -1,36 +1,45 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
if defined?(RSpec)
|
4
|
-
|
5
|
-
match do |actual|
|
6
|
-
# Suppresses logging output to stdout while ensuring that it is still happening
|
7
|
-
default_output = Selenium::WebDriver.logger.io
|
8
|
-
io = StringIO.new
|
9
|
-
Watir.logger.output = io
|
4
|
+
LEVELS = %w[warning info deprecated].freeze
|
10
5
|
|
11
|
-
|
6
|
+
LEVELS.each do |level|
|
7
|
+
RSpec::Matchers.define "have_#{level}" do |entry|
|
8
|
+
match do |actual|
|
9
|
+
# Suppresses logging output to stdout while ensuring that it is still happening
|
10
|
+
default_output = Watir.logger.io
|
11
|
+
io = StringIO.new
|
12
|
+
Watir.logger.output = io
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
begin
|
15
|
+
actual.call
|
16
|
+
rescue StandardError => e
|
17
|
+
raise e, 'Can not evaluate output when statement raises an exception'
|
18
|
+
ensure
|
19
|
+
Watir.logger.output = default_output
|
20
|
+
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
"instead these deprecations were found: [#{@deprecations_found.join(', ')}]"
|
23
|
-
end
|
24
|
-
"expected :#{deprecation} to have been deprecated, but #{but_message}"
|
25
|
-
end
|
22
|
+
@entries_found = (io.rewind && io.read).scan(/\[:([^\]]*)\]/).flatten.map(&:to_sym)
|
23
|
+
expect(Array(entry).sort).to eq(@entries_found.sort)
|
24
|
+
end
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
failure_message do
|
27
|
+
but_message = if @entries_found.nil? || @entries_found.empty?
|
28
|
+
"no #{entry} entries were reported"
|
29
|
+
else
|
30
|
+
"instead these entries were found: [#{@entries_found.join(', ')}]"
|
31
|
+
end
|
32
|
+
"expected :#{entry} to have been logged, but #{but_message}"
|
33
|
+
end
|
31
34
|
|
32
|
-
|
33
|
-
|
35
|
+
failure_message_when_negated do
|
36
|
+
but_message = "it was found among these entries: [#{@entries_found.join(', ')}]"
|
37
|
+
"expected :#{entry} not to have been logged, but #{but_message}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def supports_block_expectations?
|
41
|
+
true
|
42
|
+
end
|
34
43
|
end
|
35
44
|
end
|
36
45
|
|
@@ -146,6 +146,7 @@ module Watir
|
|
146
146
|
browser.goto WatirSpec.url_for('window_switching.html')
|
147
147
|
browser.a(id: 'open').click
|
148
148
|
browser.windows.wait_until(size: 2)
|
149
|
+
browser.wait_until { |b| !b.window(title: 'about:blank').exist? }
|
149
150
|
end
|
150
151
|
|
151
152
|
it 'allows actions on first window after opening second',
|
@@ -474,7 +475,7 @@ module Watir
|
|
474
475
|
|
475
476
|
browser.window.minimize
|
476
477
|
|
477
|
-
browser.wait_until { |b| b.execute_script('return document.visibilityState;')
|
478
|
+
browser.wait_until { |b| !%w[visible normal].include?(b.execute_script('return document.visibilityState;')) }
|
478
479
|
|
479
480
|
expect(browser.execute_script('return document.visibilityState;')).to eq 'hidden'
|
480
481
|
browser.window.maximize
|
data/watir.gemspec
CHANGED
@@ -8,7 +8,7 @@ require 'watir/version'
|
|
8
8
|
Gem::Specification.new do |s|
|
9
9
|
s.name = 'watir'
|
10
10
|
s.version = Watir::VERSION
|
11
|
-
s.required_ruby_version = '>=
|
11
|
+
s.required_ruby_version = '>= 3.0.0'
|
12
12
|
|
13
13
|
s.platform = Gem::Platform::RUBY
|
14
14
|
s.authors = ['Alex Rodionov', 'Titus Fortner', 'Justin Ko']
|
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
|
|
42
42
|
s.add_development_dependency 'rubocop-rake', '~> 0.6'
|
43
43
|
s.add_development_dependency 'rubocop-rspec', '~> 2.16'
|
44
44
|
s.add_development_dependency 'selenium_statistics'
|
45
|
-
s.add_development_dependency 'selenium-webdriver', '~> 4.
|
45
|
+
s.add_development_dependency 'selenium-webdriver', '~> 4.11'
|
46
46
|
s.add_development_dependency 'simplecov-console'
|
47
47
|
s.add_development_dependency 'webidl', '>= 0.2.2'
|
48
48
|
s.add_development_dependency 'yard', '> 0.9.11'
|
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: 7.
|
4
|
+
version: 7.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Rodionov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-08-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: regexp_parser
|
@@ -226,14 +226,14 @@ dependencies:
|
|
226
226
|
requirements:
|
227
227
|
- - "~>"
|
228
228
|
- !ruby/object:Gem::Version
|
229
|
-
version: '4.
|
229
|
+
version: '4.11'
|
230
230
|
type: :development
|
231
231
|
prerelease: false
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
234
|
- - "~>"
|
235
235
|
- !ruby/object:Gem::Version
|
236
|
-
version: '4.
|
236
|
+
version: '4.11'
|
237
237
|
- !ruby/object:Gem::Dependency
|
238
238
|
name: simplecov-console
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -627,7 +627,6 @@ files:
|
|
627
627
|
- spec/watirspec/window_switching_spec.rb
|
628
628
|
- spec/watirspec_helper.rb
|
629
629
|
- support/doctest_helper.rb
|
630
|
-
- support/travis.sh
|
631
630
|
- support/version_differ.rb
|
632
631
|
- watir.gemspec
|
633
632
|
homepage: https://github.com/watir/watir
|
@@ -643,7 +642,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
643
642
|
requirements:
|
644
643
|
- - ">="
|
645
644
|
- !ruby/object:Gem::Version
|
646
|
-
version:
|
645
|
+
version: 3.0.0
|
647
646
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
648
647
|
requirements:
|
649
648
|
- - ">="
|
data/support/travis.sh
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
set -e
|
4
|
-
set -x
|
5
|
-
|
6
|
-
sh -e /etc/init.d/xvfb start
|
7
|
-
|
8
|
-
if [[ "$RAKE_TASK" = "yard:doctest" ]]; then
|
9
|
-
mkdir ~/.yard
|
10
|
-
bundle exec yard config -a autoload_plugins yard-doctest
|
11
|
-
fi
|
12
|
-
|
13
|
-
pwd
|
14
|
-
echo "$RUBY_VERSION" >> .ruby-version
|
15
|
-
cat .ruby-version
|