diff --git a/examples/cdp_mode/raw_multi_async.py b/examples/cdp_mode/raw_multi_async.py new file mode 100644 index 00000000000..cfbd64a2db3 --- /dev/null +++ b/examples/cdp_mode/raw_multi_async.py @@ -0,0 +1,29 @@ +# Testing multiple CDP drivers using the async API +import asyncio +from concurrent.futures import ThreadPoolExecutor +from random import randint +from seleniumbase.undetected import cdp_driver + + +async def main(url): + driver = await cdp_driver.cdp_util.start_async() + page = await driver.get(url) + await page.set_window_rect(randint(4, 600), randint(8, 410), 860, 500) + await page.sleep(0.5) + field = await page.select("input") + await field.send_keys_async("Text") + button = await page.select("button") + await button.click_async() + await page.sleep(2) + + +def set_up_loop(url): + loop = asyncio.new_event_loop() + loop.run_until_complete(main(url)) + + +if __name__ == "__main__": + urls = ["https://seleniumbase.io/demo_page" for i in range(4)] + with ThreadPoolExecutor(max_workers=len(urls)) as executor: + for url in urls: + executor.submit(set_up_loop, url) diff --git a/examples/cdp_mode/raw_multi_cdp.py b/examples/cdp_mode/raw_multi_cdp.py new file mode 100644 index 00000000000..c7f42f4f6a4 --- /dev/null +++ b/examples/cdp_mode/raw_multi_cdp.py @@ -0,0 +1,25 @@ +# Testing multiple CDP drivers using the sync API +import asyncio +from concurrent.futures import ThreadPoolExecutor +from random import randint +from seleniumbase.core import sb_cdp +from seleniumbase.undetected import cdp_driver + + +def main(url): + loop = asyncio.new_event_loop() + driver = cdp_driver.cdp_util.start_sync() + page = loop.run_until_complete(driver.get(url)) + sb = sb_cdp.CDPMethods(loop, page, driver) + sb.set_window_rect(randint(4, 720), randint(8, 410), 800, 500) + sb.press_keys("input", "Text") + sb.highlight("button") + sb.click("button") + sb.sleep(2) + + +if __name__ == "__main__": + urls = ["https://seleniumbase.io/demo_page" for i in range(4)] + with ThreadPoolExecutor(max_workers=len(urls)) as executor: + for url in urls: + executor.submit(main, url) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index ad541b90471..7cfecb2463f 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.34.7" +__version__ = "4.34.8" diff --git a/seleniumbase/core/sb_cdp.py b/seleniumbase/core/sb_cdp.py index 403011e894e..98755cc7c1b 100644 --- a/seleniumbase/core/sb_cdp.py +++ b/seleniumbase/core/sb_cdp.py @@ -877,8 +877,13 @@ def set_value(self, selector, text, timeout=None): def evaluate(self, expression): """Run a JavaScript expression and return the result.""" - if expression.startswith("return "): - expression = expression[len("return "):] + expression = expression.strip() + exp_list = expression.split("\n") + if exp_list and exp_list[-1].strip().startswith("return "): + expression = ( + "\n".join(exp_list[0:-1]) + "\n" + + exp_list[-1].strip()[len("return "):] + ).strip() return self.loop.run_until_complete( self.page.evaluate(expression) ) diff --git a/seleniumbase/undetected/cdp_driver/cdp_util.py b/seleniumbase/undetected/cdp_driver/cdp_util.py index 237ba3b28b3..a30ddb536d3 100644 --- a/seleniumbase/undetected/cdp_driver/cdp_util.py +++ b/seleniumbase/undetected/cdp_driver/cdp_util.py @@ -241,7 +241,18 @@ async def start_async(*args, **kwargs) -> Browser: def start_sync(*args, **kwargs) -> Browser: - loop = asyncio.get_event_loop() + loop = None + if ( + "loop" in kwargs + and kwargs["loop"] + and hasattr(kwargs["loop"], "create_task") + ): + loop = kwargs["loop"] + else: + try: + loop = asyncio.get_event_loop() + except RuntimeError: + loop = asyncio.new_event_loop() headless = False binary_location = None if "browser_executable_path" in kwargs: diff --git a/seleniumbase/undetected/cdp_driver/tab.py b/seleniumbase/undetected/cdp_driver/tab.py index 7cc3f71c589..3f74354989a 100644 --- a/seleniumbase/undetected/cdp_driver/tab.py +++ b/seleniumbase/undetected/cdp_driver/tab.py @@ -896,6 +896,10 @@ async def set_window_size(self, left=0, top=0, width=1280, height=1024): """ return await self.set_window_state(left, top, width, height) + async def set_window_rect(self, left=0, top=0, width=1280, height=1024): + """Same as set_window_size(). Uses a different naming convention.""" + return await self.set_window_state(left, top, width, height) + async def activate(self): """Active this target (Eg: tab, window, page)""" await self.send(cdp.target.activate_target(self.target.target_id))