Source code for selenium_driverless.input.utils

from selenium_driverless.types.webelement import WebElement
from selenium_driverless.types import JSEvalException
import asyncio
from typing import Type
try:
    from cdp_patches.input import AsyncInput
    from cdp_patches.input import KeyboardCodes
except ImportError:
    # noinspection PyTypeChecker
    AsyncInput: Type["AsyncInput"] = "AsyncInput"
    KeyboardCodes: Type["KeyboardCodes"] = "KeyboardCodes"


[docs]async def select(elem: WebElement, value: str = None, text: str = None, async_input: AsyncInput = None, timeouts: float = 0.01) -> None: """ Selects an option of a ``<select>`` element :param elem: ``<select>`` element to select an option from :param value: value for the option to select (can be different from the text!) :param text: the text of the option to select :param async_input: an instance of ``cdp_patches.input.AsyncInput`` :param timeouts: timeout in seconds between actions performed to select an option .. warning:: this is potentially detectable without the use of `CDP-patches <https://github.com/Kaliiiiiiiiii-Vinyzu/CDP-Patches>`_ ! """ use_js = async_input is None if use_js: await elem.click() else: x, y = await elem.mid_location() await async_input.click("left", x, y) if value is None and text is None: raise ValueError("value or text need to be specified") try: n, direction = await elem.execute_script(""" let [value, text, use_js] = arguments var idx = Array.from(obj.options).findIndex(option => option.value === value || option.text === text) var currIdx = obj.selectedIndex if (idx === -1){throw ReferenceError("option not found")} if(typeof value == 'undefined'){ value = obj.options[idx].value } if(use_js && obj.options[currIdx].value !== value){ obj.value = value const evt = new Event("change") evt.initEvent("change", true, true) obj.dispatchEvent(evt) return [0, 1] }else{ const n = Math.abs(idx - currIdx); const direction = idx < currIdx ? 1 : -1 return [n, direction] } """, value, text, use_js) except JSEvalException as e: if e.class_name == "ReferenceError" and e.description[:33] == 'ReferenceError: option not found\n': raise ValueError(f"option not found based on value:{value}, text:{text} for {elem}") raise e if use_js is False: if direction == 1: code = KeyboardCodes.UP_ARROW else: code = KeyboardCodes.DOWN_ARROW for _ in range(n): await asyncio.sleep(timeouts) async_input.base.send_keystrokes(code) await asyncio.sleep(timeouts) x, y = await elem.mid_location() await async_input.click("left", x, y) await asyncio.sleep(timeouts)