Skip to content

Commit 59d4ba9

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 83cb4d6 commit 59d4ba9

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

@@ -269,7 +268,8 @@ def service(self):
269268

270269
@property
271270
def driver(self):
272-
self._driver = self._initialize_driver()
271+
if self._driver is None:
272+
self._driver = self._initialize_driver()
273273
return self._driver
274274

275275
@property
@@ -290,21 +290,15 @@ def _initialize_driver(self):
290290
kwargs["service"] = self.service
291291
return getattr(webdriver, self.driver_class)(**kwargs)
292292

293-
@property
294293
def stop_driver(self):
295-
def fin():
296-
global driver_instance
297-
if self._driver is not None:
298-
self._driver.quit()
299-
self._driver = None
300-
driver_instance = None
301-
302-
return fin
294+
driver_to_stop = self._driver
295+
self._driver = None
296+
if driver_to_stop is not None:
297+
driver_to_stop.quit()
303298

304299

305300
@pytest.fixture(scope="function")
306301
def driver(request):
307-
global driver_instance
308302
global selenium_driver
309303
driver_class = getattr(request, "param", "Chrome").lower()
310304

@@ -338,38 +332,36 @@ def driver(request):
338332

339333
request.addfinalizer(selenium_driver.stop_driver)
340334

341-
if driver_instance is None:
342-
driver_instance = selenium_driver.driver
343-
344-
yield driver_instance
345335
# Close the browser after BiDi tests. Those make event subscriptions
346336
# and doesn't seems to be stable enough, causing the flakiness of the
347337
# subsequent tests.
348338
# Remove this when BiDi implementation and API is stable.
349-
if selenium_driver.bidi:
339+
if selenium_driver is not None and selenium_driver.bidi:
350340
request.addfinalizer(selenium_driver.stop_driver)
351341

342+
yield selenium_driver.driver
343+
352344
if request.node.get_closest_marker("no_driver_after_test"):
353-
driver_instance = None
345+
selenium_driver = None
354346

355347

356348
@pytest.fixture(scope="session", autouse=True)
357349
def stop_driver(request):
358350
def fin():
359-
global driver_instance
360-
if driver_instance is not None:
361-
driver_instance.quit()
362-
driver_instance = None
351+
global selenium_driver
352+
if selenium_driver is not None:
353+
selenium_driver.stop_driver()
354+
selenium_driver = None
363355

364356
request.addfinalizer(fin)
365357

366358

367359
def pytest_exception_interact(node, call, report):
368360
if report.failed:
369-
global driver_instance
370-
if driver_instance is not None:
371-
driver_instance.quit()
372-
driver_instance = None
361+
global selenium_driver
362+
if selenium_driver is not None:
363+
selenium_driver.stop_driver()
364+
selenium_driver = None
373365

374366

375367
@pytest.fixture

0 commit comments

Comments
 (0)