From a7b1acfa18d0914024efbf6c3dde20dc7549b465 Mon Sep 17 00:00:00 2001 From: Ben Younes Date: Sun, 3 May 2026 17:22:24 +0200 Subject: [PATCH] fix(cdp): accept Audits domain as no-op for Puppeteer compatibility (#57) (#80) Puppeteer's FrameManager.initialize calls Audits.enable on connect. Without it puppeteer.connect() fails with "Unknown domain: Audits" before any user code runs. Playwright doesn't enable Audits, which is why the workaround in #57 sidesteps the issue. Add Audits to the existing accepted-but-no-op domain list, alongside Log/Performance/Security/etc. that already swallow Puppeteer's connect chatter. No new module needed. Generated by Ora Studio Vibe coded by ousamabenyounes Co-authored-by: Ora Studio --- crates/obscura-cdp/src/dispatch.rs | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/crates/obscura-cdp/src/dispatch.rs b/crates/obscura-cdp/src/dispatch.rs index 26480bd..35d2463 100644 --- a/crates/obscura-cdp/src/dispatch.rs +++ b/crates/obscura-cdp/src/dispatch.rs @@ -136,9 +136,13 @@ pub async fn dispatch(req: &CdpRequest, ctx: &mut CdpContext) -> CdpResponse { "Storage" => domains::storage::handle(method, &req.params, ctx, &req.session_id).await, "LP" => domains::lp::handle(method, &req.params, ctx, &req.session_id).await, "Accessibility" => domains::accessibility::handle(method, &req.params, ctx, &req.session_id).await, + // Accepted but no-op. Puppeteer's FrameManager.initialize calls + // Audits.enable on connect — refusing it breaks puppeteer.connect() + // before any user code runs. "Emulation" | "Log" | "Performance" | "Security" | "CSS" | "ServiceWorker" | "Inspector" - | "Debugger" | "Profiler" | "HeapProfiler" | "Overlay" => { + | "Debugger" | "Profiler" | "HeapProfiler" | "Overlay" + | "Audits" => { Ok(json!({})) } _ => Err(format!("Unknown domain: {}", domain)), @@ -152,3 +156,35 @@ pub async fn dispatch(req: &CdpRequest, ctx: &mut CdpContext) -> CdpResponse { } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::types::CdpRequest; + + fn req(method: &str) -> CdpRequest { + CdpRequest { + id: 1, + method: method.into(), + params: json!({}), + session_id: None, + } + } + + #[tokio::test] + async fn audits_enable_returns_empty_success() { + let mut ctx = CdpContext::new(); + let resp = dispatch(&req("Audits.enable"), &mut ctx).await; + assert!(resp.error.is_none(), "Audits.enable should not error: {:?}", resp.error); + assert_eq!(resp.result, Some(json!({}))); + } + + #[tokio::test] + async fn unknown_domain_still_errors() { + let mut ctx = CdpContext::new(); + let resp = dispatch(&req("DefinitelyNotADomain.enable"), &mut ctx).await; + let err = resp.error.expect("unknown domain must surface as error"); + assert_eq!(err.code, -32601); + assert!(err.message.contains("Unknown domain")); + } +}