kaliiiiiiiiii / Selenium-Driverless

undetected Selenium without usage of chromedriver

Home Page:https://kaliiiiiiiiii.github.io/Selenium-Driverless/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[feature request] `driver.execute_async_script` alternative

milahu opened this issue · comments

currently, driver.execute_async_script only provides
a resolve function in arguments[arguments.length - 1]

if exec_context and obj_id:
args = [self, *args]
script = """
(function(...arguments){
const obj = arguments.shift()
const promise = new Promise((resolve, reject) => {
arguments.push(resolve)
});""" + script + ";return promise})"
else:
script = """(function(...arguments){
const obj = this
const promise = new Promise((resolve, reject) => {
arguments.push(resolve)
});""" + script + ";return promise})"
res = await self.__exec_raw__(script, *args, max_depth=max_depth,
serialization=serialization, timeout=timeout,
await_res=True,
execution_context_id=exec_context)
return res

this is compatible with selenium execute_async_script
but... i dont see a way to throw an error from javascript
so currently, on error, i have to wait for the CDP timeout


the tests are a bit confusing, as they use resolve = arguments[0]

$ grep -r -w -h execute_async_script tests/
    async_token = await driver.execute_async_script('window.getAsyncToken().then(arguments[0])')
    async_token = driver.execute_async_script('window.getAsyncToken().then(arguments[0])')
        async_token = await driver.execute_async_script('window.getAsyncToken().then(arguments[0])')

ah yep indeed.
I thought of that as well.
My plan is to provide another method with smth like:

script = """(async function(...arguments){ 
       const obj = this;""" + script + ")" 

Haven't tested if that actually works yet tho.

Smth like the following will be supported.
Like it way more than execute_async_script

import asyncio
from selenium_driverless import webdriver


async def main():
    options = webdriver.ChromeOptions()
    options.add_arguments(
        "--disable-web-security",  # disable CORS
        "--headless=new")
    async with webdriver.Chrome(options=options) as driver:
        url = "https://httpbin.org/get"
        window = await driver.execute_script("return window")
        res = await window.__eval_async__('''
                res = await fetch(arguments[0]);
                json = await res.json()
                return json
            ''', url)
        print(dict(**res.headers))


asyncio.run(main())