cloudflare / chrome-devtools-rs

Rust library for the Chrome Devtools Protocol
MIT License
62 stars 4 forks source link

just in case you didn't know about this other crate #20

Closed Dowwie closed 4 years ago

Dowwie commented 4 years ago

Hi. Just in case you weren't aware of this other related project, I am bringing it to your attention: https://github.com/atroche/rust-headless-chrome

EverlastingBugstopper commented 4 years ago

well would ya look at that! taking a look now.

EverlastingBugstopper commented 4 years ago

Hey @Dowwie - I really appreciate your super quick response to the creation of this repository. I've done some investigation into the crate you've linked and I'm not quite sure it fits my needs. My primary need is not to interact with chrome directly, but with the protocol itself - specifically wrt console.log messages (Runtime.consoleAPICalled).

I think that the rust-headless-chrome crate probably fits the use cases of people trying to do Puppeteer style automation but I'm looking for a way to serialize from protocol json {method: {...}, params: {...}} to nested structs

The API I'm trying to go for here is something like this (very very rough pseudo rust follows):

use chrome_devtools::events::DevtoolsEvent;
use crate::DevtoolsClient; // some websocket wrapper that takes a websocket url in constructor
let ws = DevtoolsClient::new("wss://example.com/inspector/uuid")?;
impl DevtoolsClient {
  onMessage(msg: String) {
    let msg: <DevtoolsEvent, _> = serde_json::from_str(msg)?;
    println!("{}", msg);
  }
}

which means I have a top level enum that looks like this:

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "method", content = "params")]
pub enum DevtoolsEvent {
    #[serde(rename = "Runtime.consoleAPICalled")]
    ConsoleAPICalled(ConsoleEvent),
    #[serde(rename = "Runtime.exceptionThrown")]
    ExceptionThrown(ExceptionEvent),
}

impl fmt::Display for DevtoolsEvent {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match &self {
            DevtoolsEvent::ConsoleAPICalled(event) => write!(f, "{}", event),
            DevtoolsEvent::ExceptionThrown(event) => write!(f, "{}", event),
        }
    }
}

I took a look at the crate you linked and it seems to require everything to be run inside of a tab, which my use case doesn't interact with.

I hope this makes sense and if you think that the other crate could be extended to fit this use case, I'd love to talk! I don't want to reinvent the wheel!

It's probably important to note that this is for use in https://github.com/cloudflare/wrangler which will be streaming console.log messages from a websocket to stdout. The devtools protocol it's using as a backend is not yet fully implemented - it really only has the console and network tabs and is not running in Chrome.

Dowwie commented 4 years ago

It was by a very random occurrence that I stumbled upon your work. I'm not the author of rust-headless-chrome but did contribute a piece earlier this year (print-to-pdf and remote connection). It is absolutely a puppeteer clone. Shouldn't a DevTools library act as a building block for your purposes AND rust-headless-chrome? You may save yourself effort by taking what was already rewritten, no? The author may be open to creating a Workspace that separates core_devtools protocol work from the client..

Good luck!

EverlastingBugstopper commented 4 years ago

Ah! Thanks @Dowwie - I'll reach out to them about that

EverlastingBugstopper commented 4 years ago

rust-headless-chrome does not quite fit my use case, and I think there is room for a crate that stands by itself as a serializer/deserializer for all of the devtools message types. What is here is not quite there yet, and I'm sure some code from that other crate could be reused.