Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How does Page.expose_function work? #223

Closed
Havunen opened this issue Jul 23, 2024 · 4 comments · Fixed by #224
Closed

How does Page.expose_function work? #223

Havunen opened this issue Jul 23, 2024 · 4 comments · Fixed by #224

Comments

@Havunen
Copy link
Contributor

Havunen commented Jul 23, 2024

Hi,

Can somebody provide example or more info how Page.expose_function is supposed to be used?

chromiumoxide/src/page.rs

Lines 272 to 290 in 0897fb5

pub async fn expose_function(
&self,
name: impl Into<String>,
function: impl AsRef<str>,
) -> Result<()> {
let name = name.into();
let expression = utils::evaluation_string(function, &["exposedFun", name.as_str()]);
self.execute(AddBindingParams::new(name)).await?;
self.execute(AddScriptToEvaluateOnNewDocumentParams::new(
expression.clone(),
))
.await?;
// TODO add execution context tracking for frames
//let frames = self.frames().await?;
Ok(())
}

I got it to compile used like this:

        let pages = browser.pages().await.expect("Failed to get pages");
        let page = pages.first().expect("No pages found");

        // Correct usage based on the provided snippet and error description
        let js_function = r#"
    function(args) {
        console.log('SetInterval called with args:', args);
        return Promise.resolve();
    }
"#;

        page.expose_function("$#MT#SetInterval", js_function)
            .await
            .expect("Failed to expose function!");

and it seems to get registered client side:

Screenshot from 2024-07-23 13-23-15

But that does not fulfill the purpose why expose_function exists, the idea is to expose a method so client side JS could call the Rust backend as shown here: https://pptr.dev/api/puppeteer.page.exposefunction.

Am I missing something here or is this functionality broken?

@Havunen
Copy link
Contributor Author

Havunen commented Jul 23, 2024

This does not seem to print anything either...

let (browser, mut handler) = Browser::launch(browser_config)
    .await
    .expect("Failed to launch browser");

// Spawn a task to handle browser events
tokio::spawn(async move {
    while let Some(event) = handler.next().await {
        println!("Event: {:?}", event);
    }
});

page.execute(AddBindingParams::new("MTMTMT1")).await.expect("Failed to add binding");

let mut event_listener: EventStream<EventBindingCalled> = browser.event_listener().await.expect("Failed to get event listener");

tokio::spawn(async move {
    while let Some(event) = event_listener.next().await {
        println!("Event 2: {:?}", event);
    }
});

The MTMTMT1 is shown in the client side side but calling it does not print anything in rust backend

... there has to be some way

@Havunen
Copy link
Contributor Author

Havunen commented Jul 23, 2024

After going through the source code I figured out how this is done. I opened a PR for new example to possibly help others with similar issue. #224

@Havunen
Copy link
Contributor Author

Havunen commented Jul 23, 2024

Achieving this functionality is possible by using let mut listener = page.event_listener::<EventBindingCalled>().await?; Wether expose_function method works as expected is still unclear

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant