Skip to content

Commit a5992f2

Browse files
authored
Merge pull request #2630 from seleniumbase/uc-mode-upgrade
Upgrade UC Mode
2 parents b3ff2a7 + 0abea07 commit a5992f2

14 files changed

+91
-71
lines changed

examples/raw_cdp_logging.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
driver = Driver(uc=True, log_cdp=True)
55
try:
66
driver.uc_open_with_reconnect("https://seleniumbase.io/apps/turnstile")
7-
driver.uc_switch_to_frame("iframe")
7+
driver.switch_to_frame("iframe")
88
driver.uc_click("span.mark")
99
driver.sleep(3)
1010
pprint(driver.get_log("performance"))

examples/raw_form_turnstile.py

+4-20
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,7 @@
11
from seleniumbase import SB
22

3-
4-
def open_the_form_turnstile_page(sb):
5-
sb.driver.uc_open_with_reconnect(
6-
"https://seleniumbase.io/apps/form_turnstile", reconnect_time=2.7,
7-
)
8-
9-
10-
def click_turnstile_and_verify(sb):
11-
sb.scroll_to_bottom()
12-
sb.driver.uc_switch_to_frame("iframe")
13-
sb.driver.uc_click("span.mark")
14-
sb.highlight("img#captcha-success", timeout=3.33)
15-
16-
173
with SB(uc=True, test=True) as sb:
18-
open_the_form_turnstile_page(sb)
19-
try:
20-
click_turnstile_and_verify(sb)
21-
except Exception:
22-
open_the_form_turnstile_page(sb)
23-
click_turnstile_and_verify(sb)
4+
sb.driver.uc_open_with_reconnect("seleniumbase.io/apps/form_turnstile", 3)
245
sb.press_keys("#name", "SeleniumBase")
256
sb.press_keys("#email", "[email protected]")
267
sb.press_keys("#phone", "1-555-555-5555")
@@ -30,6 +11,9 @@ def click_turnstile_and_verify(sb):
3011
sb.click('span:contains("9:00 PM")')
3112
sb.highlight_click('input[value="AR"] + span')
3213
sb.click('input[value="cc"] + span')
14+
sb.switch_to_frame("iframe")
15+
sb.driver.uc_click("span.mark")
16+
sb.highlight("img#captcha-success", timeout=3)
3317
sb.highlight_click('button:contains("Request & Pay")')
3418
sb.highlight("img#submit-success")
3519
sb.highlight('button:contains("Success!")')

examples/raw_nopecha.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
from seleniumbase import SB
22

33
with SB(uc=True, test=True) as sb:
4-
sb.driver.uc_open_with_reconnect("https://nopecha.com/demo/turnstile", 4)
5-
sb.driver.uc_switch_to_frame("#example-container5 iframe")
6-
sb.driver.uc_click("span.mark", reconnect_time=1)
4+
sb.driver.uc_open_with_reconnect("nopecha.com/demo/turnstile", 4.2)
5+
sb.switch_to_frame("#example-container5 iframe")
6+
sb.driver.uc_click("span.mark")
77

88
if sb.is_element_visible("#example-container0 iframe"):
99
sb.switch_to_frame("#example-container0 iframe")
1010
if not sb.is_element_visible("circle.success-circle"):
11-
sb.driver.uc_click("span.mark", reconnect_time=1)
11+
sb.driver.uc_click("span.mark")
1212
sb.switch_to_frame("#example-container0 iframe")
1313
sb.assert_element("circle.success-circle")
1414
sb.switch_to_parent_frame()

examples/raw_turnstile.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
def open_the_turnstile_page(sb):
55
sb.driver.uc_open_with_reconnect(
6-
"https://seleniumbase.io/apps/turnstile", reconnect_time=2.7,
6+
"seleniumbase.io/apps/turnstile", reconnect_time=3,
77
)
88

99

1010
def click_turnstile_and_verify(sb):
11-
sb.driver.uc_switch_to_frame("iframe")
11+
sb.driver.switch_to_frame("iframe")
1212
sb.driver.uc_click("span.mark")
13-
sb.assert_element("img#captcha-success", timeout=3.33)
13+
sb.assert_element("img#captcha-success", timeout=3)
1414

1515

1616
with SB(uc=True, test=True) as sb:

examples/test_download_files.py

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def test_download_files_from_pypi(self):
4343
if (
4444
self.browser == "safari"
4545
or self.browser == "ie"
46+
or self.browser == "edge"
4647
or (self.is_chromium() and self.guest_mode)
4748
or (self.is_chromium() and (self.headless or self.headless2))
4849
):

examples/uc_cdp_events.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ def add_cdp_listener(self):
1313
)
1414

1515
def click_turnstile_and_verify(sb):
16-
sb.driver.uc_switch_to_frame("iframe")
16+
sb.switch_to_frame("iframe")
1717
sb.driver.uc_click("span.mark")
18-
sb.assert_element("img#captcha-success", timeout=3.33)
18+
sb.assert_element("img#captcha-success", timeout=3)
1919
sb.highlight("img#captcha-success", loops=8)
2020

2121
def test_display_cdp_events(self):
2222
if not (self.undetectable and self.uc_cdp_events):
2323
self.get_new_driver(undetectable=True, uc_cdp_events=True)
24-
self.driver.uc_open("https://seleniumbase.io/apps/turnstile")
24+
self.driver.uc_open_with_reconnect("seleniumbase.io/apps/turnstile")
2525
self.add_cdp_listener()
2626
self.click_turnstile_and_verify()
2727
self.sleep(1)

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ sniffio==1.3.1
2626
h11==0.14.0
2727
outcome==1.3.0.post0
2828
trio==0.22.2;python_version<"3.8"
29-
trio==0.24.0;python_version>="3.8"
29+
trio==0.25.0;python_version>="3.8"
3030
trio-websocket==0.11.1
3131
wsproto==1.2.0
3232
selenium==4.11.2;python_version<"3.8"

seleniumbase/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "4.24.11"
2+
__version__ = "4.24.12"

seleniumbase/core/browser_launcher.py

