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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 635faa9aa111937b2d90f6ab1585a148d8eea5cf375b4a1dc4d3e164b3e24c38
4
- data.tar.gz: 31bb99fbba606a62c369c4a89b8c12764e00feff89048179e5958bf4b0abca3d
3
+ metadata.gz: a0bd050e4d97703802051446eb12d01751b5e63a10fe70353f0f955ac2bb9424
4
+ data.tar.gz: e573957fe4cd87d311af62b9a77ec8c6383f65f1e4ead17e5f117c40f31f87f8
5
5
  SHA512:
6
- metadata.gz: 131f2cccc8debc1afd14462f90fbafff4d5f349b4caa193247f2adf8efa6f91e03c8218ff8bec23a86d8c4c8e4de18b1c63b38f6cc5c9c878420a9bc01d816f3
7
- data.tar.gz: c4f5abb5e301fcee62f25a091f299933f2c10e1b703a3378fcd6d850012d989f3e5ac2f9d8fcec170fee44f97ec4758c5894d85e7a7a62d3efaf2f609a733676
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: [ 2.7, 3.2 ]
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:
@@ -13,7 +13,7 @@ jobs:
13
13
  fail-fast: false
14
14
  matrix:
15
15
  os: [macos-latest, windows-latest]
16
- ruby: [ 2.7, 3.2 ]
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:chrome
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: [ 2.7, 3.2 ]
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:chrome
53
+ run: bundle exec rake spec:firefox
46
54
  env:
47
55
  DISPLAY: :99
@@ -12,7 +12,7 @@ jobs:
12
12
  strategy:
13
13
  fail-fast: false
14
14
  matrix:
15
- ruby: [ 2.7, 3.2 ]
15
+ ruby: [ 3.0, 3.2 ]
16
16
  steps:
17
17
  - name: Checkout source tree
18
18
  uses: actions/checkout@v2
@@ -12,7 +12,7 @@ jobs:
12
12
  strategy:
13
13
  fail-fast: false
14
14
  matrix:
15
- ruby: [ 2.7, 3.2 ]
15
+ ruby: [ 3.0, 3.2 ]
16
16
  steps:
17
17
  - name: Checkout source tree
18
18
  uses: actions/checkout@v2
@@ -21,7 +21,7 @@ jobs:
21
21
  - name: Install Ruby
22
22
  uses: ruby/setup-ruby@v1
23
23
  with:
24
- ruby-version: 2.7
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: ['2.7', '3.0', '3.1', '3.2', 'jruby-9.4.0.0', 'truffleruby-22.3.0']
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: 2.7
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: 2.7
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
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
@@ -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! if @options.delete(: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.safe_load(File.read(file), permitted_classes: [::Symbol, ::Time]).each do |c|
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 of Date or Time"
13
- raise ArgumentError, message unless [Date, ::Time].include?(date.class)
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 of DateTime or Time"
13
- raise ArgumentError, message unless [DateTime, ::Time].include?(date.class)
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] = Array[text] if text
118
- selectors[:value] = Array[value] if value
119
- selectors[:label] = Array[label] if 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)_(.+)$/.freeze
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],
@@ -21,7 +21,7 @@ module Watir
21
21
  values_to_match[:text] = values_to_match.delete(key)
22
22
  end
23
23
  else
24
- return
24
+ return false
25
25
  end
26
26
 
27
27
  super
data/lib/watir/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Watir
4
- VERSION = '7.2.2'
4
+ VERSION = '7.3.0'
5
5
  end
data/lib/watir.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'net/http'
3
4
  require 'selenium-webdriver'
4
5
  require 'time'
5
6
 
@@ -39,7 +39,7 @@ module WatirSpec
39
39
  end
40
40
 
41
41
  def inspect_args
42
- selenium_opts = browser_args.last
42
+ selenium_opts = browser_args.last.dup
43
43
 
44
44
  options = selenium_opts.delete(:options)
45
45
  args = ["#{browser_args.first} tests:\n"]
data/lib/watirspec.rb CHANGED
@@ -33,7 +33,7 @@ module WatirSpec
33
33
 
34
34
  def load_support
35
35
  root = File.expand_path('../spec/watirspec', __dir__)
36
- Dir.glob("#{root}/support/**/*.rb").sort.each do |file|
36
+ Dir.glob("#{root}/support/**/*.rb").each do |file|
37
37
  require file
38
38
  end
39
39
  end
@@ -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 receive(:browser).and_return(@browser)
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 receive(:query_scope).and_return(browser)
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 receive(:enabled?).and_return true
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 receive(:file?).and_return(true)
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.send(browser_symbol)
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(:@extra_args)).to include '--foo', '--bar'
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.send(browser_symbol)
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 receive(:selector_builder).and_return(selector_builder)
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 receive(:selector_builder).and_return(selector_builder)
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.include? 'timeout_window_location.html' }
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 match_array([1, 2, '3'])
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' do
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(:@service) }
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' do
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' do
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.safe_load(File.read(file), permitted_classes: [::Symbol])
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', except: {browser: :firefox, reason: 'location not supported yet'} do
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
- RSpec::Matchers.define :have_deprecated do |deprecation|
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
- actual.call
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
- Watir.logger.output = default_output
14
- @deprecations_found = (io.rewind && io.read).scan(/DEPRECATION\] \[:([^\]]*)\]/).flatten.map(&:to_sym)
15
- expect(Array(deprecation).sort).to eq(@deprecations_found.sort)
16
- end
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
- failure_message do
19
- but_message = if @deprecations_found.nil? || @deprecations_found.empty?
20
- 'no deprecations were found'
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
- failure_message_when_negated do
28
- but_message = "it was found among these deprecations: [#{@deprecations_found.join(', ')}]"
29
- "expected :#{deprecation} not to have been deprecated, but #{but_message}"
30
- end
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
- def supports_block_expectations?
33
- true
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;') != 'visible' }
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 = '>= 2.7.0'
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.7'
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.2.2
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-01-03 00:00:00.000000000 Z
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.7'
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.7'
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: 2.7.0
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