Refactor normalize_keys and fix for edge case now tested for in Capybara

This commit is contained in:
Thomas Walpole 2018-10-18 14:54:12 -07:00
parent 5aa5d9675e
commit ed85f0d3dc
2 changed files with 49 additions and 35 deletions

View File

@ -273,7 +273,7 @@ module Capybara::Poltergeist
end end
def send_keys(page_id, id, keys) def send_keys(page_id, id, keys)
command 'send_keys', page_id, id, normalize_keys(keys) command 'send_keys', page_id, id, normalize_keys(Array(keys))
end end
def path(page_id, id) def path(page_id, id)
@ -465,39 +465,54 @@ module Capybara::Poltergeist
decimal: 'numpad.' decimal: 'numpad.'
}.freeze }.freeze
def normalize_keys(keys) def combine_strings(keys)
keys.map do |key_desc| keys.chunk { |k| k.is_a? String }.map { |string, k| string ? [k.reduce(&:+)] : k }.reduce(&:+)
case key_desc end
when Array
# [:Shift, "s"] => { modifier: "shift", keys: "S" } def is_modifier(key)
# [:Shift, "string"] => { modifier: "shift", keys: "STRING" } return false unless %i[shift ctrl control alt meta command].include?(key.downcase)
# [:Ctrl, :Left] => { modifier: "ctrl", key: 'Left' } case key = key.to_s.downcase
# [:Ctrl, :Shift, :Left] => { modifier: "ctrl,shift", key: 'Left' } when 'control' then 'ctrl'
# [:Ctrl, :Left, :Left] => { modifier: "ctrl", key: [:Left, :Left] } when 'command' then 'meta'
chunked_keys = key_desc.chunk { |k| k.is_a?(Symbol) && %w[shift ctrl control alt meta command].include?(k.to_s.downcase) } else key
modifiers = if chunked_keys.peek[0] end
chunked_keys.next[1].map do |k| end
k = k.to_s.downcase
k = 'ctrl' if k == 'control' def key_descriptor(key)
k = 'meta' if k == 'command' key = KEY_ALIASES.fetch(key, key)
k res = if (match = key.to_s.match(/numpad(.)/))
end.join(',') { keys: match[1], modifier: 'keypad' }
else else
'' key = key.to_s.split('_').map(&:capitalize).join if key !~ /^[A-Z]/
end { key: key }
letters = normalize_keys(chunked_keys.next[1].map { |k| k.is_a?(String) ? k.upcase : k }) end
{ modifier: modifiers, keys: letters } end
when Symbol
def normalize_keys(keys, pressed_keys = [], memo = [])
case keys
when Array
pressed_keys.push []
memo += combine_strings(keys).map { |k| normalize_keys(k, pressed_keys, memo) }
pressed_keys.pop
memo.flatten.compact
when Symbol
if (key_desc = is_modifier(keys))
pressed_keys.last.push key_desc
nil
else
# Return a known sequence for PhantomJS # Return a known sequence for PhantomJS
key = KEY_ALIASES.fetch(key_desc, key_desc) key = key_descriptor(keys)
if (match = key.to_s.match(/numpad(.)/)) modifiers = Array(key[:modifier])
res = { keys: match[1], modifier: 'keypad' } modifiers.concat(pressed_keys.flatten)
elsif key !~ /^[A-Z]/ key[:modifier] = modifiers.join(',') unless modifiers.empty?
key = key.to_s.split('_').map(&:capitalize).join key
end end
res || { key: key } when String
when String modifiers = pressed_keys.flatten
key_desc # Plain string, nothing to do if modifiers.empty?
keys # Plain string, nothing to do
else
{ modifier: modifiers.join(','), keys: keys.upcase }
end end
end end
end end

View File

@ -1362,7 +1362,7 @@ module Capybara::Poltergeist
it 'sends sequences' do it 'sends sequences' do
input = @session.find(:css, '#empty_input') input = @session.find(:css, '#empty_input')
input.native.send_keys(:Shift, 'S', :Alt, 't', 'r', 'i', 'g', :Left, 'n') input.native.send_keys([:Shift], 'S', [:Alt], 't', 'r', 'i', 'g', :Left, 'n')
expect(input.value).to eq('String') expect(input.value).to eq('String')
end end
@ -1377,7 +1377,6 @@ module Capybara::Poltergeist
it 'sends sequences with modifiers and letters' do it 'sends sequences with modifiers and letters' do
input = @session.find(:css, '#empty_input') input = @session.find(:css, '#empty_input')
input.native.send_keys([:Shift, 's'], 't', 'r', 'i', 'n', 'g') input.native.send_keys([:Shift, 's'], 't', 'r', 'i', 'n', 'g')
expect(input.value).to eq('String') expect(input.value).to eq('String')