diff --git a/examples/test_multiple_drivers.py b/examples/test_multiple_drivers.py
new file mode 100644
index 00000000000..e2307c3a62c
--- /dev/null
+++ b/examples/test_multiple_drivers.py
@@ -0,0 +1,14 @@
+from seleniumbase import BaseCase
+
+
+class MultipleDriversTest(BaseCase):
+ def test_multiple_drivers(self):
+ self.open("data:text/html,
Driver 1
")
+ driver2 = self.get_new_driver()
+ self.open("data:text/html,Driver 2
")
+ self.switch_to_default_driver() # Driver 1
+ self.highlight("h1")
+ self.assert_text("Driver 1", "h1")
+ self.switch_to_driver(driver2) # Driver 2
+ self.highlight("h1")
+ self.assert_text("Driver 2", "h1")
diff --git a/help_docs/method_summary.md b/help_docs/method_summary.md
index 79c1c649001..541d8aeb0dc 100755
--- a/help_docs/method_summary.md
+++ b/help_docs/method_summary.md
@@ -265,6 +265,8 @@ self.save_recorded_actions()
self.activate_jquery()
+self.bring_active_window_to_front()
+
self.bring_to_front(selector, by=By.CSS_SELECTOR)
self.highlight_click(selector, by=By.CSS_SELECTOR, loops=3, scroll=True)
diff --git a/requirements.txt b/requirements.txt
index 3aa77826300..b41a290b9a8 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,7 +5,7 @@ packaging>=21.3;python_version>="3.6"
setuptools>=44.1.1;python_version<"3.5"
setuptools>=50.3.2;python_version>="3.5" and python_version<"3.6"
setuptools>=59.6.0;python_version>="3.6" and python_version<"3.7"
-setuptools>=60.2.0;python_version>="3.7"
+setuptools>=60.3.1;python_version>="3.7"
setuptools-scm>=5.0.2;python_version<"3.6"
setuptools-scm>=6.3.2;python_version>="3.6"
tomli>=1.2.2;python_version>="3.6" and python_version<"3.7"
@@ -28,7 +28,7 @@ idna==3.3;python_version>="3.6"
chardet==3.0.4;python_version<"3.5"
chardet==4.0.0;python_version>="3.5"
charset-normalizer==2.0.10;python_version>="3.5"
-urllib3==1.26.7
+urllib3==1.26.8
requests==2.27.0;python_version<"3.5"
requests==2.25.1;python_version>="3.5" and python_version<"3.6"
requests==2.27.1;python_version>="3.6"
@@ -83,12 +83,12 @@ cryptography==3.2.1;python_version>="3.5" and python_version<"3.6"
cryptography==3.4.8;python_version>="3.6" and python_version<"3.7"
cryptography==36.0.1;python_version>="3.7"
pygments==2.5.2;python_version<"3.5"
-pygments==2.11.1;python_version>="3.5"
+pygments==2.11.2;python_version>="3.5"
prompt-toolkit==1.0.18;python_version<"3.5"
prompt-toolkit==2.0.10;python_version>="3.5" and python_version<"3.6.2"
prompt-toolkit==3.0.24;python_version>="3.6.2"
decorator==4.4.2;python_version<"3.5"
-decorator==5.1.0;python_version>="3.5"
+decorator==5.1.1;python_version>="3.5"
ipython==5.10.0;python_version<"3.5"
ipython==7.9.0;python_version>="3.5" and python_version<"3.6"
ipython==7.16.1;python_version>="3.6" and python_version<"3.7"
diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py
index 80723b06ea1..d755509eb87 100755
--- a/seleniumbase/__version__.py
+++ b/seleniumbase/__version__.py
@@ -1,2 +1,2 @@
# seleniumbase package
-__version__ = "2.3.9"
+__version__ = "2.3.10"
diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py
index f76b29ccd2d..156f13631a8 100755
--- a/seleniumbase/fixtures/base_case.py
+++ b/seleniumbase/fixtures/base_case.py
@@ -2986,6 +2986,7 @@ def switch_to_driver(self, driver):
self.driver = driver
if self.driver in self.__driver_browser_map:
self.browser = self.__driver_browser_map[self.driver]
+ self.bring_active_window_to_front()
def switch_to_default_driver(self):
""" Sets self.driver to the default/original driver. """
@@ -2993,6 +2994,7 @@ def switch_to_default_driver(self):
self.driver = self._default_driver
if self.driver in self.__driver_browser_map:
self.browser = self.__driver_browser_map[self.driver]
+ self.bring_active_window_to_front()
def save_screenshot(
self, name, folder=None, selector=None, by=By.CSS_SELECTOR
@@ -3183,7 +3185,10 @@ def wait_for_angularjs(self, timeout=None, **kwargs):
def sleep(self, seconds):
self.__check_scope()
- if not sb_config.time_limit:
+ if (
+ not hasattr(sb_config, "time_limit")
+ or (hasattr(sb_config, "time_limit") and not sb_config.time_limit)
+ ):
time.sleep(seconds)
elif seconds < 0.4:
shared_utils.check_if_time_limit_exceeded()
@@ -3890,6 +3895,15 @@ def __are_quotes_escaped(self, string):
def __escape_quotes_if_needed(self, string):
return js_utils.escape_quotes_if_needed(string)
+ def bring_active_window_to_front(self):
+ """Brings the active browser window to the front.
+ This is useful when multiple drivers are being used."""
+ self.__check_scope()
+ try:
+ self.switch_to_window(self.driver.current_window_handle)
+ except Exception:
+ pass
+
def bring_to_front(self, selector, by=By.CSS_SELECTOR):
"""Updates the Z-index of a page element to bring it into view.
Useful when getting a WebDriverException, such as the one below:
@@ -10466,7 +10480,7 @@ def __click_dropdown_partial_link_text(self, link_text, link_css):
def __recalculate_selector(self, selector, by, xp_ok=True):
"""Use autodetection to return the correct selector with "by" updated.
If "xp_ok" is False, don't call convert_css_to_xpath(), which is
- used to make the ":contains()" selector valid outside JS calls."""
+ used to make the ":contains()" selector valid outside of JS calls."""
_type = type(selector) # First make sure the selector is a string
not_string = False
if not python3:
diff --git a/seleniumbase/fixtures/js_utils.py b/seleniumbase/fixtures/js_utils.py
index f1878cadc3f..d02cb5bba3f 100755
--- a/seleniumbase/fixtures/js_utils.py
+++ b/seleniumbase/fixtures/js_utils.py
@@ -599,7 +599,7 @@ def set_messenger_theme(
theme = "flat"
if location == "default":
location = "bottom_right"
- if sb_config.mobile_emulator:
+ if hasattr(sb_config, "mobile_emulator") and sb_config.mobile_emulator:
location = "top_center"
if max_messages == "default":
max_messages = "8"
@@ -682,7 +682,7 @@ def post_messenger_success_message(driver, message, msg_dur):
try:
theme = "flat"
location = "bottom_right"
- if sb_config.mobile_emulator:
+ if hasattr(sb_config, "mobile_emulator") and sb_config.mobile_emulator:
location = "top_center"
set_messenger_theme(driver, theme=theme, location=location)
post_message(driver, message, msg_dur, style="success")
diff --git a/setup.py b/setup.py
index a8477223c00..01d6e515575 100755
--- a/setup.py
+++ b/setup.py
@@ -83,6 +83,7 @@
author_email="mdmintz@gmail.com",
maintainer="Michael Mintz",
license="MIT",
+ keywords="pytest automation selenium browser testing webdriver sbase",
classifiers=[
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
@@ -125,7 +126,7 @@
'setuptools>=44.1.1;python_version<"3.5"',
'setuptools>=50.3.2;python_version>="3.5" and python_version<"3.6"',
'setuptools>=59.6.0;python_version>="3.6" and python_version<"3.7"',
- 'setuptools>=60.2.0;python_version>="3.7"',
+ 'setuptools>=60.3.1;python_version>="3.7"',
'setuptools-scm>=5.0.2;python_version<"3.6"',
'setuptools-scm>=6.3.2;python_version>="3.6"',
'tomli>=1.2.2;python_version>="3.6" and python_version<"3.7"',
@@ -148,7 +149,7 @@
'chardet==3.0.4;python_version<"3.5"', # Stay in sync with "requests"
'chardet==4.0.0;python_version>="3.5"', # Stay in sync with "requests"
'charset-normalizer==2.0.10;python_version>="3.5"', # Sync "requests"
- "urllib3==1.26.7", # Must stay in sync with "requests"
+ "urllib3==1.26.8", # Must stay in sync with "requests"
'requests==2.27.0;python_version<"3.5"',
'requests==2.25.1;python_version>="3.5" and python_version<"3.6"',
'requests==2.27.1;python_version>="3.6"',
@@ -203,12 +204,12 @@
'cryptography==3.4.8;python_version>="3.6" and python_version<"3.7"',
'cryptography==36.0.1;python_version>="3.7"',
'pygments==2.5.2;python_version<"3.5"',
- 'pygments==2.11.1;python_version>="3.5"',
+ 'pygments==2.11.2;python_version>="3.5"',
'prompt-toolkit==1.0.18;python_version<"3.5"',
'prompt-toolkit==2.0.10;python_version>="3.5" and python_version<"3.6.2"', # noqa: E501
'prompt-toolkit==3.0.24;python_version>="3.6.2"',
'decorator==4.4.2;python_version<"3.5"',
- 'decorator==5.1.0;python_version>="3.5"',
+ 'decorator==5.1.1;python_version>="3.5"',
'ipython==5.10.0;python_version<"3.5"',
'ipython==7.9.0;python_version>="3.5" and python_version<"3.6"',
'ipython==7.16.1;python_version>="3.6" and python_version<"3.7"',