From db012234fc9760cc41357f8c7011e1cd9f454a75 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 2 Aug 2024 18:43:41 -0400 Subject: [PATCH 1/6] Allow Mobile Mode "device_pixel_ratio" to use floats --- seleniumbase/core/browser_launcher.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py index 79f64eb4eee..37fae421bba 100644 --- a/seleniumbase/core/browser_launcher.py +++ b/seleniumbase/core/browser_launcher.py @@ -394,9 +394,9 @@ def uc_special_open_if_cf( ) uc_metrics = {} if ( - isinstance(device_width, int) - and isinstance(device_height, int) - and isinstance(device_pixel_ratio, int) + isinstance(device_width, (int, float)) + and isinstance(device_height, (int, float)) + and isinstance(device_pixel_ratio, (int, float)) ): uc_metrics["width"] = device_width uc_metrics["height"] = device_height @@ -1479,9 +1479,9 @@ def _set_chrome_options( emulator_settings = {} device_metrics = {} if ( - isinstance(device_width, int) - and isinstance(device_height, int) - and isinstance(device_pixel_ratio, int) + isinstance(device_width, (int, float)) + and isinstance(device_height, (int, float)) + and isinstance(device_pixel_ratio, (int, float)) ): device_metrics["width"] = device_width device_metrics["height"] = device_height @@ -3229,9 +3229,9 @@ def get_local_driver( emulator_settings = {} device_metrics = {} if ( - isinstance(device_width, int) - and isinstance(device_height, int) - and isinstance(device_pixel_ratio, int) + isinstance(device_width, (int, float)) + and isinstance(device_height, (int, float)) + and isinstance(device_pixel_ratio, (int, float)) ): device_metrics["width"] = device_width device_metrics["height"] = device_height @@ -4446,9 +4446,9 @@ def get_local_driver( if mobile_emulator: uc_metrics = {} if ( - isinstance(device_width, int) - and isinstance(device_height, int) - and isinstance(device_pixel_ratio, int) + isinstance(device_width, (int, float)) + and isinstance(device_height, (int, float)) + and isinstance(device_pixel_ratio, (int, float)) ): uc_metrics["width"] = device_width uc_metrics["height"] = device_height From 8621dfeef6581f95c9efbd4be7db8d9fe11a3a4d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 2 Aug 2024 18:45:13 -0400 Subject: [PATCH 2/6] Update UC Mode --- seleniumbase/core/browser_launcher.py | 144 +++++++++++++++++--------- seleniumbase/fixtures/base_case.py | 8 +- 2 files changed, 103 insertions(+), 49 deletions(-) diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py index 37fae421bba..fd91f59785f 100644 --- a/seleniumbase/core/browser_launcher.py +++ b/seleniumbase/core/browser_launcher.py @@ -975,9 +975,24 @@ def uc_gui_click_cf(driver, frame="iframe", retry=False, blind=False): ) -def uc_gui_handle_cf(driver, frame="iframe"): - if not _on_a_cf_turnstile_page(driver): - return +def _uc_gui_handle_captcha( + driver, + frame="iframe", + ctype=None, +): + if ctype == "cf_t": + if not _on_a_cf_turnstile_page(driver): + return + elif ctype == "g_rc": + if not _on_a_g_recaptcha_page(driver): + return + else: + if _on_a_g_recaptcha_page(driver): + ctype = "g_rc" + elif _on_a_cf_turnstile_page(driver): + ctype = "cf_t" + else: + return install_pyautogui_if_missing(driver) import pyautogui pyautogui = get_configured_pyautogui(pyautogui) @@ -988,7 +1003,10 @@ def uc_gui_handle_cf(driver, frame="iframe"): with gui_lock: # Prevent issues with multiple processes needs_switch = False is_in_frame = js_utils.is_in_frame(driver) - if is_in_frame and driver.is_element_present("#challenge-stage"): + selector = "#challenge-stage" + if ctype == "g_rc": + selector = "#recaptcha-token" + if is_in_frame and driver.is_element_present(selector): driver.switch_to.parent_frame() needs_switch = True is_in_frame = js_utils.is_in_frame(driver) @@ -997,67 +1015,77 @@ def uc_gui_handle_cf(driver, frame="iframe"): page_actions.switch_to_window( driver, driver.current_window_handle, 2, uc_lock=False ) - if ( - driver.is_element_present(".cf-turnstile-wrapper iframe") - or driver.is_element_present( - '[data-callback="onCaptchaSuccess"] iframe' - ) - ): - pass - else: - visible_iframe = False - if driver.is_element_present(".cf-turnstile-wrapper"): - frame = ".cf-turnstile-wrapper" - elif driver.is_element_present( - '[data-callback="onCaptchaSuccess"]' - ): - frame = '[data-callback="onCaptchaSuccess"]' - elif ( - driver.is_element_present('[name*="cf-turnstile-"]') - and driver.is_element_present("div.spacer div[style]") - ): - frame = "div.spacer div[style]" - elif ( - ( - driver.is_element_present('[name*="cf-turnstile-"]') - or driver.is_element_present('[id*="cf-turnstile-"]') - ) - and driver.is_element_present( - 'form div div[style*="margin"][style*="padding"]' + if ctype == "cf_t": + if ( + driver.is_element_present(".cf-turnstile-wrapper iframe") + or driver.is_element_present( + '[data-callback="onCaptchaSuccess"] iframe' ) ): - frame = 'form div div[style*="margin"][style*="padding"]' - elif ( - ( + pass + else: + visible_iframe = False + if driver.is_element_present(".cf-turnstile-wrapper"): + frame = ".cf-turnstile-wrapper" + elif driver.is_element_present( + '[data-callback="onCaptchaSuccess"]' + ): + frame = '[data-callback="onCaptchaSuccess"]' + elif ( driver.is_element_present('[name*="cf-turnstile-"]') - or driver.is_element_present('[id*="cf-turnstile-"]') - ) - and driver.is_element_present( - 'div > div > [style*="margin"][style*="padding"]' - ) + and driver.is_element_present("div.spacer div[style]") + ): + frame = "div.spacer div[style]" + elif ( + ( + driver.is_element_present('[name*="cf-turnstile-"]') + or driver.is_element_present('[id*="cf-turnstile-"]') + ) + and driver.is_element_present( + 'form div div[style*="margin"][style*="padding"]' + ) + ): + frame = 'form div div[style*="margin"][style*="padding"]' + elif ( + ( + driver.is_element_present('[name*="cf-turnstile-"]') + or driver.is_element_present('[id*="cf-turnstile-"]') + ) + and driver.is_element_present( + 'div > div > [style*="margin"][style*="padding"]' + ) + ): + frame = 'div > div > [style*="margin"][style*="padding"]' + else: + return + else: + if ( + driver.is_element_present('iframe[title="reCAPTCHA"]') + and frame == "iframe" ): - frame = 'div > div > [style*="margin"][style*="padding"]' - else: - return + frame = 'iframe[title="reCAPTCHA"]' if not is_in_frame or needs_switch: # Currently not in frame (or nested frame outside CF one) try: - if visible_iframe: + if visible_iframe or ctype == "g_rc": driver.switch_to_frame(frame) except Exception: - if visible_iframe: + if visible_iframe or ctype == "g_rc": if driver.is_element_present("iframe"): driver.switch_to_frame("iframe") else: return try: + selector = "div.cf-turnstile" + if ctype == "g_rc": + selector = "span#recaptcha-anchor" found_checkbox = False for i in range(24): pyautogui.press("\t") time.sleep(0.02) active_element_css = js_utils.get_active_element_css(driver) if ( - active_element_css.startswith("div.cf-turnstile") + active_element_css.startswith(selector) or active_element_css.endswith(" > div" * 2) ): found_checkbox = True @@ -1081,6 +1109,18 @@ def uc_gui_handle_cf(driver, frame="iframe"): driver.reconnect(reconnect_time) +def uc_gui_handle_captcha(driver, frame="iframe"): + _uc_gui_handle_captcha(driver, frame=frame, ctype=None) + + +def uc_gui_handle_cf(driver, frame="iframe"): + _uc_gui_handle_captcha(driver, frame=frame, ctype="cf_t") + + +def uc_gui_handle_rc(driver, frame="iframe"): + _uc_gui_handle_captcha(driver, frame=frame, ctype="g_rc") + + def uc_switch_to_frame(driver, frame="iframe", reconnect_time=None): from selenium.webdriver.remote.webelement import WebElement if isinstance(frame, WebElement): @@ -4421,13 +4461,18 @@ def get_local_driver( driver, *args, **kwargs ) ) + driver.uc_gui_click_cf = ( + lambda *args, **kwargs: uc_gui_click_cf( + driver, *args, **kwargs + ) + ) driver.uc_gui_click_rc = ( lambda *args, **kwargs: uc_gui_click_rc( driver, *args, **kwargs ) ) - driver.uc_gui_click_cf = ( - lambda *args, **kwargs: uc_gui_click_cf( + driver.uc_gui_handle_captcha = ( + lambda *args, **kwargs: uc_gui_handle_captcha( driver, *args, **kwargs ) ) @@ -4436,6 +4481,11 @@ def get_local_driver( driver, *args, **kwargs ) ) + driver.uc_gui_handle_rc = ( + lambda *args, **kwargs: uc_gui_handle_rc( + driver, *args, **kwargs + ) + ) driver.uc_switch_to_frame = ( lambda *args, **kwargs: uc_switch_to_frame( driver, *args, **kwargs diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 92e008eba04..428e61c66f7 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -4246,12 +4246,16 @@ def get_new_driver( self.uc_gui_click_x_y = new_driver.uc_gui_click_x_y if hasattr(new_driver, "uc_gui_click_captcha"): self.uc_gui_click_captcha = new_driver.uc_gui_click_captcha - if hasattr(new_driver, "uc_gui_click_rc"): - self.uc_gui_click_rc = new_driver.uc_gui_click_rc if hasattr(new_driver, "uc_gui_click_cf"): self.uc_gui_click_cf = new_driver.uc_gui_click_cf + if hasattr(new_driver, "uc_gui_click_rc"): + self.uc_gui_click_rc = new_driver.uc_gui_click_rc + if hasattr(new_driver, "uc_gui_handle_captcha"): + self.uc_gui_handle_captcha = new_driver.uc_gui_handle_captcha if hasattr(new_driver, "uc_gui_handle_cf"): self.uc_gui_handle_cf = new_driver.uc_gui_handle_cf + if hasattr(new_driver, "uc_gui_handle_rc"): + self.uc_gui_handle_rc = new_driver.uc_gui_handle_rc if hasattr(new_driver, "uc_switch_to_frame"): self.uc_switch_to_frame = new_driver.uc_switch_to_frame return new_driver From fda2ffe865c6757ace96a5356093df593935ffb2 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 2 Aug 2024 18:46:50 -0400 Subject: [PATCH 3/6] Update examples --- examples/raw_cdp_logging.py | 2 +- examples/raw_form_turnstile.py | 2 +- examples/raw_gui_click.py | 7 ++----- examples/raw_pyautogui.py | 7 ++----- examples/raw_recaptcha.py | 10 +++++++++- examples/uc_cdp_events.py | 2 +- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/examples/raw_cdp_logging.py b/examples/raw_cdp_logging.py index 1f9c7659665..23ae0b177a2 100644 --- a/examples/raw_cdp_logging.py +++ b/examples/raw_cdp_logging.py @@ -5,7 +5,7 @@ try: url = "seleniumbase.io/apps/turnstile" driver.uc_open_with_reconnect(url, 2) - driver.uc_gui_handle_cf() + driver.uc_gui_handle_captcha() driver.sleep(3) pprint(driver.get_log("performance")) finally: diff --git a/examples/raw_form_turnstile.py b/examples/raw_form_turnstile.py index 8e7bf6b7085..0ff1be0fa52 100644 --- a/examples/raw_form_turnstile.py +++ b/examples/raw_form_turnstile.py @@ -13,7 +13,7 @@ sb.highlight_click('input[value="AR"] + span') sb.click('input[value="cc"] + span') sb.scroll_to('div[class*="cf-turnstile"]') - sb.uc_gui_handle_cf() + sb.uc_gui_handle_captcha() sb.highlight("img#captcha-success", timeout=3) sb.highlight_click('button:contains("Request & Pay")') sb.highlight("img#submit-success") diff --git a/examples/raw_gui_click.py b/examples/raw_gui_click.py index f4dabb05d80..fb46fe747bd 100644 --- a/examples/raw_gui_click.py +++ b/examples/raw_gui_click.py @@ -1,10 +1,7 @@ -""" -UC Mode now has uc_gui_click_cf(), which uses PyAutoGUI. -An incomplete UserAgent forces CAPTCHA-solving on macOS. -""" import sys from seleniumbase import SB +# An incomplete UserAgent forces CAPTCHA-solving on macOS agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0.0.0" if "linux" in sys.platform or "win32" in sys.platform: agent = None # Use the default UserAgent @@ -12,7 +9,7 @@ with SB(uc=True, test=True, rtf=True, agent=agent) as sb: url = "https://gitlab.com/users/sign_in" sb.uc_open_with_reconnect(url, 4) - sb.uc_gui_click_cf() # Ready if needed! + sb.uc_gui_click_captcha() # Only if needed sb.assert_element('label[for="user_login"]') sb.assert_element('input[data-testid*="username"]') sb.assert_element('input[data-testid*="password"]') diff --git a/examples/raw_pyautogui.py b/examples/raw_pyautogui.py index 75616d2a769..7bc4eb27926 100644 --- a/examples/raw_pyautogui.py +++ b/examples/raw_pyautogui.py @@ -1,10 +1,7 @@ -""" -UC Mode now has uc_gui_handle_cf(), which uses PyAutoGUI. -An incomplete User-Agent forces CAPTCHA-solving on macOS. -""" import sys from seleniumbase import SB +# An incomplete UserAgent forces CAPTCHA-solving on macOS agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0.0.0" if "linux" in sys.platform or "win32" in sys.platform: agent = None # Use the default UserAgent @@ -12,7 +9,7 @@ with SB(uc=True, test=True, rtf=True, agent=agent) as sb: url = "https://gitlab.com/users/sign_in" sb.uc_open_with_reconnect(url, 4) - sb.uc_gui_handle_cf() # Ready if needed! + sb.uc_gui_handle_captcha() # Only if needed sb.assert_element('label[for="user_login"]') sb.assert_element('input[data-testid*="username"]') sb.assert_element('input[data-testid*="password"]') diff --git a/examples/raw_recaptcha.py b/examples/raw_recaptcha.py index c348bfdc244..a9a35e32c4d 100644 --- a/examples/raw_recaptcha.py +++ b/examples/raw_recaptcha.py @@ -3,7 +3,15 @@ with SB(uc=True, test=True) as sb: url = "https://seleniumbase.io/apps/recaptcha" sb.uc_open_with_reconnect(url) - sb.uc_gui_click_captcha() + sb.uc_gui_handle_captcha() # Try with TAB + SPACEBAR + sb.assert_element("img#captcha-success", timeout=3) + sb.set_messenger_theme(location="top_left") + sb.post_message("SeleniumBase wasn't detected", duration=3) + +with SB(uc=True, test=True) as sb: + url = "https://seleniumbase.io/apps/recaptcha" + sb.uc_open_with_reconnect(url) + sb.uc_gui_click_captcha() # Try with PyAutoGUI Click sb.assert_element("img#captcha-success", timeout=3) sb.set_messenger_theme(location="top_left") sb.post_message("SeleniumBase wasn't detected", duration=3) diff --git a/examples/uc_cdp_events.py b/examples/uc_cdp_events.py index d869c7513fc..6fcaf2c2477 100644 --- a/examples/uc_cdp_events.py +++ b/examples/uc_cdp_events.py @@ -13,7 +13,7 @@ def add_cdp_listener(self): ) def click_turnstile_and_verify(sb): - sb.uc_gui_handle_cf() + sb.uc_gui_handle_captcha() sb.assert_element("img#captcha-success", timeout=3) sb.highlight("img#captcha-success", loops=8) From 0f9592e0d81a3d2d23be6f71ae25a9b8cdfe50e8 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 2 Aug 2024 18:47:24 -0400 Subject: [PATCH 4/6] Update the UC Mode docs --- help_docs/method_summary.md | 10 +++++----- help_docs/uc_mode.md | 34 ++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/help_docs/method_summary.md b/help_docs/method_summary.md index c6dd040e08f..be5be59cec7 100644 --- a/help_docs/method_summary.md +++ b/help_docs/method_summary.md @@ -1077,12 +1077,12 @@ driver.uc_gui_write(text) # Similar to uc_gui_press_keys(), but faster driver.uc_gui_click_x_y(x, y, timeframe=0.25) # PyAutoGUI click screen driver.uc_gui_click_captcha(frame="iframe", retry=False, blind=False) +# driver.uc_gui_click_cf(frame="iframe", retry=False, blind=False) +# driver.uc_gui_click_rc(frame="iframe", retry=False, blind=False) -driver.uc_gui_click_rc(frame="iframe", retry=False, blind=False) # reC - -driver.uc_gui_click_cf(frame="iframe", retry=False, blind=False) # CFT - -driver.uc_gui_handle_cf(frame="iframe") # PyAutoGUI click CF Turnstile +driver.uc_gui_handle_captcha(frame="iframe") # (Auto-detects the CAPTCHA) +# driver.uc_gui_handle_cf(frame="iframe") # PyAutoGUI click CF Turnstile +# driver.uc_gui_handle_rc(frame="iframe") # PyAutoGUI click G. reCAPTCHA driver.uc_switch_to_frame(frame="iframe") # Stealthy switch_to_frame() ``` diff --git a/help_docs/uc_mode.md b/help_docs/uc_mode.md index 870c52e258b..425df65855c 100644 --- a/help_docs/uc_mode.md +++ b/help_docs/uc_mode.md @@ -45,7 +45,9 @@ with SB(uc=True) as sb: sb.uc_open_with_reconnect(url, 4) ``` -👤 Here's a longer example, which includes a special click if the CAPTCHA isn't bypassed on the initial page load: +(Note: If running UC Mode scripts on headless Linux machines, then you'll need to use the SB manager instead of the Driver manager because the SB manager includes a special virtual display that allows for PyAutoGUI actions.) + +👤 Here's a longer example, which includes a special PyAutoGUI click if the CAPTCHA isn't bypassed on the initial page load: ```python from seleniumbase import SB @@ -71,7 +73,7 @@ from seleniumbase import SB with SB(uc=True, test=True) as sb: url = "https://seleniumbase.io/apps/turnstile" sb.uc_open_with_reconnect(url, reconnect_time=2) - sb.uc_gui_handle_cf() + sb.uc_gui_handle_captcha() sb.assert_element("img#captcha-success", timeout=3) sb.set_messenger_theme(location="top_left") sb.post_message("SeleniumBase wasn't detected", duration=3) @@ -79,7 +81,7 @@ with SB(uc=True, test=True) as sb: -If running on a Linux server, `uc_gui_handle_cf()` might not be good enough. Switch to `uc_gui_click_cf()` to be more stealthy. You can also use `uc_gui_click_captcha()` as a generic CAPTCHA-clicker, which auto-detects between CF Turnstile and Google reCAPTCHA. +If running on a Linux server, `uc_gui_handle_captcha()` might not be good enough. Switch to `uc_gui_click_captcha()` to be more stealthy. Note that these methods auto-detect between CF Turnstile and Google reCAPTCHA. 👤 Here's an example where the CAPTCHA appears after submitting a form: @@ -118,7 +120,7 @@ with SB(uc=True, test=True, ad_block=True) as sb: -👤 On Linux, use `sb.uc_gui_click_cf()` to handle Cloudflare Turnstiles: +👤 On Linux, use `sb.uc_gui_click_captcha()` to handle CAPTCHAs (Cloudflare Turnstiles): ```python from seleniumbase import SB @@ -127,7 +129,7 @@ with SB(uc=True, test=True) as sb: url = "https://www.virtualmanager.com/en/login" sb.uc_open_with_reconnect(url, 4) print(sb.get_page_title()) - sb.uc_gui_click_cf() # Ready if needed! + sb.uc_gui_click_captcha() # Only if needed print(sb.get_page_title()) sb.assert_element('input[name*="email"]') sb.assert_element('input[name*="login"]') @@ -135,7 +137,7 @@ with SB(uc=True, test=True) as sb: sb.post_message("SeleniumBase wasn't detected!") ``` -uc_gui_click_cf on Linux +uc_gui_click_captcha on Linux The 2nd `print()` should output "Virtual Manager", which means that the automation successfully passed the Turnstile. @@ -191,12 +193,12 @@ driver.uc_gui_write(text) driver.uc_gui_click_x_y(x, y, timeframe=0.25) driver.uc_gui_click_captcha(frame="iframe", retry=False, blind=False) +# driver.uc_gui_click_cf(frame="iframe", retry=False, blind=False) +# driver.uc_gui_click_rc(frame="iframe", retry=False, blind=False) -driver.uc_gui_click_rc(frame="iframe", retry=False, blind=False) - -driver.uc_gui_click_cf(frame="iframe", retry=False, blind=False) - -driver.uc_gui_handle_cf(frame="iframe") +driver.uc_gui_handle_captcha(frame="iframe") +# driver.uc_gui_handle_cf(frame="iframe") +# driver.uc_gui_handle_rc(frame="iframe") driver.uc_switch_to_frame(frame, reconnect_time=None) ``` @@ -233,14 +235,14 @@ driver.reconnect("breakpoint") (Note that while the special UC Mode breakpoint is active, you can't use Selenium commands in the browser, and the browser can't detect Selenium.) -👤 On Linux, you may need to use `driver.uc_gui_click_cf()` to successfully bypass a Cloudflare CAPTCHA. If there's more than one Cloudflare iframe on that website, then put the CSS Selector of an element that's above the iframe as the first arg to `driver.uc_gui_click_cf()`. This method uses `pyautogui`. In order for `pyautogui` to focus on the correct element, use `xvfb=True` / `--xvfb` to activate a special virtual display on Linux. +👤 On Linux, you may need to use `driver.uc_gui_click_captcha()` to successfully bypass a Cloudflare CAPTCHA. If there's more than one Cloudflare iframe on that website, then put the CSS Selector of an element that's above the iframe as the first arg to `driver.uc_gui_click_captcha()`. This method uses `pyautogui`. In order for `pyautogui` to focus on the correct element, use `xvfb=True` / `--xvfb` to activate a special virtual display on Linux. + +👤 `driver.uc_gui_click_captcha()` auto-detects the CAPTCHA type before trying to click it. This is a generic method for both CF Turnstile and Google reCAPTCHA. It will use the code from `uc_gui_click_cf()` and `uc_gui_click_rc()` as needed. 👤 `driver.uc_gui_click_cf(frame="iframe", retry=False, blind=False)` has three args. (All optional). The first one, `frame`, lets you specify the iframe in case the CAPTCHA is not located in the first iframe on the page. The second one, `retry`, lets you retry the click after reloading the page if the first one didn't work (and a CAPTCHA is still present after the page reload). The third arg, `blind`, will retry after a page reload (if the first click failed) by clicking at the last known coordinates of the CAPTCHA checkbox without confirming first with Selenium that a CAPTCHA is still on the page. 👤 `driver.uc_gui_click_rc(frame="iframe", retry=False, blind=False)` is for reCAPTCHA. This may only work a few times before not working anymore... not because Selenium was detected, but because reCAPTCHA uses advanced AI to detect unusual activity, unlike the CF Turnstile, which only uses basic detection. -👤 `driver.uc_gui_click_captcha()` auto-detects the CAPTCHA type before trying to click it. This is a generic method for both CF Turnstile and Google reCAPTCHA. It will use the code from `uc_gui_click_cf()` and `uc_gui_click_rc()` as needed. - 👤 To find out if UC Mode will work at all on a specific site (before adjusting for timing), load your site with the following script: ```python @@ -334,11 +336,11 @@ The above JS method is used within the SeleniumBaseTroubleshooting UC Mode -On Windows, the `uc_gui_click_cf()` and `uc_gui_click_captcha()` methods require "Scaling" to be set at "100%". (Note that "100%" may be different from the system's "Recommended" percent, which can be higher depending on your screen resolution and monitor size.) +On Windows, the `uc_gui_click_captcha()` method requires "Scaling" to be set at "100%". (Note that "100%" may be different from the system's "Recommended" percent, which can be higher depending on your screen resolution and monitor size.) -As an alternative to using the `uc_gui_click_cf()` or `uc_gui_click_captcha()` methods on Windows, you can use `sb.uc_gui_handle_cf()`, which does not require "Scaling" to be set to a specific value. Instead of using the mouse to click a CAPTCHA, `sb.uc_gui_handle_cf()` uses a combination of the `TAB` key and the `SPACEBAR`. +As an alternative to using the `uc_gui_click_captcha()` method on Windows, you can use `sb.uc_gui_handle_captcha()`, which does not require "Scaling" to be set to a specific value. Instead of using the mouse to click a CAPTCHA, `sb.uc_gui_handle_captcha()` uses a combination of the `TAB` key and the `SPACEBAR`. -------- From e9cfebcd46dda6ebef805c7a4a38d4b1fc3ccc7e Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 2 Aug 2024 22:35:05 -0400 Subject: [PATCH 5/6] Refresh mkdocs dependencies --- mkdocs_build/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs_build/requirements.txt b/mkdocs_build/requirements.txt index ede10140976..0dda4afae78 100644 --- a/mkdocs_build/requirements.txt +++ b/mkdocs_build/requirements.txt @@ -20,7 +20,7 @@ lxml==5.2.2 pyquery==2.0.0 readtime==3.0.0 mkdocs==1.6.0 -mkdocs-material==9.5.30 +mkdocs-material==9.5.31 mkdocs-exclude-search==0.6.6 mkdocs-simple-hooks==0.1.5 mkdocs-material-extensions==1.3.1 From a4355f0b373f46f6a5976cfab1f37349440ba9dd Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 2 Aug 2024 22:35:49 -0400 Subject: [PATCH 6/6] Version 4.29.5 --- seleniumbase/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index 2a471a4f252..08b97dcac47 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.29.4" +__version__ = "4.29.5"