use super::*; use std::fmt::Write; async fn evaluate_preparation_error_document(html: &str) -> Result { let mut document_url = String::from("data:text/html,"); for byte in html.bytes() { write!(&mut document_url, "%{byte:02X}")?; } let browser = Browser::new(AppConfig::default())?; let mut page = browser.fetch(&document_url).await?; let result = page .evaluate_runtime_expression_with_await_async( "preparationDone.then(() => JSON.stringify(probe))", true, ) .await?; serde_json::from_str(result["value"].as_str().expect("serialized probe")).map_err(Into::into) } #[tokio::test(flavor = "multi_thread")] async fn script_preparation_errors_target_elements_without_reporting_window_exceptions() -> Result<()> { let result = evaluate_preparation_error_document( r#" "#, ) .await?; let mut elements = result["elements"].as_array().unwrap().clone(); elements.sort_by(|left, right| left[0].as_str().cmp(&right[0].as_str())); let mut expected = [ "classic-empty", "classic-invalid", "async-empty", "defer-invalid", "module-empty", "module-invalid", "write-empty", "write-module", ] .map(|id| { serde_json::json!([ id, "error", false, false, false, true, true, false, true, true ]) }); expected.sort_by(|left, right| left[0].as_str().cmp(&right[0].as_str())); assert_eq!(elements, expected, "{result}"); assert_eq!(result["exceptions"], serde_json::json!([true]), "{result}"); assert_eq!(result["bubbles"], serde_json::json!([]), "{result}"); assert_eq!( result["reexecuted"], 0, "failed preparation must still mark the script already started" ); let mut captures = result["captures"].as_array().unwrap().clone(); captures.sort_by(|left, right| left.as_str().cmp(&right.as_str())); assert_eq!( captures, expected .iter() .map(|row| row[0].clone()) .collect::>() ); let mut checkpoints = result["checkpoints"].as_array().unwrap().clone(); checkpoints.sort_by(|left, right| left.as_str().cmp(&right.as_str())); assert_eq!( checkpoints, captures, "each error listener must complete its microtasks" ); Ok(()) } #[tokio::test(flavor = "multi_thread")] async fn script_preparation_errors_are_delivered_in_child_parser_documents() -> Result<()> { let server = FixtureServer::spawn().await?; let browser = Browser::new(AppConfig::default())?; let mut page = browser.fetch(&server.url("/static")).await?; let result = page.evaluate_runtime_expression_with_await_async( r#"new Promise(resolve => { const frame = document.createElement('iframe'); globalThis.childPreparationErrorsReady = result => { delete globalThis.childPreparationErrorsReady; resolve(JSON.stringify(result)); }; frame.srcdoc = `