Skip to main content

NodeHandle

Struct NodeHandle 

Source
pub struct NodeHandle { /* private fields */ }
Expand description

A handle to a live DOM node backed by a CDP RemoteObjectId.

Obtained via PageHandle::query_selector_all. Each method issues one or more CDP Runtime.callFunctionOn calls against the held V8 remote object reference — no HTML serialisation occurs.

A handle becomes stale after page navigation or if the underlying DOM node is removed. Stale calls return BrowserError::StaleNode so callers can distinguish them from other CDP failures.

§Example

use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
use std::time::Duration;

let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;

for node in page.query_selector_all("a[href]").await? {
    let href = node.attr("href").await?;
    let text = node.text_content().await?;
    println!("{text}: {href:?}");
}

Implementations§

Source§

impl NodeHandle

Source

pub async fn attr(&self, name: &str) -> Result<Option<String>>

Return a single attribute value, or None if the attribute is absent.

Issues one Runtime.callFunctionOn CDP call (el.getAttribute(name)).

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated, or BrowserError::Timeout / BrowserError::CdpError on transport-level failures.

Source

pub async fn attr_map(&self) -> Result<HashMap<String, String>>

Return all attributes as a HashMap<name, value> in a single CDP round-trip.

Uses DOM.getAttributes (via the chromiumoxide attributes() API) which returns a flat [name, value, name, value, …] list from the node description — no per-attribute calls are needed.

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated.

Source

pub async fn text_content(&self) -> Result<String>

Return the element’s textContent (all text inside, no markup).

Reads the DOM textContent property via a single JS eval — this is the raw text concatenation of all descendant text nodes, independent of layout or visibility (unlike innerText).

Returns an empty string when the property is absent or null.

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated.

Source

pub async fn inner_html(&self) -> Result<String>

Return the element’s innerHTML.

Returns an empty string when the property is absent or null.

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated.

Source

pub async fn outer_html(&self) -> Result<String>

Return the element’s outerHTML.

Returns an empty string when the property is absent or null.

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated.

Source

pub async fn ancestors(&self) -> Result<Vec<String>>

Return the ancestor tag-name chain, root-last.

Executes a single Runtime.callFunctionOn JavaScript function that walks parentElement and collects tag names — no repeated CDP calls.

// for <span> inside <p> inside <article> inside <body> inside <html>
["p", "article", "body", "html"]
§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated, or BrowserError::ScriptExecutionFailed when CDP returns no value or the value is not a string array.

Source

pub async fn children_matching(&self, selector: &str) -> Result<Vec<Self>>

Return child elements matching selector as new NodeHandles.

Issues a single Runtime.callFunctionOn + DOM.querySelectorAll call scoped to this element — not to the entire document.

Returns an empty Vec when no children match (consistent with the JS querySelectorAll contract).

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated, or BrowserError::CdpError on transport failure.

Source

pub async fn parent(&self) -> Result<Option<Self>>

Return the immediate parent element, or None if this element has no parent (i.e. it is the document root).

Issues a single Runtime.callFunctionOn CDP call that temporarily tags the parent element with a unique attribute, then resolves it via a document-level DOM.querySelector before removing the tag.

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated.

§Example
use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
use std::time::Duration;

let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;
let nodes = page.query_selector_all("p").await?;
if let Some(parent) = nodes[0].parent().await? {
    let html = parent.outer_html().await?;
    println!("parent: {}", &html[..html.len().min(80)]);
}
Source

pub async fn next_sibling(&self) -> Result<Option<Self>>

Return the next element sibling, or None if this element is the last child of its parent.

Uses nextElementSibling (skips text/comment nodes).

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated.

§Example
use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
use std::time::Duration;

let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;
let nodes = page.query_selector_all("li").await?;
if let Some(next) = nodes[0].next_sibling().await? {
    println!("next sibling: {}", next.text_content().await?);
}
Source

pub async fn previous_sibling(&self) -> Result<Option<Self>>

Return the previous element sibling, or None if this element is the first child of its parent.

Uses previousElementSibling (skips text/comment nodes).

§Errors

Returns BrowserError::StaleNode when the remote object has been invalidated.

§Example
use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
use std::time::Duration;

let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;
let nodes = page.query_selector_all("li").await?;
if let Some(prev) = nodes[1].previous_sibling().await? {
    println!("prev sibling: {}", prev.text_content().await?);
}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more