Playwright (and recent Puppeteer) call Target.attachToBrowserTarget on connect to obtain a session for the implicit "browser" target. Without the handler the dispatcher returns "Unknown Target method: attachToBrowserTarget" and the connect handshake aborts before any user code runs. Add a handler that mirrors Target.attachToTarget but for the browser target: register a "browser-session" → "browser" mapping in ctx.sessions, emit Target.attachedToTarget with type=browser, and return the new session id. Note: this addresses item (1) from #64. The Rocket Loader / Cloudflare JS execution gap and Page.getLayoutMetrics are tracked separately (getLayoutMetrics is fixed in PR #79). Generated by Ora Studio Vibe coded by ousamabenyounes Co-authored-by: Ora Studio <noreply@oratelecom.net>
This commit is contained in:
1 parent
3bb628eaf0
commit
23753405e5
1 file changed
+64
@@ -104,6 +104,31 @@ pub async fn handle(method: &str, params: &Value, ctx: &mut CdpContext) -> Resul
|
||||
|
||||
Ok(json!({ "targetId": page_id }))
|
||||
}
|
||||
"attachToBrowserTarget" => {
|
||||
// Playwright calls this on connect to obtain a session for the
|
||||
// implicit "browser" target. Returning Unknown method aborts
|
||||
// the connect handshake before any user code runs.
|
||||
let session_id = "browser-session".to_string();
|
||||
ctx.sessions.insert(session_id.clone(), "browser".to_string());
|
||||
|
||||
ctx.pending_events.push(CdpEvent::new(
|
||||
"Target.attachedToTarget",
|
||||
json!({
|
||||
"sessionId": session_id,
|
||||
"targetInfo": {
|
||||
"targetId": "browser",
|
||||
"type": "browser",
|
||||
"title": "",
|
||||
"url": "",
|
||||
"attached": true,
|
||||
"browserContextId": "",
|
||||
},
|
||||
"waitingForDebugger": false,
|
||||
}),
|
||||
));
|
||||
|
||||
Ok(json!({ "sessionId": session_id }))
|
||||
}
|
||||
"attachToTarget" => {
|
||||
let target_id = params.get("targetId").and_then(|v| v.as_str())
|
||||
.ok_or("targetId required")?;
|
||||
@@ -194,3 +219,42 @@ pub async fn handle(method: &str, params: &Value, ctx: &mut CdpContext) -> Resul
|
||||
_ => Err(format!("Unknown Target method: {}", method)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn attach_to_browser_target_returns_session_id() {
|
||||
let mut ctx = CdpContext::new();
|
||||
let result = handle("attachToBrowserTarget", &json!({}), &mut ctx)
|
||||
.await
|
||||
.expect("attachToBrowserTarget should succeed");
|
||||
|
||||
assert_eq!(result["sessionId"], "browser-session");
|
||||
assert_eq!(
|
||||
ctx.sessions.get("browser-session").map(String::as_str),
|
||||
Some("browser")
|
||||
);
|
||||
|
||||
// Playwright/Puppeteer expect a Target.attachedToTarget event before
|
||||
// they finish wiring up the session — without it the connect promise
|
||||
// hangs.
|
||||
let attached_evt = ctx
|
||||
.pending_events
|
||||
.iter()
|
||||
.find(|e| e.method == "Target.attachedToTarget")
|
||||
.expect("attachedToTarget event must be emitted");
|
||||
assert_eq!(attached_evt.params["sessionId"], "browser-session");
|
||||
assert_eq!(attached_evt.params["targetInfo"]["type"], "browser");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn unknown_target_method_still_errors() {
|
||||
let mut ctx = CdpContext::new();
|
||||
let err = handle("notARealMethod", &json!({}), &mut ctx)
|
||||
.await
|
||||
.expect_err("unknown methods must surface as errors");
|
||||
assert!(err.contains("Unknown Target method"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user