Skip to content

Commit 5fdfc77

Browse files
committed
[py] Remove redundant driver_instance from conftest.py
Currently, the driver lifetime is handled by two global variables: - `driver_instance`, the actual Selenium API driver. - `selenium_driver`, the wrapper `conftest.Driver`, which "owns" the former. Also, conftest.py could quit the driver from multiple places: - `Driver.stop_driver` finalizer, used for bidi and xfail tests - `stop_driver` Session-scope fixture finalizer - `pytest_exception_interact` to handle exceptions The last two paths called `driver_instance.quit()` directly but did not tell `selenium_driver` that the driver had exited. This could potentially raise `urllib.exception.MaxRetryError`, as `Driver.stop_driver` would try to send the `quit()` command to an already destroyed driver service. For example, this happened rather frequently on WebKit import of selenium 4.34.2 tests, whenever an exception happened, as we have enabled the `bidi` flag when calling pytest. To address this issue, this commit removes the global variable `driver_instance`, keeping only `selenium_driver` as global, and routes all teardown paths through `Driver.stop_driver()`.
1 parent ed794f7 commit 5fdfc77

File tree

1 file changed

+18
-26
lines changed

1 file changed

+18
-26
lines changed

py/conftest.py

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ def pytest_generate_tests(metafunc):
101101
metafunc.parametrize("driver", metafunc.config.option.drivers, indirect=True)
102102

103103

104-
driver_instance = None
105104
selenium_driver = None
106105

107106

@@ -276,7 +275,8 @@ def service(self):
276275

277276
@property
278277
def driver(self):
279-
self._driver = self._initialize_driver()
278+
if self._driver is None:
279+
self._driver = self._initialize_driver()
280280
return self._driver
281281

282282
@property
@@ -297,21 +297,15 @@ def _initialize_driver(self):
297297
kwargs["service"] = self.service
298298
return getattr(webdriver, self.driver_class)(**kwargs)
299299

300-
@property
301300
def stop_driver(self):
302-
def fin():
303-
global driver_instance
304-
if self._driver is not None:
305-
self._driver.quit()
306-
self._driver = None
307-
driver_instance = None
308-
309-
return fin
301+
driver_to_stop = self._driver
302+
self._driver = None
303+
if driver_to_stop is not None:
304+
driver_to_stop.quit()
310305

311306

312307
@pytest.fixture(scope="function")
313308
def driver(request):
314-
global driver_instance
315309
global selenium_driver
316310
driver_class = getattr(request, "param", "Chrome").lower()
317311

@@ -345,38 +339,36 @@ def driver(request):
345339

346340
request.addfinalizer(selenium_driver.stop_driver)
347341

348-
if driver_instance is None:
349-
driver_instance = selenium_driver.driver
350-
351-
yield driver_instance
352342
# Close the browser after BiDi tests. Those make event subscriptions
353343
# and doesn't seems to be stable enough, causing the flakiness of the
354344
# subsequent tests.
355345
# Remove this when BiDi implementation and API is stable.
356-
if selenium_driver.bidi:
346+
if selenium_driver is not None and selenium_driver.bidi:
357347
request.addfinalizer(selenium_driver.stop_driver)
358348

349+
yield selenium_driver.driver
350+
359351
if request.node.get_closest_marker("no_driver_after_test"):
360-
driver_instance = None
352+
selenium_driver = None
361353

362354

363355
@pytest.fixture(scope="session", autouse=True)
364356
def stop_driver(request):
365357
def fin():
366-
global driver_instance
367-
if driver_instance is not None:
368-
driver_instance.quit()
369-
driver_instance = None
358+
global selenium_driver
359+
if selenium_driver is not None:
360+
selenium_driver.stop_driver()
361+
selenium_driver = None
370362

371363
request.addfinalizer(fin)
372364

373365

374366
def pytest_exception_interact(node, call, report):
375367
if report.failed:
376-
global driver_instance
377-
if driver_instance is not None:
378-
driver_instance.quit()
379-
driver_instance = None
368+
global selenium_driver
369+
if selenium_driver is not None:
370+
selenium_driver.stop_driver()
371+
selenium_driver = None
380372

381373

382374
@pytest.fixture

0 commit comments

Comments
 (0)