Module: Capybara::Cuprite::Browser::Input

Included in:
Page
Defined in:
lib/capybara/cuprite/browser/input.rb

Constant Summary collapse

KEYS =
JSON.parse(File.read(File.expand_path("../input.json", __FILE__)))
MODIFIERS =
{ "alt" => 1, "ctrl" => 2, "control" => 2, "meta" => 4, "command" => 4, "shift" => 8 }
KEYS_MAPPING =
{
  cancel: "Cancel", help: "Help", backspace: "Backspace", tab: "Tab",
  clear: "Clear", return: "Enter", enter: "Enter", shift: "Shift",
  ctrl: "Control", control: "Control", alt: "Alt", pause: "Pause",
  escape: "Escape", space: "Space",  pageup: "PageUp", page_up: "PageUp",
  pagedown: "PageDown", page_down: "PageDown", end: "End", home: "Home",
  left: "ArrowLeft", up: "ArrowUp", right: "ArrowRight",
  down: "ArrowDown", insert: "Insert", delete: "Delete",
  semicolon: "Semicolon", equals: "Equal", numpad0: "Numpad0",
  numpad1: "Numpad1", numpad2: "Numpad2", numpad3: "Numpad3",
  numpad4: "Numpad4", numpad5: "Numpad5", numpad6: "Numpad6",
  numpad7: "Numpad7", numpad8: "Numpad8", numpad9: "Numpad9",
  multiply: "NumpadMultiply", add: "NumpadAdd",
  separator: "NumpadDecimal", subtract: "NumpadSubtract",
  decimal: "NumpadDecimal", divide: "NumpadDivide", f1: "F1", f2: "F2",
  f3: "F3", f4: "F4", f5: "F5", f6: "F6", f7: "F7", f8: "F8", f9: "F9",
  f10: "F10", f11: "F11", f12: "F12", meta: "Meta", command: "Meta",
}

Instance Method Summary collapse

Instance Method Details

#click(node, keys = [], offset = {}) ⇒ Object



25
26
27
28
29
30
# File 'lib/capybara/cuprite/browser/input.rb', line 25

def click(node, keys = [], offset = {})
  x, y, modifiers = prepare_before_click(__method__, node, keys, offset)
  command("Input.dispatchMouseEvent", type: "mousePressed", modifiers: modifiers, button: "left", x: x, y: y, clickCount: 1)
  @wait = 0.05 # Potential wait because if network event is triggered then we have to wait until it's over.
  command("Input.dispatchMouseEvent", type: "mouseReleased", modifiers: modifiers, button: "left", x: x, y: y, clickCount: 1)
end

#click_coordinates(x, y) ⇒ Object



44
45
46
47
48
# File 'lib/capybara/cuprite/browser/input.rb', line 44

def click_coordinates(x, y)
  command("Input.dispatchMouseEvent", type: "mousePressed", button: "left", x: x, y: y, clickCount: 1)
  @wait = 0.05 # Potential wait because if network event is triggered then we have to wait until it's over.
  command("Input.dispatchMouseEvent", type: "mouseReleased", button: "left", x: x, y: y, clickCount: 1)
end

#combine_strings(keys) ⇒ Object



136
137
138
139
140
141
# File 'lib/capybara/cuprite/browser/input.rb', line 136

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

#double_click(node, keys = [], offset = {}) ⇒ Object



38
39
40
41
42
# File 'lib/capybara/cuprite/browser/input.rb', line 38

def double_click(node, keys = [], offset = {})
  x, y, modifiers = prepare_before_click(__method__, node, keys, offset)
  command("Input.dispatchMouseEvent", type: "mousePressed", modifiers: modifiers, button: "left", x: x, y: y, clickCount: 2)
  command("Input.dispatchMouseEvent", type: "mouseReleased", modifiers: modifiers, button: "left", x: x, y: y, clickCount: 2)
end

#drag(node, other) ⇒ Object

Raises:

  • (NotImplementedError)


61
62
63
# File 'lib/capybara/cuprite/browser/input.rb', line 61

def drag(node, other)
  raise NotImplementedError
end

#drag_by(node, x, y) ⇒ Object

Raises:

  • (NotImplementedError)


65
66
67
# File 'lib/capybara/cuprite/browser/input.rb', line 65

def drag_by(node, x, y)
  raise NotImplementedError
end

#hover(node) ⇒ Object



50
51
52
53
54
# File 'lib/capybara/cuprite/browser/input.rb', line 50

def hover(node)
  evaluate_on(node: node, expr: "_cuprite.scrollIntoViewport(this)")
  x, y = calculate_quads(node)
  command("Input.dispatchMouseEvent", type: "mouseMoved", x: x, y: y)
end

#normalize_keys(keys, pressed_keys = [], memo = []) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/capybara/cuprite/browser/input.rb', line 94

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
    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
    pressed = pressed_keys.flatten
    keys.each_char.map do |char|
      if pressed.empty?
        key = KEYS[char] || {}
        key = key.merge(text: char, unmodifiedText: char)
        [to_options(key)]
      else
        key = KEYS[char] || {}
        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
  end
end

#right_click(node, keys = [], offset = {}) ⇒ Object



32
33
34
35
36
# File 'lib/capybara/cuprite/browser/input.rb', line 32

def right_click(node, keys = [], offset = {})
  x, y, modifiers = prepare_before_click(__method__, node, keys, offset)
  command("Input.dispatchMouseEvent", type: "mousePressed", modifiers: modifiers, button: "right", x: x, y: y, clickCount: 1)
  command("Input.dispatchMouseEvent", type: "mouseReleased", modifiers: modifiers, button: "right", x: x, y: y, clickCount: 1)
end

#scroll_to(top, left) ⇒ Object



78
79
80
# File 'lib/capybara/cuprite/browser/input.rb', line 78

def scroll_to(top, left)
  execute("window.scrollTo(#{top}, #{left})")
end

#select(node, value) ⇒ Object



69
70
71
# File 'lib/capybara/cuprite/browser/input.rb', line 69

def select(node, value)
  evaluate_on(node: node, expr: "_cuprite.select(this, #{value})")
end

#send_keys(node, keys) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/capybara/cuprite/browser/input.rb', line 82

def send_keys(node, keys)
  keys = normalize_keys(Array(keys))

  click(node) if !evaluate_on(node: node, expr: %(_cuprite.containsSelection(this)))

  keys.each do |key|
    type = key[:text] ? "keyDown" : "rawKeyDown"
    command("Input.dispatchKeyEvent", type: type, **key)
    command("Input.dispatchKeyEvent", type: "keyUp", **key)
  end
end

#set(node, value) ⇒ Object



56
57
58
59
# File 'lib/capybara/cuprite/browser/input.rb', line 56

def set(node, value)
  object_id = command("DOM.resolveNode", nodeId: node["nodeId"]).dig("object", "objectId")
  evaluate("_cuprite.set(arguments[0], arguments[1])", { "objectId" => object_id }, value)
end

#trigger(node, event) ⇒ Object



73
74
75
76
# File 'lib/capybara/cuprite/browser/input.rb', line 73

def trigger(node, event)
  options = event.to_s == "click" ? { wait: 0.1 } : {}
  evaluate_on(node: node, expr: %(_cuprite.trigger(this, "#{event}")), **options)
end