Add w3c_click_offset setting to allow click offsets from element centers
This commit is contained in:
parent
34889915f7
commit
2f2d822471
|
@ -97,6 +97,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)
|
||||
#
|
||||
# #### DSL Options
|
||||
#
|
||||
|
@ -506,4 +507,5 @@ Capybara.configure do |config|
|
|||
config.predicates_wait = true
|
||||
config.default_normalize_ws = false
|
||||
config.allow_gumbo = false
|
||||
config.w3c_click_offset = false
|
||||
end
|
||||
|
|
|
@ -157,13 +157,16 @@ module Capybara
|
|||
# Both x: and y: must be specified if an offset is wanted, if not specified the click will occur at the middle of the element.
|
||||
# @overload $0(*modifier_keys, wait: nil, **offset)
|
||||
# @param *modifier_keys [:alt, :control, :meta, :shift] ([]) Keys to be held down when clicking
|
||||
# @option offset [Integer] x X coordinate to offset the click location from the top left corner of the element
|
||||
# @option offset [Integer] y Y coordinate to offset the click location from the top left corner of the element
|
||||
# @option options [Integer] x X coordinate to offset the click location. If {Capybara.configure w3c_click_offset} is `true` the
|
||||
# offset will be from the element center, otherwise it will be from the top left corner of the element
|
||||
# @option options [Integer] y Y coordinate to offset the click location. If {Capybara.configure w3c_click_offset} is `true` the
|
||||
# offset will be from the element center, otherwise it will be from the top left corner of the element
|
||||
# @return [Capybara::Node::Element] The element
|
||||
def click(*keys, wait: nil, **offset)
|
||||
raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ offset[:x] ^ offset[:y]
|
||||
def click(*keys, wait: nil, **options)
|
||||
raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ options[:x] ^ options[:y]
|
||||
|
||||
synchronize(wait) { base.click(Array(keys), offset) }
|
||||
options[:offset] = :center if session_options.w3c_click_offset
|
||||
synchronize(wait) { base.click(Array(keys), options) }
|
||||
self
|
||||
end
|
||||
|
||||
|
|
|
@ -63,8 +63,9 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|||
native.remove_attribute('selected')
|
||||
end
|
||||
|
||||
def click(keys = [], **offset)
|
||||
raise ArgumentError, 'The RackTest driver does not support click options' unless keys.empty? && offset.empty?
|
||||
def click(keys = [], **options)
|
||||
options.delete(:offset)
|
||||
raise ArgumentError, 'The RackTest driver does not support click options' unless keys.empty? && options.empty?
|
||||
|
||||
if link?
|
||||
follow_link
|
||||
|
|
|
@ -328,7 +328,13 @@ private
|
|||
end
|
||||
|
||||
def action_with_modifiers(click_options)
|
||||
actions = browser_action.move_to(native, *click_options.coords)
|
||||
actions = browser_action.tap do |acts|
|
||||
if click_options.center_offset? && click_options.coords?
|
||||
acts.move_to(native).move_by(*click_options.coords)
|
||||
else
|
||||
acts.move_to(native, *click_options.coords)
|
||||
end
|
||||
end
|
||||
modifiers_down(actions, click_options.keys)
|
||||
yield actions
|
||||
modifiers_up(actions, click_options.keys)
|
||||
|
@ -483,6 +489,10 @@ private
|
|||
[options[:x], options[:y]]
|
||||
end
|
||||
|
||||
def center_offset?
|
||||
options[:offset] == :center
|
||||
end
|
||||
|
||||
def empty?
|
||||
keys.empty? && !coords?
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ module Capybara
|
|||
automatic_reload match exact exact_text raise_server_errors visible_text_only
|
||||
automatic_label_click enable_aria_label save_path asset_host default_host app_host
|
||||
server_host server_port server_errors default_set_options disable_animation test_id
|
||||
predicates_wait default_normalize_ws].freeze
|
||||
predicates_wait default_normalize_ws w3c_click_offset].freeze
|
||||
|
||||
attr_accessor(*OPTIONS)
|
||||
|
||||
|
@ -59,6 +59,8 @@ module Capybara
|
|||
# See {Capybara.configure}
|
||||
# @!method default_normalize_ws
|
||||
# See {Capybara.configure}
|
||||
# @!method w3c_click_offset
|
||||
# See {Capybara.configure}
|
||||
|
||||
remove_method :server_host
|
||||
|
||||
|
|
|
@ -636,25 +636,52 @@ Capybara::SpecHelper.spec 'node' do
|
|||
expect { obscured.click(wait: 0) }.to(raise_error { |e| expect(e).to be_an_invalid_element_error(@session) })
|
||||
end
|
||||
|
||||
context "offset" do
|
||||
context 'offset', requires: [:js] do
|
||||
before do
|
||||
@session.visit('/offset')
|
||||
@clicker = @session.find(:id, 'clicker')
|
||||
end
|
||||
|
||||
it 'should offset from top left of element' do
|
||||
@clicker.click(x: 10, y: 5)
|
||||
expect(@session).to have_text(/clicked at 110,105/)
|
||||
context 'when w3c_click_offset is false' do
|
||||
before do
|
||||
Capybara.w3c_click_offset = false
|
||||
end
|
||||
|
||||
it 'should offset from top left of element' do
|
||||
@clicker.click(x: 10, y: 5)
|
||||
expect(@session).to have_text(/clicked at 110,105/)
|
||||
end
|
||||
|
||||
it 'should offset outside the element' do
|
||||
@clicker.click(x: -15, y: -10)
|
||||
expect(@session).to have_text(/clicked at 85,90/)
|
||||
end
|
||||
|
||||
it 'should default to click the middle' do
|
||||
@clicker.click
|
||||
expect(@session).to have_text(/clicked at 150,150/)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should offset outside the element' do
|
||||
@clicker.click(x: -15, y: -10)
|
||||
expect(@session).to have_text(/clicked at 85,90/)
|
||||
end
|
||||
context 'when w3c_click_offset is true' do
|
||||
before do
|
||||
Capybara.w3c_click_offset = true
|
||||
end
|
||||
|
||||
it 'should default to click the middle' do
|
||||
@clicker.click
|
||||
expect(@session).to have_text(/clicked at 150,150/)
|
||||
it 'should offset from center of element' do
|
||||
@clicker.click(x: 10, y: 5)
|
||||
expect(@session).to have_text(/clicked at 160,155/)
|
||||
end
|
||||
|
||||
it 'should offset outside from center of element' do
|
||||
@clicker.click(x: -65, y: -60)
|
||||
expect(@session).to have_text(/clicked at 85,90/)
|
||||
end
|
||||
|
||||
it 'should default to click the middle' do
|
||||
@clicker.click
|
||||
expect(@session).to have_text(/clicked at 150,150/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -692,7 +719,7 @@ Capybara::SpecHelper.spec 'node' do
|
|||
expect { obscured.double_click }.not_to raise_error
|
||||
end
|
||||
|
||||
context "offset" do
|
||||
context 'offset', requires: [:js] do
|
||||
before do
|
||||
@session.visit('/offset')
|
||||
@clicker = @session.find(:id, 'clicker')
|
||||
|
@ -748,7 +775,7 @@ Capybara::SpecHelper.spec 'node' do
|
|||
expect { obscured.right_click }.not_to raise_error
|
||||
end
|
||||
|
||||
context "offset" do
|
||||
context 'offset', requires: [:js] do
|
||||
before do
|
||||
@session.visit('/offset')
|
||||
@clicker = @session.find(:id, 'clicker')
|
||||
|
|
|
@ -36,6 +36,7 @@ module Capybara
|
|||
Capybara.predicates_wait = true
|
||||
Capybara.default_normalize_ws = false
|
||||
Capybara.allow_gumbo = true
|
||||
Capybara.w3c_click_offset = false
|
||||
reset_threadsafe
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue