Class: Obxcura::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/obxcura/node.rb

Overview

A live handle to a DOM node inside a Frame. Backed by a CDP remote object, so reads run as function calls bound to that object and reflect the current DOM. Returned by Frame::DOM#at_css / #css.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(frame, object_id) ⇒ Node

Returns a new instance of Node.

Parameters:

  • frame (Obxcura::Frame)

    the frame the node lives in.

  • object_id (String)

    the CDP objectId of the node.



15
16
17
18
# File 'lib/obxcura/node.rb', line 15

def initialize(frame, object_id)
  @frame = frame
  @remote_object_id = object_id
end

Instance Attribute Details

#remote_object_idString (readonly)

remote_object_id (not object_id) so it doesn't shadow Ruby's Object#object_id, which every object relies on for identity.

Returns:

  • (String)

    the CDP remote objectId backing this node. Named



11
12
13
# File 'lib/obxcura/node.rb', line 11

def remote_object_id
  @remote_object_id
end

Instance Method Details

#[](name) ⇒ String? Also known as: attribute

Read an attribute value.

Parameters:

  • name (String)

    the attribute name.

Returns:

  • (String, nil)

    the attribute value, or nil if absent.



42
43
44
# File 'lib/obxcura/node.rb', line 42

def [](name)
  @frame.call_on(remote_object_id, "function(name) { return this.getAttribute(name); }", [ name ])
end

#at_css(selector) ⇒ Obxcura::Node?

First descendant matching a CSS selector, searched within this node.

Parameters:

  • selector (String)

    a CSS selector.

Returns:



34
35
36
# File 'lib/obxcura/node.rb', line 34

def at_css(selector)
  @frame.to_node(@frame.call_on(remote_object_id, "function(s) { return this.querySelector(s); }", [ selector ]))
end

#focusself

Give this node keyboard focus.

Returns:

  • (self)


50
51
52
# File 'lib/obxcura/node.rb', line 50

def focus
  tap { @frame.page.command("DOM.focus", objectId: remote_object_id) }
end

#outer_htmlString

Returns the node's serialized outer HTML.

Returns:

  • (String)

    the node's serialized outer HTML.



93
94
95
# File 'lib/obxcura/node.rb', line 93

def outer_html
  @frame.call_on(remote_object_id, "function() { return this.outerHTML; }")
end

#submitself

Submit this node's form. Works whether the node is the <form> itself or a control inside one (resolved via .form / closest <form>). Prefers requestSubmit (runs validation and fires the submit event) and falls back to submit where it's unavailable.

Returns:

  • (self)

Raises:



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/obxcura/node.rb', line 79

def submit
  result = @frame.call_on(remote_object_id, <<~JS)
    function() {
      const form = this.tagName === "FORM" ? this : (this.form || this.closest("form"));
      if (!form) return { error: "node is not a form and has no ancestor form" };
      form.requestSubmit ? form.requestSubmit() : form.submit();
    }
  JS
  raise ProtocolError, result["error"] if result.is_a?(Hash) && result["error"]

  self
end

#textString

Returns the visible text of the node and its descendants.

Returns:

  • (String)

    the visible text of the node and its descendants.



21
22
23
# File 'lib/obxcura/node.rb', line 21

def text
  @frame.call_on(remote_object_id, "function() { return this.textContent; }")
end

#type(*keys) ⇒ self

Type text into this node. Obscura has no Input domain (Input.insertText / dispatchKeyEvent are unimplemented), so this sets value in page context and fires the input/change events real typing would, letting listeners react. Appends, matching keyboard behaviour when the node already has text.

Parameters:

  • keys (Array<String>)

    text fragments to type (joined).

Returns:

  • (self)


61
62
63
64
65
66
67
68
69
70
# File 'lib/obxcura/node.rb', line 61

def type(*keys)
  tap { @frame.call_on(remote_object_id, <<~JS, [ keys.join ])
    function(text) {
      this.value = (this.value || "") + text;
      this.dispatchEvent(new Event("input", { bubbles: true }));
      this.dispatchEvent(new Event("change", { bubbles: true }));
    }
  JS
  }
end

#valueString?

Returns the node's value (form controls), or nil.

Returns:

  • (String, nil)

    the node's value (form controls), or nil.



26
27
28
# File 'lib/obxcura/node.rb', line 26

def value
  @frame.call_on(remote_object_id, "function() { return this.value; }")
end