Merge pull request #2564 from teamcapybara/click_should_respect_scope

Click should respect scope
This commit is contained in:
Thomas Walpole 2022-06-12 16:43:57 -07:00 committed by GitHub
commit a5b5a04d81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 81 additions and 20 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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')

View File

@ -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')

View File

@ -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

View File

@ -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

View File

@ -35,8 +35,8 @@
</ul>
</div>
<div id="another_foo">
<div id="another_foo" onclick="this.innerHTML = 'I was clicked';">
<ul>
<li>With Simple HTML: <a href="/">Go</a>
<li>With Simple HTML: <a href="/">Go</a></li>
</ul>
</div>

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true
module Capybara
VERSION = '3.37.1'
VERSION = '3.38.0'
end