Skip to main content

allwright_surface_web/
capture.rs

1use super::*;
2use allwright_plugin_sdk::CaptureInfo;
3
4fn expression(kind: &str, selector: &str, attribute: &str) -> Result<String, String> {
5    let element = if kind == "url" {
6        "null".to_string()
7    } else {
8        let segments = selector_segments_literal("capture", selector)?;
9        format!(
10            "(() => {{ const selectorSegments = {segments}; return ({})[0]; }})()",
11            selector_chain_query_all_js()
12        )
13    };
14    Ok(format!(
15        "JSON.stringify(({})({}, {}, {}))",
16        include_str!("capture.js"),
17        json_string_literal(kind, "capture kind")?,
18        element,
19        json_string_literal(attribute, "attribute name")?
20    ))
21}
22
23pub async fn capture(
24    browser: &BrowserSessionHandle,
25    page: &PageSessionHandle,
26    kind: &str,
27    selector: &str,
28    attribute: &str,
29) -> Result<CaptureInfo, String> {
30    let expression = expression(kind, selector, attribute)?;
31    let value = match (browser, page) {
32        (
33            BrowserSessionHandle::Chromium { cdp_websocket_url },
34            PageSessionHandle::Chromium {
35                target_id,
36                browsing_context_id,
37                mapper_target_id,
38            },
39        ) => {
40            chromium_bidi_evaluate_json(
41                cdp_websocket_url,
42                mapper_target_id.as_deref(),
43                Some(browsing_context_id.as_deref().unwrap_or(target_id)),
44                &expression,
45            )
46            .await?
47        }
48        (
49            BrowserSessionHandle::Firefox { connection_id, .. },
50            PageSessionHandle::Firefox {
51                browsing_context_id,
52            },
53        ) => {
54            let mut sessions = firefox_session_guard(connection_id).await?;
55            let bidi = &mut sessions
56                .get_mut(connection_id)
57                .expect("validated Firefox session")
58                .connection;
59            firefox_evaluate_json(bidi, browsing_context_id, &expression).await?
60        }
61        _ => return Err("browser/page backend mismatch while capturing".into()),
62    };
63    serde_json::from_value(value).map_err(|error| format!("invalid capture result: {error}"))
64}