mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Implement click delay
This commit is contained in:
parent
971eea9b23
commit
a307120d3d
6 changed files with 68 additions and 7 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
# Version 3.32.0
|
||||||
|
Relesae date: unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* Support `delay` setting on click and right_click with Selenium
|
||||||
|
|
||||||
# Version 3.31.1
|
# Version 3.31.1
|
||||||
Release date: unreleased
|
Release date: unreleased
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,7 @@ module Capybara
|
||||||
# offset will be from the element center, otherwise it will be from the top left corner of the element
|
# 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
|
# @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
|
# offset will be from the element center, otherwise it will be from the top left corner of the element
|
||||||
|
# @option options [Float] delay Delay between the mouse down and mouse up events in seconds (0)
|
||||||
# @return [Capybara::Node::Element] The element
|
# @return [Capybara::Node::Element] The element
|
||||||
def click(*keys, **options)
|
def click(*keys, **options)
|
||||||
perform_click_action(keys, **options) do |k, opts|
|
perform_click_action(keys, **options) do |k, opts|
|
||||||
|
@ -178,6 +179,7 @@ module Capybara
|
||||||
#
|
#
|
||||||
# @macro action_waiting_behavior
|
# @macro action_waiting_behavior
|
||||||
# @macro click_modifiers
|
# @macro click_modifiers
|
||||||
|
# @option options [Float] delay Delay between the mouse down and mouse up events in seconds (0)
|
||||||
# @return [Capybara::Node::Element] The element
|
# @return [Capybara::Node::Element] The element
|
||||||
def right_click(*keys, **options)
|
def right_click(*keys, **options)
|
||||||
perform_click_action(keys, **options) do |k, opts|
|
perform_click_action(keys, **options) do |k, opts|
|
||||||
|
|
|
@ -104,7 +104,14 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
||||||
click_options = ClickOptions.new(keys, options)
|
click_options = ClickOptions.new(keys, options)
|
||||||
return native.click if click_options.empty?
|
return native.click if click_options.empty?
|
||||||
|
|
||||||
click_with_options(click_options)
|
perform_with_options(click_options) do |action|
|
||||||
|
target = click_options.coords? ? nil : native
|
||||||
|
if click_options.delay.zero?
|
||||||
|
action.click(target)
|
||||||
|
else
|
||||||
|
action.click_and_hold(target).pause(action.pointer_inputs.first, click_options.delay).release
|
||||||
|
end
|
||||||
|
end
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
if e.is_a?(::Selenium::WebDriver::Error::ElementClickInterceptedError) ||
|
if e.is_a?(::Selenium::WebDriver::Error::ElementClickInterceptedError) ||
|
||||||
e.message.match?(/Other element would receive the click/)
|
e.message.match?(/Other element would receive the click/)
|
||||||
|
@ -116,14 +123,24 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
||||||
|
|
||||||
def right_click(keys = [], **options)
|
def right_click(keys = [], **options)
|
||||||
click_options = ClickOptions.new(keys, options)
|
click_options = ClickOptions.new(keys, options)
|
||||||
click_with_options(click_options) do |action|
|
perform_with_options(click_options) do |action|
|
||||||
click_options.coords? ? action.context_click : action.context_click(native)
|
target = click_options.coords? ? nil : native
|
||||||
|
if click_options.delay.zero?
|
||||||
|
action.context_click(target)
|
||||||
|
else
|
||||||
|
action.move_to(target) if target
|
||||||
|
action.pointer_down(:right)
|
||||||
|
.pause(action.pointer_inputs.first, click_options.delay)
|
||||||
|
.pointer_up(:right)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def double_click(keys = [], **options)
|
def double_click(keys = [], **options)
|
||||||
click_options = ClickOptions.new(keys, options)
|
click_options = ClickOptions.new(keys, options)
|
||||||
click_with_options(click_options) do |action|
|
raise ArgumentError, "double_click doesn't support a delay option" unless click_options.delay.zero?
|
||||||
|
|
||||||
|
perform_with_options(click_options) do |action|
|
||||||
click_options.coords? ? action.double_click : action.double_click(native)
|
click_options.coords? ? action.double_click : action.double_click(native)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -264,7 +281,9 @@ private
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_with_options(click_options)
|
def perform_with_options(click_options, &block)
|
||||||
|
raise ArgumentError, 'A block must be provided' unless block
|
||||||
|
|
||||||
scroll_if_needed do
|
scroll_if_needed do
|
||||||
action_with_modifiers(click_options) do |action|
|
action_with_modifiers(click_options) do |action|
|
||||||
if block_given?
|
if block_given?
|
||||||
|
@ -550,7 +569,11 @@ private
|
||||||
end
|
end
|
||||||
|
|
||||||
def empty?
|
def empty?
|
||||||
keys.empty? && !coords?
|
keys.empty? && !coords? && delay.zero?
|
||||||
|
end
|
||||||
|
|
||||||
|
def delay
|
||||||
|
options[:delay] || 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private_constant :ClickOptions
|
private_constant :ClickOptions
|
||||||
|
|
|
@ -85,7 +85,7 @@ private
|
||||||
(driver.options[:native_displayed] != false) && !ENV['DISABLE_CAPYBARA_SELENIUM_OPTIMIZATIONS']
|
(driver.options[:native_displayed] != false) && !ENV['DISABLE_CAPYBARA_SELENIUM_OPTIMIZATIONS']
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_with_options(click_options)
|
def perform_with_options(click_options)
|
||||||
# Firefox/marionette has an issue clicking with offset near viewport edge
|
# Firefox/marionette has an issue clicking with offset near viewport edge
|
||||||
# scroll element to middle just in case
|
# scroll element to middle just in case
|
||||||
scroll_to_center if click_options.coords?
|
scroll_to_center if click_options.coords?
|
||||||
|
|
|
@ -153,6 +153,7 @@ $(function() {
|
||||||
});
|
});
|
||||||
$('#click-test').on({
|
$('#click-test').on({
|
||||||
click: function(e) {
|
click: function(e) {
|
||||||
|
window.click_delay = ((new Date().getTime()) - window.mouse_down_time)/1000.0;
|
||||||
var desc = "";
|
var desc = "";
|
||||||
if (e.altKey) desc += 'alt ';
|
if (e.altKey) desc += 'alt ';
|
||||||
if (e.ctrlKey) desc += 'control ';
|
if (e.ctrlKey) desc += 'control ';
|
||||||
|
@ -179,6 +180,16 @@ $(function() {
|
||||||
if (e.shiftKey) desc += 'shift ';
|
if (e.shiftKey) desc += 'shift ';
|
||||||
var pos = this.getBoundingClientRect();
|
var pos = this.getBoundingClientRect();
|
||||||
$(this).after('<a id="has-been-right-clicked" href="#">Has been ' + desc + 'right clicked at ' + (e.clientX - pos.left) + ',' + (e.clientY - pos.top) + '</a>');
|
$(this).after('<a id="has-been-right-clicked" href="#">Has been ' + desc + 'right clicked at ' + (e.clientX - pos.left) + ',' + (e.clientY - pos.top) + '</a>');
|
||||||
|
},
|
||||||
|
mousedown: function(e) {
|
||||||
|
window.click_delay = undefined;
|
||||||
|
window.right_click_delay = undefined;
|
||||||
|
window.mouse_down_time = new Date().getTime();
|
||||||
|
},
|
||||||
|
mouseup: function(e) {
|
||||||
|
if (e.button == 2){
|
||||||
|
window.right_click_delay = ((new Date().getTime()) - window.mouse_down_time)/1000.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#open-alert').click(function() {
|
$('#open-alert').click(function() {
|
||||||
|
|
|
@ -856,6 +856,15 @@ Capybara::SpecHelper.spec 'node' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'delay', requires: [:js] do
|
||||||
|
it 'should delay the mouse up' do
|
||||||
|
@session.visit('with_js')
|
||||||
|
@session.find(:css, '#click-test').click(delay: 2)
|
||||||
|
delay = @session.evaluate_script('window.click_delay')
|
||||||
|
expect(delay).to be >= 2
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#double_click', requires: [:js] do
|
describe '#double_click', requires: [:js] do
|
||||||
|
@ -1028,6 +1037,15 @@ Capybara::SpecHelper.spec 'node' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'delay', requires: [:js] do
|
||||||
|
it 'should delay the mouse up' do
|
||||||
|
@session.visit('with_js')
|
||||||
|
@session.find(:css, '#click-test').right_click(delay: 2)
|
||||||
|
delay = @session.evaluate_script('window.right_click_delay')
|
||||||
|
expect(delay).to be >= 2
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#send_keys', requires: [:send_keys] do
|
describe '#send_keys', requires: [:send_keys] do
|
||||||
|
|
Loading…
Add table
Reference in a new issue