Skip to content

Commit ba74fdd

Browse files
committed
[tests] Enhance SeleniumTestMixin to support Chrome and Firefox drivers
1 parent a7e5348 commit ba74fdd

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

openwisp_utils/test_selenium_mixins.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from selenium import webdriver
44
from selenium.common.exceptions import TimeoutException
55
from selenium.webdriver.common.by import By
6+
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
67
from selenium.webdriver.firefox.options import Options
78
from selenium.webdriver.support import expected_conditions as EC
89
from selenium.webdriver.support.ui import WebDriverWait
@@ -17,10 +18,18 @@ class SeleniumTestMixin:
1718

1819
admin_username = 'admin'
1920
admin_password = 'password'
21+
browser = 'firefox'
2022

2123
@classmethod
2224
def setUpClass(cls):
2325
super().setUpClass()
26+
if cls.browser == 'firefox':
27+
cls.web_driver = cls.get_firefox_webdriver()
28+
else:
29+
cls.web_driver = cls.get_chrome_webdriver()
30+
31+
@classmethod
32+
def get_firefox_webdriver(cls):
2433
options = Options()
2534
options.page_load_strategy = 'eager'
2635
if os.environ.get('SELENIUM_HEADLESS', False):
@@ -43,7 +52,7 @@ def setUpClass(cls):
4352
GECKO_LOG = os.environ.get('GECKO_LOG', None)
4453
if GECKO_LOG:
4554
kwargs['service'] = webdriver.FirefoxService(log_output='geckodriver.log')
46-
cls.web_driver = webdriver.Firefox(**kwargs)
55+
web_driver = webdriver.Firefox(**kwargs)
4756
# Firefox does not support the WebDriver.get_log API. To work around this,
4857
# we inject JavaScript into the page to override window.console within the
4958
# browser's JS runtime. This allows us to capture and retrieve console errors
@@ -55,7 +64,38 @@ def setUpClass(cls):
5564
"console_capture_extension",
5665
)
5766
)
58-
cls.web_driver.install_addon(extension_path, temporary=True)
67+
web_driver.install_addon(extension_path, temporary=True)
68+
return web_driver
69+
70+
@classmethod
71+
def get_chrome_webdriver(cls):
72+
chrome_options = webdriver.ChromeOptions()
73+
chrome_options.page_load_strategy = 'eager'
74+
if os.environ.get('SELENIUM_HEADLESS', False):
75+
chrome_options.add_argument('--headless')
76+
CHROME_BIN = os.environ.get('CHROME_BIN', None)
77+
if CHROME_BIN:
78+
chrome_options.binary_location = CHROME_BIN
79+
chrome_options.add_argument('--window-size=1366,768')
80+
chrome_options.add_argument('--ignore-certificate-errors')
81+
# When running Selenium tests with the "--parallel" flag,
82+
# each TestCase class requires its own browser instance.
83+
# If the same "remote-debugging-port" is used for all
84+
# TestCase classes, it leads to failed test cases.
85+
# Therefore, it is necessary to utilize different remote
86+
# debugging ports for each TestCase. To accomplish this,
87+
# we can leverage the randomized live test server port to
88+
# generate a unique port for each browser instance.
89+
chrome_options.add_argument(
90+
f'--remote-debugging-port={cls.server_thread.port + 100}'
91+
)
92+
capabilities = DesiredCapabilities.CHROME
93+
capabilities['goog:loggingPrefs'] = {'browser': 'ALL'}
94+
chrome_options.set_capability('cloud:options', capabilities)
95+
web_driver = webdriver.Chrome(
96+
options=chrome_options,
97+
)
98+
return web_driver
5999

60100
@classmethod
61101
def tearDownClass(cls):
@@ -86,7 +126,9 @@ def open(self, url, driver=None, timeout=5):
86126
)
87127

88128
def get_browser_logs(self):
89-
return self.web_driver.execute_script('return window._console_logs')
129+
if self.browser == 'firefox':
130+
return self.web_driver.execute_script('return window._console_logs')
131+
return self.web_driver.get_log('browser')
90132

91133
def login(self, username=None, password=None, driver=None):
92134
"""Log in to the admin dashboard.

0 commit comments

Comments
 (0)