class Ferrum::Keyboard

def combine_strings(keys)

def combine_strings(keys)
  keys
    .chunk { |k| k.is_a?(String) }
    .map { |s, k| s ? [k.reduce(&:+)] : k }
    .reduce(&:+)
end

def down(key)

Returns:
  • (self) -

Parameters:
  • key (String, Symbol) --
def down(key)
  key = normalize_keys(Array(key)).first
  type = key[:text] ? "keyDown" : "rawKeyDown"
  @page.command("Input.dispatchKeyEvent", slowmoable: true, type: type, **key)
  self
end

def initialize(page)

def initialize(page)
  @page = page
end

def modifiers(keys)

Returns:
  • (Integer) -

Parameters:
  • keys (Array<:alt, :ctrl, :command, :shift>) --
def modifiers(keys)
  keys.map { |k| MODIFIERS[k.to_s] }.compact.reduce(0, :|)
end

def normalize_keys(keys, pressed_keys = [], memo = [])

rubocop:disable Metrics/CyclomaticComplexity
rubocop:disable Metrics/PerceivedComplexity
TODO: Refactor it, and try to simplify complexity
def normalize_keys(keys, pressed_keys = [], memo = [])
  case keys
  when Array
    raise ArgumentError, "empty keys passed" if keys.empty?
    pressed_keys.push([])
    memo += combine_strings(keys).map do |key|
      normalize_keys(key, pressed_keys, memo)
    end
    pressed_keys.pop
    memo.flatten.compact
  when Symbol
    key = keys.to_s.downcase
    if MODIFIERS.keys.include?(key)
      pressed_keys.last.push(key)
      nil
    else
      key = KEYS.fetch(KEYS_MAPPING[key.to_sym] || key.to_sym)
      key[:modifiers] = pressed_keys.flatten.map { |k| MODIFIERS[k] }.reduce(0, :|)
      to_options(key)
    end
  when String
    raise ArgumentError, "empty keys passed" if keys.empty?
    pressed = pressed_keys.flatten
    keys.each_char.map do |char|
      key = KEYS[char] || {}
      if pressed.empty?
        key = key.merge(text: char, unmodifiedText: char)
        [to_options(key)]
      else
        text = pressed == ["shift"] ? char.upcase : char
        key = key.merge(
          text: text,
          unmodifiedText: text,
          isKeypad: key["location"] == 3,
          modifiers: pressed.map { |k| MODIFIERS[k] }.reduce(0, :|)
        )
        modifiers = pressed.map { |k| to_options(KEYS.fetch(KEYS_MAPPING[k.to_sym])) }
        modifiers + [to_options(key)]
      end.flatten
    end
  else
    raise ArgumentError, "unexpected argument"
  end
end

def to_options(hash)

def to_options(hash)
  hash.inject({}) { |memo, (k, v)| memo.merge(k.to_sym => v) }
end

def type(*keys)

Returns:
  • (self) -

Parameters:
  • keys (Array) --
def type(*keys)
  keys = normalize_keys(Array(keys))
  keys.each do |key|
    type = key[:text] ? "keyDown" : "rawKeyDown"
    @page.command("Input.dispatchKeyEvent", type: type, **key)
    @page.command("Input.dispatchKeyEvent", slowmoable: true, type: "keyUp", **key)
  end
  self
end

def up(key)

Returns:
  • (self) -

Parameters:
  • key (String, Symbol) --
def up(key)
  key = normalize_keys(Array(key)).first
  @page.command("Input.dispatchKeyEvent", slowmoable: true, type: "keyUp", **key)
  self
end