I'm trying to make a fixture for cross-browser tests with PyTest. From @pytest.mark.parametrize fixture gets "browser_name" and sets up correct webdriver in internal method. In the end of tests I tried to add a teardowm method to close browser, but I noticed that it just doesn't work. Can anyone help?
In my conftest.py file I have:
import pytest
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.edge.service import Service as EdgeService
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.firefox import GeckoDriverManager
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from selenium import webdriver
@pytest.fixture()
def WebDriverFixture(request):
def driverSetup(browser_name):
print("\nStarting browser...\n")
match browser_name:
case "chrome":
options = webdriver.ChromeOptions()
options.add_argument('excludeSwitches')
options.add_argument('--ignore-ssl-errors=yes')
options.add_argument('--ignore-certificate-errors')
options.add_experimental_option("excludeSwitches", ["enable-logging"])
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options)
driver.implicitly_wait(10)
return driver
case "firefox":
options = webdriver.FirefoxOptions()
options.add_argument('excludeSwitches')
options.add_argument('--ignore-ssl-errors=yes')
options.add_argument('--ignore-certificate-errors')
options.set_preference("excludeSwitches", "enable-logging")
options.set_preference("dom.disable_beforeunload", True)
driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install()), options=options)
driver.implicitly_wait(10)
return driver
case "edge":
options = webdriver.EdgeOptions()
options.add_argument('excludeSwitches')
options.add_argument('--ignore-ssl-errors=yes')
options.add_argument('--ignore-certificate-errors')
options.accept_insecure_certs = True
driver = webdriver.Edge(service=EdgeService(EdgeChromiumDriverManager().install()), options=options)
driver.implicitly_wait(10)
return driver
def teardown(driverSetup):
driver = driverSetup(browser_name)
print("\nQuitting browser...")
driver.quit()
request.add_finalizer(teardown(driverSetup))
return driverSetup
In test file I have:
import pytest
from pages.login_page import LoginPage
from pages.base_page import BasePage
import time
@pytest.mark.parametrize('browser_name', ['chrome'])
def test_negative_cases(WebDriverFixture, browser_name):
driver = WebDriverFixture(browser_name)
#tests
...
Using
yield
is a better option than usingreturn
for your scenario, because you want to go back and perform another action at the end (closing the browser).I've modified the code (see below) to show a minimally working example that handles the pytest parameterization and closes browsers at the end.
The latest version of
selenium
already includeswebdriver_manager
now, so you no longer need to add that separately.