Skip to content

Commit 44ca569

Browse files
committed
Add support methods into "driver" instances
1 parent 63d95c4 commit 44ca569

File tree

6 files changed

+672
-76
lines changed

6 files changed

+672
-76
lines changed

seleniumbase/core/browser_launcher.py

Lines changed: 106 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import subprocess
77
import sys
88
import time
9+
import types
910
import urllib3
1011
import warnings
1112
from selenium import webdriver
@@ -22,6 +23,7 @@
2223
from seleniumbase.core import detect_b_ver
2324
from seleniumbase.core import download_helper
2425
from seleniumbase.core import proxy_helper
26+
from seleniumbase.core import sb_driver
2527
from seleniumbase.fixtures import constants
2628
from seleniumbase.fixtures import shared_utils
2729

@@ -102,6 +104,66 @@ def make_driver_executable_if_not(driver_path):
102104
make_executable(driver_path)
103105

104106

107+
def extend_driver(driver):
108+
# Extend the driver with new methods
109+
DM = sb_driver.DriverMethods(driver)
110+
page = types.SimpleNamespace()
111+
page.open = DM.open_url
112+
page.click = DM.click
113+
page.send_keys = DM.send_keys
114+
page.type = DM.update_text
115+
page.assert_element = DM.assert_element_visible
116+
page.assert_element_present = DM.assert_element_present
117+
page.assert_element_not_visible = DM.assert_element_not_visible
118+
page.assert_text = DM.assert_text
119+
page.assert_exact_text = DM.assert_exact_text
120+
page.wait_for_element = DM.wait_for_element
121+
page.wait_for_text = DM.wait_for_text
122+
page.wait_for_exact_text = DM.wait_for_exact_text
123+
page.wait_for_and_accept_alert = DM.wait_for_and_accept_alert
124+
page.wait_for_and_dismiss_alert = DM.wait_for_and_dismiss_alert
125+
page.is_element_present = DM.is_element_present
126+
page.is_element_visible = DM.is_element_visible
127+
page.is_text_visible = DM.is_text_visible
128+
page.is_exact_text_visible = DM.is_exact_text_visible
129+
page.get_text = DM.get_text
130+
driver.page = page
131+
js = types.SimpleNamespace()
132+
js.js_click = DM.js_click
133+
js.get_active_element_css = DM.get_active_element_css
134+
js.get_locale_code = DM.get_locale_code
135+
js.get_origin = DM.get_origin
136+
js.get_user_agent = DM.get_user_agent
137+
js.highlight = DM.highlight
138+
driver.js = js
139+
driver.open = DM.open_url
140+
driver.click = DM.click
141+
driver.send_keys = DM.send_keys
142+
driver.type = DM.update_text
143+
driver.assert_element = DM.assert_element_visible
144+
driver.assert_element_present = DM.assert_element_present
145+
driver.assert_element_not_visible = DM.assert_element_not_visible
146+
driver.assert_text = DM.assert_text
147+
driver.assert_exact_text = DM.assert_exact_text
148+
driver.wait_for_element = DM.wait_for_element
149+
driver.wait_for_text = DM.wait_for_text
150+
driver.wait_for_exact_text = DM.wait_for_exact_text
151+
driver.wait_for_and_accept_alert = DM.wait_for_and_accept_alert
152+
driver.wait_for_and_dismiss_alert = DM.wait_for_and_dismiss_alert
153+
driver.is_element_present = DM.is_element_present
154+
driver.is_element_visible = DM.is_element_visible
155+
driver.is_text_visible = DM.is_text_visible
156+
driver.is_exact_text_visible = DM.is_exact_text_visible
157+
driver.get_text = DM.get_text
158+
driver.js_click = DM.js_click
159+
driver.get_active_element_css = DM.get_active_element_css
160+
driver.get_locale_code = DM.get_locale_code
161+
driver.get_origin = DM.get_origin
162+
driver.get_user_agent = DM.get_user_agent
163+
driver.highlight = DM.highlight
164+
return driver
165+
166+
105167
@decorators.rate_limited(4)
106168
def requests_get(url, proxy_string=None):
107169
import requests
@@ -1607,10 +1669,11 @@ def get_remote_driver(
16071669
for key in extension_capabilities:
16081670
ext_caps = extension_capabilities
16091671
chrome_options.set_capability(key, ext_caps[key])
1610-
return webdriver.Remote(
1672+
driver = webdriver.Remote(
16111673
command_executor=address,
16121674
options=chrome_options,
16131675
)
1676+
return extend_driver(driver)
16141677
elif browser_name == constants.Browser.FIREFOX:
16151678
firefox_options = _set_firefox_options(
16161679
downloads_path,
@@ -1666,18 +1729,20 @@ def get_remote_driver(
16661729
for key in extension_capabilities:
16671730
ext_caps = extension_capabilities
16681731
firefox_options.set_capability(key, ext_caps[key])
1669-
return webdriver.Remote(
1732+
driver = webdriver.Remote(
16701733
command_executor=address,
16711734
options=firefox_options,
16721735
)
1736+
return extend_driver(driver)
16731737
elif browser_name == constants.Browser.INTERNET_EXPLORER:
16741738
capabilities = webdriver.DesiredCapabilities.INTERNETEXPLORER
16751739
remote_options = ArgOptions()
16761740
remote_options.set_capability("cloud:options", desired_caps)
1677-
return webdriver.Remote(
1741+
driver = webdriver.Remote(
16781742
command_executor=address,
16791743
options=remote_options,
16801744
)
1745+
return extend_driver(driver)
16811746
elif browser_name == constants.Browser.EDGE:
16821747
edge_options = _set_chrome_options(
16831748
browser_name,
@@ -1767,26 +1832,29 @@ def get_remote_driver(
17671832
for key in extension_capabilities:
17681833
ext_caps = extension_capabilities
17691834
edge_options.set_capability(key, ext_caps[key])
1770-
return webdriver.Remote(
1835+
driver = webdriver.Remote(
17711836
command_executor=address,
17721837
options=edge_options,
17731838
)
1839+
return extend_driver(driver)
17741840
elif browser_name == constants.Browser.SAFARI:
17751841
capabilities = webdriver.DesiredCapabilities.SAFARI
17761842
remote_options = ArgOptions()
17771843
remote_options.set_capability("cloud:options", desired_caps)
1778-
return webdriver.Remote(
1844+
driver = webdriver.Remote(
17791845
command_executor=address,
17801846
options=remote_options,
17811847
)
1848+
return extend_driver(driver)
17821849
elif browser_name == constants.Browser.REMOTE:
17831850
remote_options = ArgOptions()
17841851
for cap_name, cap_value in desired_caps.items():
17851852
remote_options.set_capability(cap_name, cap_value)
1786-
return webdriver.Remote(
1853+
driver = webdriver.Remote(
17871854
command_executor=address,
17881855
options=remote_options,
17891856
)
1857+
return extend_driver(driver)
17901858

17911859

17921860
def get_local_driver(
@@ -1913,10 +1981,11 @@ def get_local_driver(
19131981
log_output=os.devnull,
19141982
)
19151983
try:
1916-
return webdriver.Firefox(
1984+
driver = webdriver.Firefox(
19171985
service=service,
19181986
options=firefox_options,
19191987
)
1988+
return extend_driver(driver)
19201989
except BaseException as e:
19211990
if (
19221991
"geckodriver unexpectedly exited" in str(e)
@@ -1942,19 +2011,21 @@ def get_local_driver(
19422011
)
19432012
):
19442013
firefox_options.add_argument("-headless")
1945-
return webdriver.Firefox(
2014+
driver = webdriver.Firefox(
19462015
service=service,
19472016
options=firefox_options,
19482017
)
2018+
return extend_driver(driver)
19492019
else:
19502020
raise # Not an obvious fix.
19512021
else:
19522022
service = FirefoxService(log_output=os.devnull)
19532023
try:
1954-
return webdriver.Firefox(
2024+
driver = webdriver.Firefox(
19552025
service=service,
19562026
options=firefox_options,
19572027
)
2028+
return extend_driver(driver)
19582029
except BaseException as e:
19592030
if (
19602031
"geckodriver unexpectedly exited" in str(e)
@@ -1980,10 +2051,11 @@ def get_local_driver(
19802051
)
19812052
):
19822053
firefox_options.add_argument("-headless")
1983-
return webdriver.Firefox(
2054+
driver = webdriver.Firefox(
19842055
service=service,
19852056
options=firefox_options,
19862057
)
2058+
return extend_driver(driver)
19872059
else:
19882060
raise # Not an obvious fix.
19892061
elif browser_name == constants.Browser.INTERNET_EXPLORER:
@@ -2036,13 +2108,15 @@ def get_local_driver(
20362108
sys.argv = sys_args # Put back the original sys args
20372109
if not headless:
20382110
warnings.simplefilter("ignore", category=DeprecationWarning)
2039-
return webdriver.Ie(capabilities=ie_capabilities)
2111+
driver = webdriver.Ie(capabilities=ie_capabilities)
2112+
return extend_driver(driver)
20402113
else:
20412114
warnings.simplefilter("ignore", category=DeprecationWarning)
2042-
return webdriver.Ie(
2115+
driver = webdriver.Ie(
20432116
executable_path=LOCAL_HEADLESS_IEDRIVER,
20442117
capabilities=ie_capabilities,
20452118
)
2119+
return extend_driver(driver)
20462120
elif browser_name == constants.Browser.EDGE:
20472121
prefs = {
20482122
"download.default_directory": downloads_path,
@@ -2433,7 +2507,8 @@ def get_local_driver(
24332507
edge_options.add_argument(
24342508
"--remote-debugging-port=%s" % free_port
24352509
)
2436-
return Edge(service=service, options=edge_options)
2510+
driver = Edge(service=service, options=edge_options)
2511+
return extend_driver(driver)
24372512
if not auto_upgrade_edgedriver:
24382513
raise # Not an obvious fix.
24392514
else:
@@ -2463,7 +2538,7 @@ def get_local_driver(
24632538
service_args=["--disable-build-check"],
24642539
)
24652540
driver = Edge(service=service, options=edge_options)
2466-
return driver
2541+
return extend_driver(driver)
24672542
elif browser_name == constants.Browser.SAFARI:
24682543
args = " ".join(sys.argv)
24692544
if ("-n" in sys.argv or " -n=" in args or args == "-c"):
@@ -2487,9 +2562,10 @@ def get_local_driver(
24872562
):
24882563
# Only change it if not "normal", which is the default.
24892564
options.page_load_strategy = settings.PAGE_LOAD_STRATEGY.lower()
2490-
return webdriver.safari.webdriver.WebDriver(
2565+
driver = webdriver.safari.webdriver.WebDriver(
24912566
service=service, options=options
24922567
)
2568+
return extend_driver(driver)
24932569
elif browser_name == constants.Browser.GOOGLE_CHROME:
24942570
try:
24952571
chrome_options = _set_chrome_options(
@@ -3017,9 +3093,10 @@ def get_local_driver(
30173093
warnings.simplefilter(
30183094
"ignore", category=DeprecationWarning
30193095
)
3020-
return webdriver.Chrome(
3096+
driver = webdriver.Chrome(
30213097
service=service, options=chrome_options
30223098
)
3099+
return extend_driver(driver)
30233100
if not auto_upgrade_chromedriver:
30243101
raise # Not an obvious fix.
30253102
else:
@@ -3136,11 +3213,11 @@ def get_local_driver(
31363213
driver.uc_open_with_reconnect = (
31373214
lambda url: uc_open_with_reconnect(driver, url)
31383215
)
3139-
driver.open = driver.get # Shortcut
3140-
return driver
3216+
return extend_driver(driver)
31413217
else: # Running headless on Linux (and not using --uc)
31423218
try:
3143-
return webdriver.Chrome(options=chrome_options)
3219+
driver = webdriver.Chrome(options=chrome_options)
3220+
return extend_driver(driver)
31443221
except Exception as e:
31453222
if not hasattr(e, "msg"):
31463223
raise
@@ -3159,9 +3236,10 @@ def get_local_driver(
31593236
warnings.simplefilter(
31603237
"ignore", category=DeprecationWarning
31613238
)
3162-
return webdriver.Chrome(
3239+
driver = webdriver.Chrome(
31633240
service=service, options=chrome_options
31643241
)
3242+
return extend_driver(driver)
31653243
mcv = None # Major Chrome Version
31663244
if "Current browser version is " in e.msg:
31673245
line = e.msg.split("Current browser version is ")[1]
@@ -3201,10 +3279,11 @@ def get_local_driver(
32013279
log_output=os.devnull,
32023280
service_args=["--disable-build-check"],
32033281
)
3204-
return webdriver.Chrome(
3282+
driver = webdriver.Chrome(
32053283
service=service,
32063284
options=chrome_options,
32073285
)
3286+
return extend_driver(driver)
32083287
except Exception:
32093288
pass
32103289
# Use the virtual display on Linux during headless errors
@@ -3219,16 +3298,18 @@ def get_local_driver(
32193298
log_output=os.devnull,
32203299
service_args=["--disable-build-check"]
32213300
)
3222-
return webdriver.Chrome(
3301+
driver = webdriver.Chrome(
32233302
service=service, options=chrome_options
32243303
)
3304+
return extend_driver(driver)
32253305
except Exception:
32263306
try:
32273307
# Try again if Chrome didn't launch
32283308
service = ChromeService(service_args=["--disable-build-check"])
3229-
return webdriver.Chrome(
3309+
driver = webdriver.Chrome(
32303310
service=service, options=chrome_options
32313311
)
3312+
return extend_driver(driver)
32323313
except Exception:
32333314
pass
32343315
if headless:
@@ -3245,7 +3326,8 @@ def get_local_driver(
32453326
log_output=os.devnull,
32463327
service_args=["--disable-build-check"]
32473328
)
3248-
return webdriver.Chrome(service=service)
3329+
driver = webdriver.Chrome(service=service)
3330+
return extend_driver(driver)
32493331
else:
32503332
raise Exception(
32513333
"%s is not a valid browser option for this system!" % browser_name

0 commit comments

Comments
 (0)