+21-12
Original file line numberDiff line numberDiff line change
@@ -463,11 +463,16 @@ def uc_click(
463463
except Exception:
464464
pass
465465
element = driver.wait_for_selector(selector, by=by, timeout=timeout)
466-
if not element.tag_name == "span": # Element must be "visible"
466+
tag_name = element.tag_name
467+
if not tag_name == "span": # Element must be "visible"
467468
element = driver.wait_for_element(selector, by=by, timeout=timeout)
468469
try:
469470
element.uc_click(
470-
driver, selector, by=by, reconnect_time=reconnect_time
471+
driver,
472+
selector,
473+
by=by,
474+
reconnect_time=reconnect_time,
475+
tag_name=tag_name,
471476
)
472477
except ElementClickInterceptedException:
473478
time.sleep(0.16)
@@ -812,11 +817,12 @@ def _set_chrome_options(
812817
chrome_options = webdriver.edge.options.Options()
813818
prefs = {}
814819
prefs["download.default_directory"] = downloads_path
815-
prefs["local_discovery.notifications_enabled"] = False
816-
prefs["credentials_enable_service"] = False
817-
prefs["download.prompt_for_download"] = False
818820
prefs["download.directory_upgrade"] = True
821+
prefs["download.prompt_for_download"] = False
822+
prefs["credentials_enable_service"] = False
823+
prefs["local_discovery.notifications_enabled"] = False
819824
prefs["safebrowsing.enabled"] = False
825+
prefs["safebrowsing.disable_download_protection"] = True
820826
prefs["omnibox-max-zero-suggest-matches"] = 0
821827
prefs["omnibox-use-existing-autocomplete-client"] = 0
822828
prefs["omnibox-trending-zero-prefix-suggestions-on-ntp"] = 0
@@ -827,9 +833,8 @@ def _set_chrome_options(
827833
prefs["omnibox-zero-suggest-prefetching-on-srp"] = 0
828834
prefs["omnibox-zero-suggest-prefetching-on-web"] = 0
829835
prefs["omnibox-zero-suggest-in-memory-caching"] = 0
830-
prefs["default_content_setting_values.notifications"] = 0
831836
prefs["content_settings.exceptions.automatic_downloads.*.setting"] = 1
832-
prefs["safebrowsing.disable_download_protection"] = True
837+
prefs["default_content_setting_values.notifications"] = 0
833838
prefs["default_content_settings.popups"] = 0
834839
prefs["managed_default_content_settings.popups"] = 0
835840
prefs["profile.password_manager_enabled"] = False
@@ -1142,6 +1147,7 @@ def _set_chrome_options(
11421147
included_disabled_features.append("PrivacySandboxSettings4")
11431148
included_disabled_features.append("DownloadBubble")
11441149
included_disabled_features.append("DownloadBubbleV2")
1150+
included_disabled_features.append("InsecureDownloadWarnings")
11451151
for item in extra_disabled_features:
11461152
if item not in included_disabled_features:
11471153
included_disabled_features.append(item)
@@ -1153,6 +1159,7 @@ def _set_chrome_options(
11531159
included_disabled_features.append("OptimizationTargetPrediction")
11541160
included_disabled_features.append("DownloadBubble")
11551161
included_disabled_features.append("DownloadBubbleV2")
1162+
included_disabled_features.append("InsecureDownloadWarnings")
11561163
for item in extra_disabled_features:
11571164
if item not in included_disabled_features:
11581165
included_disabled_features.append(item)
@@ -2367,10 +2374,11 @@ def get_local_driver(
23672374
elif browser_name == constants.Browser.EDGE:
23682375
prefs = {
23692376
"download.default_directory": downloads_path,
2370-
"local_discovery.notifications_enabled": False,
2371-
"credentials_enable_service": False,
2372-
"download.prompt_for_download": False,
23732377
"download.directory_upgrade": True,
2378+
"download.prompt_for_download": False,
2379+
"credentials_enable_service": False,
2380+
"local_discovery.notifications_enabled": False,
2381+
"safebrowsing.disable_download_protection": True,
23742382
"safebrowsing.enabled": False,
23752383
"omnibox-max-zero-suggest-matches": 0,
23762384
"omnibox-use-existing-autocomplete-client": 0,
@@ -2382,11 +2390,10 @@ def get_local_driver(
23822390
"omnibox-zero-suggest-prefetching-on-srp": 0,
23832391
"omnibox-zero-suggest-prefetching-on-web": 0,
23842392
"omnibox-zero-suggest-in-memory-caching": 0,
2385-
"safebrowsing.disable_download_protection": True,
2393+
"content_settings.exceptions.automatic_downloads.*.setting": 1,
23862394
"default_content_setting_values.notifications": 0,
23872395
"default_content_settings.popups": 0,
23882396
"managed_default_content_settings.popups": 0,
2389-
"content_settings.exceptions.automatic_downloads.*.setting": 1,
23902397
"profile.password_manager_enabled": False,
23912398
"profile.default_content_setting_values.notifications": 2,
23922399
"profile.default_content_settings.popups": 0,
@@ -2772,6 +2779,7 @@ def get_local_driver(
27722779
included_disabled_features.append("Translate")
27732780
included_disabled_features.append("OptimizationTargetPrediction")
27742781
included_disabled_features.append("PrivacySandboxSettings4")
2782+
included_disabled_features.append("InsecureDownloadWarnings")
27752783
for item in extra_disabled_features:
27762784
if item not in included_disabled_features:
27772785
included_disabled_features.append(item)
@@ -2781,6 +2789,7 @@ def get_local_driver(
27812789
included_disabled_features.append("OptimizationHintsFetching")
27822790
included_disabled_features.append("Translate")
27832791
included_disabled_features.append("OptimizationTargetPrediction")
2792+
included_disabled_features.append("InsecureDownloadWarnings")
27842793
for item in extra_disabled_features:
27852794
if item not in included_disabled_features:
27862795
included_disabled_features.append(item)

seleniumbase/fixtures/base_case.py

+1-21
Original file line numberDiff line numberDiff line change
@@ -7876,27 +7876,7 @@ def convert_to_css_selector(self, selector, by):
78767876
jQuery commands require a CSS_SELECTOR for finding elements.
78777877
This method should only be used for jQuery/JavaScript actions.
78787878
Pure JavaScript doesn't support using a:contains("LINK_TEXT")."""
7879-
if by == By.CSS_SELECTOR:
7880-
return selector
7881-
elif by == By.ID:
7882-
return "#%s" % selector
7883-
elif by == By.CLASS_NAME:
7884-
return ".%s" % selector
7885-
elif by == By.NAME:
7886-
return '[name="%s"]' % selector
7887-
elif by == By.TAG_NAME:
7888-
return selector
7889-
elif by == By.XPATH:
7890-
return self.convert_xpath_to_css(selector)
7891-
elif by == By.LINK_TEXT:
7892-
return 'a:contains("%s")' % selector
7893-
elif by == By.PARTIAL_LINK_TEXT:
7894-
return 'a:contains("%s")' % selector
7895-
else:
7896-
raise Exception(
7897-
"Exception: Could not convert {%s}(by=%s) to CSS_SELECTOR!"
7898-
% (selector, by)
7899-
)
7879+
return js_utils.convert_to_css_selector(selector, by)
79007880

79017881
def set_value(
79027882
self, selector, text, by="css selector", timeout=None, scroll=True

seleniumbase/fixtures/constants.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ class Mobile:
367367

368368

369369
class UC:
370-
RECONNECT_TIME = 2.35 # Seconds
370+
RECONNECT_TIME = 2.4 # Seconds
371371

372372

373373
class ValidBrowsers:

seleniumbase/fixtures/js_utils.py

+39
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import time
55
from selenium.common.exceptions import NoSuchElementException
66
from selenium.common.exceptions import WebDriverException
7+
from selenium.webdriver.common.by import By
78
from seleniumbase import config as sb_config
89
from seleniumbase.config import settings
910
from seleniumbase.fixtures import constants
1011
from seleniumbase.fixtures import css_to_xpath
12+
from seleniumbase.fixtures import xpath_to_css
1113

1214

1315
def wait_for_ready_state_complete(driver, timeout=settings.LARGE_TIMEOUT):
@@ -93,6 +95,37 @@ def wait_for_angularjs(driver, timeout=settings.LARGE_TIMEOUT, **kwargs):
9395
time.sleep(0.05)
9496

9597

98+
def convert_to_css_selector(selector, by=By.CSS_SELECTOR):
99+
if by == By.CSS_SELECTOR:
100+
return selector
101+
elif by == By.ID:
102+
return "#%s" % selector
103+
elif by == By.CLASS_NAME:
104+
return ".%s" % selector
105+
elif by == By.NAME:
106+
return '[name="%s"]' % selector
107+
elif by == By.TAG_NAME:
108+
return selector
109+
elif (
110+
by == By.XPATH
111+
or (
112+
selector.startswith("/")
113+
or selector.startswith("./")
114+
or selector.startswith("(")
115+
)
116+
):
117+
return xpath_to_css.convert_xpath_to_css(selector)
118+
elif by == By.LINK_TEXT:
119+
return 'a:contains("%s")' % selector
120+
elif by == By.PARTIAL_LINK_TEXT:
121+
return 'a:contains("%s")' % selector
122+
else:
123+
raise Exception(
124+
"Exception: Could not convert {%s}(by=%s) to CSS_SELECTOR!"
125+
% (selector, by)
126+
)
127+
128+
96129
def is_html_inspector_activated(driver):
97130
try:
98131
driver.execute_script("HTMLInspector;") # Fails if not defined
@@ -325,6 +358,12 @@ def swap_selector_and_by_if_reversed(selector, by):
325358
return (selector, by)
326359

327360

361+
def call_me_later(driver, script, ms):
362+
"""Call script after ms passed."""
363+
call = "function() {%s}" % script
364+
driver.execute_script("window.setTimeout(%s, %s);" % (call, ms))
365+
366+
328367
def highlight(driver, selector, by="css selector", loops=4):
329368
"""For driver.highlight() / driver.page.highlight()"""
330369
swap_selector_and_by_if_reversed(selector, by)

seleniumbase/undetected/webelement.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import selenium.webdriver.remote.webelement
2+
from seleniumbase.fixtures import js_utils
23

34

45
class WebElement(selenium.webdriver.remote.webelement.WebElement):
@@ -8,18 +9,24 @@ def uc_click(
89
selector=None,
910
by=None,
1011
reconnect_time=None,
12+
tag_name=None,
1113
):
1214
if driver and selector and by:
13-
driver.js_click(selector, by=by, timeout=1)
15+
if tag_name == "span" and ":contains" not in selector:
16+
selector = js_utils.convert_to_css_selector(selector, by)
17+
script = 'document.querySelector("%s").click();' % selector
18+
js_utils.call_me_later(driver, script, 111)
19+
else:
20+
driver.js_click(selector, by=by, timeout=1)
1421
else:
1522
super().click()
1623
if not reconnect_time:
17-
self._parent.reconnect(0.45)
24+
self._parent.reconnect(0.5)
1825
else:
1926
self._parent.reconnect(reconnect_time)
2027

2128
def uc_reconnect(self, reconnect_time=None):
2229
if not reconnect_time:
23-
self._parent.reconnect(0.1)
30+
self._parent.reconnect(0.2)
2431
else:
2532
self._parent.reconnect(reconnect_time)

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@
174174
'h11==0.14.0',
175175
'outcome==1.3.0.post0',
176176
'trio==0.22.2;python_version<"3.8"',
177-
'trio==0.24.0;python_version>="3.8"',
177+
'trio==0.25.0;python_version>="3.8"',
178178
'trio-websocket==0.11.1',
179179
'wsproto==1.2.0',
180180
'selenium==4.11.2;python_version<"3.8"',

0 commit comments

Comments
 (0)