Skip to content

Commit

Permalink
Implement function to fetch existing targets when connecting to exist…
Browse files Browse the repository at this point in the history
…ing chromium instance (#187)

* feat(browser): fetch existing targets(pages)

* rustfmt

---------

Co-authored-by: Matthias Seitz <[email protected]>
  • Loading branch information
hackermondev and mattsse authored Nov 6, 2023
1 parent 1b9d619 commit c189e64
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use futures::SinkExt;

use chromiumoxide_cdp::cdp::browser_protocol::target::{
CreateBrowserContextParams, CreateTargetParams, DisposeBrowserContextParams, TargetId,
TargetInfo,
};
use chromiumoxide_cdp::cdp::{CdpEventMessage, IntoEventKind};
use chromiumoxide_types::*;
Expand Down Expand Up @@ -177,6 +178,26 @@ impl Browser {
Ok((browser, fut))
}

/// Request to fetch all existing browser targets.
///
/// By default, only targets launched after the browser connection are tracked
/// when connecting to a existing browser instance with the devtools websocket url
/// This function fetches existing targets on the browser and adds them as pages internally
///
/// The pages are not guaranteed to be ready as soon as the function returns
/// You should wait a few millis if you need to use a page
/// Returns [TargetInfo]
pub async fn fetch_targets(&mut self) -> Result<Vec<TargetInfo>> {
let (tx, rx) = oneshot_channel();

self.sender
.clone()
.send(HandlerMessage::FetchTargets(tx))
.await?;

rx.await?
}

/// Request for the browser to close completely.
///
/// If the browser was spawned by [`Browser::launch`], it is recommended to wait for the
Expand Down
45 changes: 45 additions & 0 deletions src/handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,30 @@ impl Handler {
}
}
}
PendingRequest::GetTargets(tx) => {
match to_command_response::<GetTargetsParams>(resp, method) {
Ok(resp) => {
let targets: Vec<TargetInfo> = resp.result.target_infos;
let results = targets.clone();
for target_info in targets {
let target_id = target_info.target_id.clone();
let event: EventTargetCreated = EventTargetCreated { target_info };
self.on_target_created(event);
let attach = AttachToTargetParams::new(target_id);
let _ = self.conn.submit_command(
attach.identifier(),
None,
serde_json::to_value(attach).unwrap(),
);
}

let _ = tx.send(Ok(results)).ok();
}
Err(err) => {
let _ = tx.send(Err(err)).ok();
}
}
}
PendingRequest::Navigate(id) => {
self.on_navigation_response(id, resp);
}
Expand Down Expand Up @@ -266,6 +290,18 @@ impl Handler {
Ok(())
}

fn submit_fetch_targets(&mut self, tx: OneshotSender<Result<Vec<TargetInfo>>>, now: Instant) {
let msg = GetTargetsParams { filter: None };
let method = msg.identifier();
let call_id = self
.conn
.submit_command(method.clone(), None, serde_json::to_value(msg).unwrap())
.unwrap();

self.pending_commands
.insert(call_id, (PendingRequest::GetTargets(tx), method, now));
}

/// Send the Request over to the server and store its identifier to handle
/// the response once received.
fn submit_navigation(&mut self, id: NavigationId, req: CdpRequest, now: Instant) {
Expand Down Expand Up @@ -456,6 +492,9 @@ impl Handler {
PendingRequest::CreateTarget(tx) => {
let _ = tx.send(Err(CdpError::Timeout));
}
PendingRequest::GetTargets(tx) => {
let _ = tx.send(Err(CdpError::Timeout));
}
PendingRequest::Navigate(nav) => {
if let Some(nav) = self.navigations.remove(&nav) {
match nav {
Expand Down Expand Up @@ -498,6 +537,9 @@ impl Stream for Handler {
HandlerMessage::Command(cmd) => {
pin.submit_external_command(cmd, now)?;
}
HandlerMessage::FetchTargets(tx) => {
pin.submit_fetch_targets(tx, now);
}
HandlerMessage::CloseBrowser(tx) => {
pin.submit_close(tx, now);
}
Expand Down Expand Up @@ -679,6 +721,8 @@ enum PendingRequest {
/// A Request to create a new `Target` that results in the creation of a
/// `Page` that represents a browser page.
CreateTarget(OneshotSender<Result<Page>>),
/// A Request to fetch old `Target`s created before connection
GetTargets(OneshotSender<Result<Vec<TargetInfo>>>),
/// A Request to navigate a specific `Target`.
///
/// Navigation requests are not automatically completed once the response to
Expand All @@ -701,6 +745,7 @@ enum PendingRequest {
#[derive(Debug)]
pub(crate) enum HandlerMessage {
CreatePage(CreateTargetParams, OneshotSender<Result<Page>>),
FetchTargets(OneshotSender<Result<Vec<TargetInfo>>>),
InsertContext(BrowserContext),
DisposeContext(BrowserContext),
GetPages(OneshotSender<Vec<Page>>),
Expand Down

0 comments on commit c189e64

Please sign in to comment.