rubycdp / ferrum

Headless Chrome Ruby API
https://ferrum.rubycdp.com
MIT License
1.7k stars 122 forks source link

Javascript: Async/await #475

Open erikaxel opened 1 month ago

erikaxel commented 1 month ago

Describe the bug Ferrum gives error on top level await calls in javascript

To Reproduce Running the following javascript (through Cuprite, but the issue is in Ferrum):

  page.execute_script "await new Promise(r => setTimeout(r, 100));"

will give

Ferrum::JavaScriptError: SyntaxError: await is only valid in async functions and the top level bodies of modules

Expected behavior It runs

Additional context The same works if run through Selenium.

I'm pretty sure the problem is that the executable script is wrapped in a function in https://github.com/rubycdp/ferrum/blob/19767d0885afbebc95574eda685e04dc9da2b47d/lib/ferrum/frame/runtime.rb#L84 and that function does not use the async keyword.

I'm not sure which Chrome versions Ferrum is targeting, but async/await has been available since Chrome 62 which came out in October 2017. So if it is ok to not support javascript execution in Chrome older than 62, one solution which might work could be to just add async:

expression = format("async function() { %s }", expression)

If this is an acceptable solution I will be happy to provide a PR.

route commented 1 month ago

@erikaxel sounds good to me in general, though I don't like current JS API which was type of inherited from Poltergeist. I say let's try if it works and doesn't break non-async function execution.