diff --git a/History.md b/History.md index 40ae15e2..eb11bc1c 100644 --- a/History.md +++ b/History.md @@ -1,14 +1,25 @@ -# Version 3.37.2 +# Version 3.38.0 Release date: unreleased +### Changed + +* Capybara.w3c_click_offset now defaults to true. If you need click offsets to be from the elements top left corner set it to false in your config + +### Added + +* Support upcoming Selenium 4.3 changes to click offset calculations +* `click`, `double_click`, `right_click` can now be called on the session to click the currently scoped element (or document) +* `Session#within` now passes the scoped element to the block + ### Fixed * Support file upload requirement changes in upcoming rack-test release * Use higher precision clock in Capybara::Helpers::Timer if available * rack-test driver behavior with \r\n - Issue #2547 [Stefan Hoffmann] +* Updated for deprecation of positional parameters in Selenium::WebDriver::ActionBuilder#pause # Version 3.37.1 -Relesae date: 2022-05-09 +Release date: 2022-05-09 ### Fixed diff --git a/lib/capybara.rb b/lib/capybara.rb index 9c65f87a..690590df 100644 --- a/lib/capybara.rb +++ b/lib/capybara.rb @@ -101,7 +101,7 @@ module Capybara # and {configure raise_server_errors} is `true`. # - **test_id** (Symbol, String, `nil` = `nil`) - Optional attribute to match locator against with built-in selectors along with id. # - **threadsafe** (Boolean = `false`) - Whether sessions can be configured individually. - # - **w3c_click_offset** (Boolean = 'false') - Whether click offsets should be from element center (true) or top left (false) + # - **w3c_click_offset** (Boolean = 'true') - Whether click offsets should be from element center (true) or top left (false) # # #### DSL Options # @@ -514,5 +514,5 @@ Capybara.configure do |config| config.predicates_wait = true config.default_normalize_ws = false config.use_html5_parsing = false - config.w3c_click_offset = false + config.w3c_click_offset = true end diff --git a/lib/capybara/selenium/logger_suppressor.rb b/lib/capybara/selenium/logger_suppressor.rb index a0372003..57ef6e4d 100644 --- a/lib/capybara/selenium/logger_suppressor.rb +++ b/lib/capybara/selenium/logger_suppressor.rb @@ -18,6 +18,10 @@ module Capybara end end + def warn(*args, **opts) + super unless @suppress_for_capybara + end + def suppress_deprecations prev_suppress_for_capybara, @suppress_for_capybara = @suppress_for_capybara, true yield diff --git a/lib/capybara/selenium/node.rb b/lib/capybara/selenium/node.rb index 6d27ff3c..7ef8e92a 100644 --- a/lib/capybara/selenium/node.rb +++ b/lib/capybara/selenium/node.rb @@ -113,11 +113,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node action.click(target) else action.click_and_hold(target) - if w3c? - action.pause(action.pointer_inputs.first, click_options.delay) - else - action.pause(click_options.delay) - end + action_pause(action, click_options.delay) action.release end end @@ -138,9 +134,9 @@ class Capybara::Selenium::Node < Capybara::Driver::Node action.context_click(target) elsif w3c? action.move_to(target) if target - action.pointer_down(:right) - .pause(action.pointer_inputs.first, click_options.delay) - .pointer_up(:right) + action.pointer_down(:right).then do |act| + action_pause(act, click_options.delay) + end.pointer_up(:right) else raise ArgumentError, 'Delay is not supported when right clicking with legacy (non-w3c) selenium driver' end @@ -413,10 +409,30 @@ private def action_with_modifiers(click_options) actions = browser_action.tap do |acts| - if click_options.center_offset? && click_options.coords? - acts.move_to(native).move_by(*click_options.coords) + if click_options.coords? + if click_options.center_offset? + if Selenium::WebDriver::VERSION.to_f >= 4.3 + acts.move_to(native, *click_options.coords) + else + ::Selenium::WebDriver.logger.suppress_deprecations do + acts.move_to(native).move_by(*click_options.coords) + end + end + elsif Selenium::WebDriver::VERSION.to_f >= 4.3 + right_by, down_by = *click_options.coords + size = native.size + left_offset = (size[:width] / 2).to_i + top_offset = (size[:height] / 2).to_i + left = -left_offset + right_by + top = -top_offset + down_by + acts.move_to(native, left, top) + else + ::Selenium::WebDriver.logger.suppress_deprecations do + acts.move_to(native, *click_options.coords) + end + end else - acts.move_to(native, *click_options.coords) + acts.move_to(native) end end modifiers_down(actions, click_options.keys) @@ -459,6 +475,18 @@ private capabilities.is_a?(::Selenium::WebDriver::Remote::W3C::Capabilities) end + def action_pause(action, duration) + if w3c? + if Selenium::WebDriver::VERSION.to_f >= 4.2 + action.pause(device: action.pointer_inputs.first, duration: duration) + else + action.pause(action.pointer_inputs.first, duration) + end + else + action.pause(duration) + end + end + def normalize_keys(keys) keys.map do |key| case key diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 9918453e..d5a70e6a 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -40,6 +40,7 @@ module Capybara NODE_METHODS = %i[ all first attach_file text check choose scroll_to scroll_by + click double_click right_click click_link_or_button click_button click_link fill_in find find_all find_button find_by_id find_field find_link has_content? has_text? has_css? has_no_content? has_no_text? @@ -360,7 +361,7 @@ module Capybara new_scope = args.first.respond_to?(:to_capybara_node) ? args.first.to_capybara_node : find(*args, **kw_args) begin scopes.push(new_scope) - yield if block_given? + yield new_scope if block_given? ensure scopes.pop end diff --git a/lib/capybara/spec/session/check_spec.rb b/lib/capybara/spec/session/check_spec.rb index f747f385..eec03567 100644 --- a/lib/capybara/spec/session/check_spec.rb +++ b/lib/capybara/spec/session/check_spec.rb @@ -239,6 +239,7 @@ Capybara::SpecHelper.spec '#check' do context 'with allow_label_click options', requires: [:js] do it 'should allow offsets to click location on label' do + Capybara.w3c_click_offset = false expect(@session.find(:checkbox, 'form_cars_lotus', unchecked: true, visible: :hidden)).to be_truthy @session.check('form_cars_lotus', allow_label_click: { x: 90, y: 10 }) @session.click_button('awesome') diff --git a/lib/capybara/spec/session/node_spec.rb b/lib/capybara/spec/session/node_spec.rb index e8cda108..a58824aa 100644 --- a/lib/capybara/spec/session/node_spec.rb +++ b/lib/capybara/spec/session/node_spec.rb @@ -775,6 +775,7 @@ Capybara::SpecHelper.spec 'node' do end it 'should allow to adjust the click offset', requires: [:js] do + Capybara.w3c_click_offset = false @session.visit('with_js') @session.find(:css, '#click-test').click(x: 5, y: 5) link = @session.find(:link, 'has-been-clicked') @@ -901,6 +902,7 @@ Capybara::SpecHelper.spec 'node' do end it 'should allow to adjust the offset', requires: [:js] do + Capybara.w3c_click_offset = false @session.visit('with_js') @session.find(:css, '#click-test').double_click(x: 10, y: 5) link = @session.find(:link, 'has-been-double-clicked') @@ -987,6 +989,7 @@ Capybara::SpecHelper.spec 'node' do end it 'should allow to adjust the offset', requires: [:js] do + Capybara.w3c_click_offset = false @session.visit('with_js') @session.find(:css, '#click-test').right_click(x: 10, y: 10) link = @session.find(:link, 'has-been-right-clicked') diff --git a/lib/capybara/spec/session/within_spec.rb b/lib/capybara/spec/session/within_spec.rb index 4314a20d..016cc0bc 100644 --- a/lib/capybara/spec/session/within_spec.rb +++ b/lib/capybara/spec/session/within_spec.rb @@ -49,6 +49,19 @@ Capybara::SpecHelper.spec '#within' do expect { @session.text }.to raise_error(StandardError) end end + + it 'should pass scope element to the block' do + @session.within(:css, '#another_foo') do |scope| + expect(scope).to match_css('#another_foo') + end + end + + it 'should scope click', requires: [:js] do + @session.within(:css, '#another_foo') do |scope| + @session.click + expect(scope).to have_text('I was clicked') + end + end end context 'with XPath selector' do diff --git a/lib/capybara/spec/spec_helper.rb b/lib/capybara/spec/spec_helper.rb index 58d2a60c..0b649eaa 100644 --- a/lib/capybara/spec/spec_helper.rb +++ b/lib/capybara/spec/spec_helper.rb @@ -37,7 +37,7 @@ module Capybara Capybara.predicates_wait = true Capybara.default_normalize_ws = false Capybara.use_html5_parsing = !ENV['HTML5_PARSING'].nil? - Capybara.w3c_click_offset = false + Capybara.w3c_click_offset = true reset_threadsafe end diff --git a/lib/capybara/spec/views/with_scope.erb b/lib/capybara/spec/views/with_scope.erb index 638e62dc..87be9637 100644 --- a/lib/capybara/spec/views/with_scope.erb +++ b/lib/capybara/spec/views/with_scope.erb @@ -35,8 +35,8 @@ -
+
diff --git a/lib/capybara/version.rb b/lib/capybara/version.rb index de96e379..5a437c95 100644 --- a/lib/capybara/version.rb +++ b/lib/capybara/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Capybara - VERSION = '3.37.1' + VERSION = '3.38.0' end