mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Workaround geckodriver/firefox deficient send_keys implementation as much as possible
This commit is contained in:
parent
6711aed299
commit
3e5f82bb23
5 changed files with 47 additions and 14 deletions
|
@ -47,7 +47,6 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
# Array => an array of keys to send before the value being set, e.g. [[:command, 'a'], :backspace]
|
||||
def set(value, **options)
|
||||
raise ArgumentError, "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}" if value.is_a?(Array) && !multiple?
|
||||
|
||||
case tag_name
|
||||
when 'input'
|
||||
case self[:type]
|
||||
|
@ -212,17 +211,17 @@ private
|
|||
elsif clear == :backspace
|
||||
# Clear field by sending the correct number of backspace keys.
|
||||
backspaces = [:backspace] * self.value.to_s.length
|
||||
native.send_keys(*([:end] + backspaces + [value.to_s]))
|
||||
send_keys(*([:end] + backspaces + [value.to_s]))
|
||||
elsif clear == :none
|
||||
native.send_keys(value.to_s)
|
||||
send_keys(value.to_s)
|
||||
elsif clear.is_a? Array
|
||||
native.send_keys(*clear, value.to_s)
|
||||
send_keys(*clear, value.to_s)
|
||||
else
|
||||
# Clear field by JavaScript assignment of the value property.
|
||||
# Script can change a readonly element which user input cannot, so
|
||||
# don't execute if readonly.
|
||||
driver.execute_script "arguments[0].value = ''", self
|
||||
native.send_keys(value.to_s)
|
||||
send_keys(value.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -42,8 +42,51 @@ class Capybara::Selenium::MarionetteNode < Capybara::Selenium::Node
|
|||
end
|
||||
end
|
||||
|
||||
def send_keys(*args)
|
||||
# https://github.com/mozilla/geckodriver/issues/846
|
||||
return super(*args.map { |arg| arg == :space ? ' ' : arg }) if args.none? { |s| s.is_a? Array }
|
||||
|
||||
native.click
|
||||
actions = driver.browser.action
|
||||
args.each do |keys|
|
||||
_send_keys(keys, actions)
|
||||
end
|
||||
actions.perform
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _send_keys(keys, actions, down_keys = nil)
|
||||
case keys
|
||||
when String
|
||||
keys = keys.upcase if down_keys&.include?(:shift) # https://bugzilla.mozilla.org/show_bug.cgi?id=1405370
|
||||
actions.send_keys(keys)
|
||||
when :space
|
||||
actions.send_keys(' ') # https://github.com/mozilla/geckodriver/issues/846
|
||||
when :control, :left_control, :right_control,
|
||||
:alt, :left_alt, :right_alt,
|
||||
:shift, :left_shift, :right_shift,
|
||||
:meta, :left_meta, :right_meta,
|
||||
:command
|
||||
if down_keys.nil?
|
||||
actions.send_keys(keys)
|
||||
else
|
||||
down_keys << keys
|
||||
actions.key_down(keys)
|
||||
end
|
||||
when Symbol
|
||||
actions.send_keys(keys)
|
||||
when Array
|
||||
local_down_keys = []
|
||||
keys.each do |sub_keys|
|
||||
_send_keys(sub_keys, actions, local_down_keys)
|
||||
end
|
||||
local_down_keys.each { |key| actions.key_up(key) }
|
||||
else
|
||||
raise ArgumentError, 'Unknown keys type'
|
||||
end
|
||||
end
|
||||
|
||||
def bridge
|
||||
driver.browser.send(:bridge)
|
||||
end
|
||||
|
|
|
@ -60,10 +60,6 @@ skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLE
|
|||
|
||||
Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
|
||||
case example.metadata[:full_description]
|
||||
when 'Capybara::Session selenium_firefox_remote node #send_keys should generate key events',
|
||||
'Capybara::Session selenium_firefox_remote node #send_keys should allow for multiple simultaneous keys',
|
||||
'Capybara::Session selenium_firefox_remote node #send_keys should send special characters'
|
||||
pending "selenium-webdriver/geckodriver doesn't support complex sets of characters"
|
||||
when 'Capybara::Session selenium_firefox_remote node #click should allow multiple modifiers'
|
||||
pending "Firefox doesn't generate an event for shift+control+click" if marionette_gte?(62, @session)
|
||||
when /^Capybara::Session selenium node #double_click/
|
||||
|
|
|
@ -50,10 +50,6 @@ $stdout.puts `#{Selenium::WebDriver::Firefox.driver_path} --version` if ENV['CI'
|
|||
|
||||
Capybara::SpecHelper.run_specs TestSessions::SeleniumMarionette, 'selenium', capybara_skip: skipped_tests do |example|
|
||||
case example.metadata[:full_description]
|
||||
when 'Capybara::Session selenium node #send_keys should generate key events',
|
||||
'Capybara::Session selenium node #send_keys should allow for multiple simultaneous keys',
|
||||
'Capybara::Session selenium node #send_keys should send special characters'
|
||||
pending "selenium-webdriver/geckodriver doesn't support complex sets of characters"
|
||||
when 'Capybara::Session selenium node #click should allow multiple modifiers'
|
||||
pending "Firefox doesn't generate an event for shift+control+click" if marionette_gte?(62, @session)
|
||||
when /^Capybara::Session selenium node #double_click/
|
||||
|
|
|
@ -185,7 +185,6 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|||
|
||||
context '#fill_in with { clear: Array } fill_options' do
|
||||
it 'should pass the array through to the element' do
|
||||
pending "selenium-webdriver/geckodriver doesn't support complex sets of characters" if marionette?(session)
|
||||
# this is mainly for use with [[:control, 'a'], :backspace] - however since that is platform dependant I'm testing with something less useful
|
||||
session.visit('/form')
|
||||
session.fill_in('form_first_name',
|
||||
|
|
Loading…
Reference in a new issue