Class: Capybara::Chrome::Node
- Inherits:
-
Driver::Node
- Object
- Driver::Node
- Capybara::Chrome::Node
- Includes:
- Debug
- Defined in:
- lib/capybara/chrome/node.rb
Constant Summary collapse
- KEY_DATA =
Hash.new do |h, k| h[k] = {text: k.to_s} end.merge!({ cancel: { key_code: 3, code: "Abort", key: "Cancel"}, help: { key_code: 6, code: "Help", key: "Help"}, backspace: { key_code: 8, code: "Backspace", key: "Backspace"}, tab: { key_code: 9, code: "Tab", key: "Tab"}, delete: { key_code: 46, code: "Delete", key: "Delete"}, home: { key_code: 36, code: "Home", key: "Home"}, end: { key_code: 35, code: "End", key: "End"}, left: { key_code: 37, code: "ArrowLeft", key: "ArrowLeft"}, right: { key_code: 39, code: "ArrowRight", key: "ArrowRight"}, up: { key_code: 38, code: "ArrowUp", key: "ArrowUp"}, down: { key_code: 40, code: "ArrowDown", key: "ArrowDown"}, return: { key_code: 13, code: "Enter", key: "Enter"}, enter: { key_code: 13, code: "Enter", key: "Enter"}, "\r" => { key_code: 13, code: "Enter", key: "Enter", text: "\r"}, "\n" => { key_code: 13, code: "Enter", key: "Enter", text: "\r"}, space: { key_code: 32, code: "Space", key: " ", text: " "}, shift: { key_code: 16, code: "Shift", key: "ShiftLeft", location: 1}, control: { key_code: 17, code: "ControlLeft", key: "Control", text: "\r"}, alt: { key_code: 18, code: "AltLeft", key: "Alt", location: 1}, meta: { key_code: 91, code: "MetaLeft", key: "Meta", location: 1}, })
- TEXT_TYPES =
%w(date email number password search tel text textarea url)
Instance Attribute Summary collapse
-
#browser ⇒ Object
readonly
Returns the value of attribute browser.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
Instance Method Summary collapse
- #[](attr) ⇒ Object
- #all_text ⇒ Object
- #checked? ⇒ Boolean
- #click ⇒ Object
- #disabled? ⇒ Boolean
- #expect_node_at_position(x, y) ⇒ Object
- #find_css(query) ⇒ Object
- #find_xpath(query) ⇒ Object
- #focus ⇒ Object
- #get_dimensions ⇒ Object
- #get_key_data(key) ⇒ Object
- #get_modifiers(ary) ⇒ Object
- #html ⇒ Object
-
#initialize(driver, browser, id) ⇒ Node
constructor
A new instance of Node.
- #is_connected? ⇒ Boolean
- #method_missing(method, *args) ⇒ Object
- #move_mouse(x, y, steps: 1) ⇒ Object
- #node_description ⇒ Object
- #node_id ⇒ Object
- #on_self(function_body, options = {}) ⇒ Object
- #on_self!(function_body, options = {}) ⇒ Object
- #on_self_value(function_body, options = {}) ⇒ Object
- #path ⇒ Object (also: #get_xpath)
- #raw_text ⇒ Object
- #remote_object ⇒ Object
- #remote_object_id ⇒ Object
- #request_node(remote_object_id) ⇒ Object
- #select_option(*args) ⇒ Object
- #selected? ⇒ Boolean
- #send_cmd(cmd, args = {}) ⇒ Object
- #send_cmd!(cmd, args = {}) ⇒ Object
- #send_key_data(data, modifiers: 0) ⇒ Object
- #send_keys(*keys) ⇒ Object
- #set(value, options = {}) ⇒ Object
- #tag_name ⇒ Object (also: #local_name)
- #trigger(event_name) ⇒ Object
- #type_string(string) ⇒ Object
- #value(*args) ⇒ Object
- #visible? ⇒ Boolean
- #visible_text ⇒ Object (also: #text)
Methods included from Debug
Constructor Details
#initialize(driver, browser, id) ⇒ Node
Returns a new instance of Node.
31 32 33 34 35 36 37 38 |
# File 'lib/capybara/chrome/node.rb', line 31 def initialize(driver, browser, id) raise "hell" if id == 0 @driver = driver @browser = browser @id = id @mouse_x = 0 @mouse_y = 0 end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
273 274 275 276 |
# File 'lib/capybara/chrome/node.rb', line 273 def method_missing(method, *args) debug ["method missing", method, args] raise "method missing #{method} #{args.inspect}" end |
Instance Attribute Details
#browser ⇒ Object (readonly)
Returns the value of attribute browser.
4 5 6 |
# File 'lib/capybara/chrome/node.rb', line 4 def browser @browser end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
4 5 6 |
# File 'lib/capybara/chrome/node.rb', line 4 def id @id end |
Instance Method Details
#[](attr) ⇒ Object
278 279 280 |
# File 'lib/capybara/chrome/node.rb', line 278 def [](attr) on_self_value %(return this.getAttribute("#{attr}") ) end |
#all_text ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/capybara/chrome/node.rb', line 45 def all_text browser.evaluate_script %( ChromeRemoteHelper.waitDOMContentLoaded(); ) text = browser.evaluate_script %( ChromeRemoteHelper.onSelfValue(#{id}, "textContent") ) if Capybara::VERSION.to_f < 3.0 Capybara::Helpers.normalize_whitespace(text) else text.gsub(/[\u200b\u200e\u200f]/, '') .gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ') .gsub(/\A[[:space:]&&[^\u00a0]]+/, "") .gsub(/[[:space:]&&[^\u00a0]]+\z/, "") .tr("\u00a0", ' ') end end |
#checked? ⇒ Boolean
234 235 236 |
# File 'lib/capybara/chrome/node.rb', line 234 def checked? val = browser.evaluate_script %( ChromeRemoteHelper.onSelfValue(#{id}, "checked") ) end |
#click ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/capybara/chrome/node.rb', line 107 def click browser.with_retry do on_self("this.scrollIntoViewIfNeeded();"); dim = get_dimensions if dim["width"] == 0 && dim["height"] == 0 puts "DIM IS 0" puts html raise Capybara::ElementNotFound end xd = [1, dim["width"]/2, dim["width"]/3] yd = [1, dim["height"]/2, dim["height"]/3] strategy = rand(0..xd.size-1) cx = (dim["x"] + xd[strategy]).floor cy = (dim["y"] + yd[strategy]).floor move_mouse(cx, cy, steps: [cx, cy].max) expect_node_at_position(cx, cy) send_cmd! "Input.dispatchMouseEvent", type: "mousePressed", x: cx, y: cy, clickCount: 1, button: "left" send_cmd! "Input.dispatchMouseEvent", type: "mouseReleased", x: cx, y: cy, clickCount: 1, button: "left" vv = browser.wait_for_load end end |
#disabled? ⇒ Boolean
142 143 144 145 146 |
# File 'lib/capybara/chrome/node.rb', line 142 def disabled? val = browser.evaluate_script %( ChromeRemoteHelper.onSelfValue(#{id}, "disabled") ) debug val val end |
#expect_node_at_position(x, y) ⇒ Object
88 89 90 91 92 93 |
# File 'lib/capybara/chrome/node.rb', line 88 def expect_node_at_position(x,y) in_position = browser.evaluate_script %( ChromeRemoteHelper.nodeIsNodeAtPosition(#{id}, {relativeX: #{x}, relativeY: #{y}}) ) if !in_position raise "Element '<#{tag_name}>' not at expected position: #{x},#{y}" end end |
#find_css(query) ⇒ Object
129 130 131 |
# File 'lib/capybara/chrome/node.rb', line 129 def find_css(query) browser.query_selector_all(query, id) end |
#find_xpath(query) ⇒ Object
133 134 135 |
# File 'lib/capybara/chrome/node.rb', line 133 def find_xpath(query) browser.find_xpath query, id end |
#focus ⇒ Object
225 226 227 |
# File 'lib/capybara/chrome/node.rb', line 225 def focus val = browser.evaluate_script %( ChromeRemoteHelper.onSelfValue(#{id}, "focus") ) end |
#get_dimensions ⇒ Object
81 82 83 84 85 86 |
# File 'lib/capybara/chrome/node.rb', line 81 def get_dimensions browser.wait_for_load val = browser.evaluate_script %( ChromeRemoteHelper.nodeGetDimensions(#{id}) ) val = JSON.parse(val) rescue {} val end |
#get_key_data(key) ⇒ Object
195 196 197 |
# File 'lib/capybara/chrome/node.rb', line 195 def get_key_data(key) KEY_DATA[key] end |
#get_modifiers(ary) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/capybara/chrome/node.rb', line 205 def get_modifiers(ary) mods = [] keys = [] ary.each do |k| case k when :alt mods << 1 when :control mods << 2 when :meta, :command mods << 4 when :shift mods << 8 else keys << k end end [mods.inject(&:|), keys] end |
#html ⇒ Object
40 41 42 43 |
# File 'lib/capybara/chrome/node.rb', line 40 def html browser.evaluate_script %( ChromeRemoteHelper.waitDOMContentLoaded(); ) browser.evaluate_script %( ChromeRemoteHelper.onSelfValue(#{id}, "outerHTML") ) end |
#is_connected? ⇒ Boolean
76 77 78 79 |
# File 'lib/capybara/chrome/node.rb', line 76 def is_connected? # on_self_value %( return this.isConnected ) val = browser.evaluate_script %( ChromeRemoteHelper.onSelfValue(#{id}, "isConnected") ) end |
#move_mouse(x, y, steps: 1) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/capybara/chrome/node.rb', line 95 def move_mouse(x, y, steps: 1) if steps >= 1 (0..x).step(steps).each do |dx| send_cmd! "Input.dispatchMouseEvent", type: "mouseMoved", x: dx, y: 0 end (0..y).step(steps).each do |dy| send_cmd! "Input.dispatchMouseEvent", type: "mouseMoved", x: x, y: dy end end send_cmd! "Input.dispatchMouseEvent", type: "mouseMoved", x: x, y: y end |
#node_description ⇒ Object
282 283 284 285 286 287 288 289 290 |
# File 'lib/capybara/chrome/node.rb', line 282 def node_description # return @node_description if @node_description @node_description = send_cmd("DOM.describeNode", nodeId: id) debug ["node_desc", @node_description, id] if @node_description.nil? raise Capybara::ExpectationNotMet end @node_description end |
#node_id ⇒ Object
167 168 169 170 171 |
# File 'lib/capybara/chrome/node.rb', line 167 def node_id browser.get_document val = browser.execute_script %(ChromeRemoteHelper.onSelf(#{id}, "return this;")) send_cmd("DOM.requestNode", objectId: val["result"]["objectId"])["nodeId"] end |
#on_self(function_body, options = {}) ⇒ Object
310 311 312 313 314 |
# File 'lib/capybara/chrome/node.rb', line 310 def on_self(function_body, ={}) function_body = function_body.gsub('"', '\"').gsub(/\s+/, " ") browser.evaluate_script %( window.ChromeRemoteHelper && ChromeRemoteHelper.waitDOMContentLoaded(); ) browser.evaluate_script %(window.ChromeRemoteHelper && ChromeRemoteHelper.onSelf(#{id}, "#{function_body}")) end |
#on_self!(function_body, options = {}) ⇒ Object
316 317 318 319 320 321 322 |
# File 'lib/capybara/chrome/node.rb', line 316 def on_self!(function_body, ={}) function_body = function_body.gsub('"', '\"').gsub(/\s+/, " ") browser.evaluate_script %( ChromeRemoteHelper.waitDOMContentLoaded(); ) browser.execute_script! %(ChromeRemoteHelper.onSelf(#{id}, "#{function_body}")) end |
#on_self_value(function_body, options = {}) ⇒ Object
305 306 307 308 |
# File 'lib/capybara/chrome/node.rb', line 305 def on_self_value(function_body, ={}) function_body = function_body.gsub('"', '\"').gsub(/\s+/, " ") browser.evaluate_script %(ChromeRemoteHelper.onSelf(#{id}, "#{function_body}")) end |
#path ⇒ Object Also known as: get_xpath
137 138 139 |
# File 'lib/capybara/chrome/node.rb', line 137 def path browser.evaluate_script %( ChromeRemoteHelper.nodePathForNode(#{id}) ) end |
#raw_text ⇒ Object
68 69 70 |
# File 'lib/capybara/chrome/node.rb', line 68 def raw_text browser.evaluate_script %( ChromeRemoteHelper.nodeText(#{id}) ) end |
#remote_object ⇒ Object
328 329 330 331 332 333 334 335 336 |
# File 'lib/capybara/chrome/node.rb', line 328 def remote_object return @remote_object if @remote_object @remote_object = send_cmd("DOM.resolveNode", nodeId: id) debug @remote_object, id if @remote_object.nil? raise Capybara::ExpectationNotMet end @remote_object end |
#remote_object_id ⇒ Object
324 325 326 |
# File 'lib/capybara/chrome/node.rb', line 324 def remote_object_id remote_object["object"]["objectId"] end |
#request_node(remote_object_id) ⇒ Object
338 339 340 |
# File 'lib/capybara/chrome/node.rb', line 338 def request_node(remote_object_id) @request_node ||= send_cmd("DOM.requestNode", objectId: remote_object_id) end |
#select_option(*args) ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/capybara/chrome/node.rb', line 246 def select_option(*args) on_self_value %( if (this.disabled) return; var selectNode = this.parentNode; if (selectNode.tagName == "OPTGROUP") selectNode = selectNode.parentNode; ChromeRemoteHelper.dispatchEvent(selectNode, "mousedown"); selectNode.focus(); ChromeRemoteHelper.dispatchEvent(selectNode, "input"); if (!this.selected) { this.selected = true; ChromeRemoteHelper.dispatchEvent(selectNode, "change"); } ChromeRemoteHelper.dispatchEvent(selectNode, "mouseup"); ChromeRemoteHelper.dispatchEvent(selectNode, "click"); ) end |
#selected? ⇒ Boolean
238 239 240 |
# File 'lib/capybara/chrome/node.rb', line 238 def selected? val = browser.evaluate_script %( ChromeRemoteHelper.onSelfValue(#{id}, "selected") ) end |
#send_cmd(cmd, args = {}) ⇒ Object
298 299 300 |
# File 'lib/capybara/chrome/node.rb', line 298 def send_cmd(cmd, args={}) browser.remote.send_cmd(cmd, args) end |
#send_cmd!(cmd, args = {}) ⇒ Object
301 302 303 |
# File 'lib/capybara/chrome/node.rb', line 301 def send_cmd!(cmd, args={}) browser.remote.send_cmd!(cmd, args) end |
#send_key_data(data, modifiers: 0) ⇒ Object
199 200 201 202 203 |
# File 'lib/capybara/chrome/node.rb', line 199 def send_key_data(data, modifiers: 0) type = data[:text] ? "keyDown" : "rawKeyDown" send_cmd! "Input.dispatchKeyEvent", {type: type, text: data[:text].to_s, windowsVirtualKeyCode: data[:key_code].to_i, code: data[:code].to_s, key: data[:key].to_s, modifiers: modifiers} send_cmd! "Input.dispatchKeyEvent", {type: "keyUp", modifiers: modifiers} end |
#send_keys(*keys) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/capybara/chrome/node.rb', line 182 def send_keys(*keys) keys.each do |key| if key.is_a? Array mods, new_keys = get_modifiers(key) new_keys.each do |k| send_key_data(get_key_data(k), modifiers: mods) end else send_key_data(get_key_data(key)) end end end |
#set(value, options = {}) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/capybara/chrome/node.rb', line 149 def set(value, ={}) value = value.to_s.gsub('"', '\"') type = browser.evaluate_script %( ChromeRemoteHelper.nodeSetType(#{id}) ) if type == "file" send_cmd "DOM.setFileInputFiles", files: [value.to_s], nodeId: node_id elsif TEXT_TYPES.include?(type) script = "this.value = ''; this.focus();" if value.blank? script << %(ChromeRemoteHelper.dispatchEvent(this, "change")) end on_self script type_string(value.to_s) else browser.evaluate_script %( ChromeRemoteHelper.nodeSet(#{id}, "#{value}", "#{type}") ) end end |
#tag_name ⇒ Object Also known as: local_name
292 293 294 295 |
# File 'lib/capybara/chrome/node.rb', line 292 def tag_name # node_description["node"]["localName"] on_self_value("return this.tagName.toLowerCase()") end |
#trigger(event_name) ⇒ Object
269 270 271 |
# File 'lib/capybara/chrome/node.rb', line 269 def trigger(event_name) on_self %( ChromeRemoteHelper.dispatchEvent(this, '#{event_name}') ) end |
#type_string(string) ⇒ Object
173 174 175 176 177 178 179 180 |
# File 'lib/capybara/chrome/node.rb', line 173 def type_string(string) ary = string.chars ary.each do |char| char.tr!("\n", "\r") send_cmd! "Input.dispatchKeyEvent", {type: "keyDown", text: char} send_cmd! "Input.dispatchKeyEvent", {type: "keyUp"} end end |
#value(*args) ⇒ Object
229 230 231 232 |
# File 'lib/capybara/chrome/node.rb', line 229 def value(*args) debug args val = browser.evaluate_script %( ChromeRemoteHelper.onSelfValue(#{id}, "value") ) end |
#visible? ⇒ Boolean
72 73 74 |
# File 'lib/capybara/chrome/node.rb', line 72 def visible? browser.evaluate_script %( ChromeRemoteHelper.nodeVisible(#{id}) ) end |
#visible_text ⇒ Object Also known as: text
59 60 61 62 63 64 65 |
# File 'lib/capybara/chrome/node.rb', line 59 def visible_text raw_text.to_s.gsub(/\ +/, ' ') .gsub(/[\ \n]*\n[\ \n]*/, "\n") .gsub(/\A[[:space:]&&[^\u00a0]]+/, "") .gsub(/[[:space:]&&[^\u00a0]]+\z/, "") .tr("\u00a0", ' ') end |