For the purpose of creating a test suite, I am using chromiumoxide
and trying to execute some Javascript which contains console.assert
statements and to listen for errors and any error messages. For example, the below executes a console.assert
statement which throws an error. I would like to collect that error and it's message. In the docs I was able to find some types that seemed relevant to this task, eg CdpEvent
, but I wasn't able to get any further than that.
use chromiumoxide::browser::{Browser, BrowserConfig};
use futures::StreamExt;
use tokio;
#[tokio::test]
async fn check_javascript() -> Result<(), Box<dyn std::error::Error>> {
let (mut browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?;
let handle = tokio::task::spawn(async move {
while let Some(h) = handler.next().await {
match h {
Ok(_) => continue,
Err(_) => break,
}
}
});
let page = browser.new_page("about:blank").await?;
page.evaluate_expression("console.assert(2 === 3, { msg: 'numbers do not match' });").await?;
browser.close().await?;
handle.await?;
Ok(())
}
We need to enable breakpoints on all exceptions (that includes console.assert
s), and attach an event listener for "paused in debugger" events. I was unable to find how to extract the message, though.
use std::error::Error;
use std::sync::Arc;
use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::cdp::js_protocol::debugger::*;
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let (mut browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?;
let handle = tokio::task::spawn(async move {
while let Some(h) = handler.next().await {
match h {
Ok(_) => continue,
Err(_) => break,
}
}
});
let page = browser.new_page("about:blank").await?;
page.enable_debugger().await?;
let mut events = page.event_listener::<EventPaused>().await?;
let events_handle = tokio::spawn({
let page = page.clone();
async move {
while let Some(event) = events.next().await {
if event.reason == PausedReason::Assert {
dbg!(event);
}
page.execute(ResumeParams::default()).await?;
}
Ok::<(), Box<dyn Error + Send + Sync>>(())
}
});
page.execute(SetPauseOnExceptionsParams {
state: SetPauseOnExceptionsState::All,
})
.await?;
page.evaluate_expression("console.assert(2 === 3, { msg: 'numbers do not match' });")
.await?;
browser.close().await?;
handle.await?;
events_handle.await??;
Ok(())
}