Skip to content

Creating WebDriver sessions during wdspec teardown #51845

Closed
@gsnedders

Description

@gsnedders

There appear to be certain cases where we create a new WebDriver session just to run our teardown code. This seems… bad.

This is, as far as I can tell, caused by a combination of our behaviour implicitly creating sessions when trying to run commands and our teardown code running commands.

Sometimes it even appears like we're restarting the browser, via creating a new session, while we're trying to terminate the runner — I think as a result of this.

This behaviour has always seemed slightly scary, because it carries the risk of something ignoring an exception during a test, and then when another WebDriver command is run then creating an entirely new session in the middle of a test — and I hope we all agree that that is clearly incorrect behaviour.

I don't know why we have the implicit session creation — it does appear to go all the way back to the original implementation in w3c/wptrunner#109 (cc @jgraham).

Changing command to instead assert session_id is not None leads to the following:

ERROR test_pointer_down_closes_browsing_context - teardown error: 
+ Exception Group Traceback (most recent call last):
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/runner.py", line 341, in from_call
  |     result: Optional[TResult] = func()
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/runner.py", line 241, in <lambda>
  |     lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pluggy/src/pluggy/_hooks.py", line 513, in __call__
  |     return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pluggy/src/pluggy/_manager.py", line 120, in _hookexec
  |     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pluggy/src/pluggy/_callers.py", line 139, in _multicall
  |     raise exception.with_traceback(exception.__traceback__)
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pluggy/src/pluggy/_callers.py", line 122, in _multicall
  |     teardown.throw(exception)  # type: ignore[union-attr]
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/threadexception.py", line 92, in pytest_runtest_teardown
  |     yield from thread_exception_runtest_hook()
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/threadexception.py", line 63, in thread_exception_runtest_hook
  |     yield
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pluggy/src/pluggy/_callers.py", line 122, in _multicall
  |     teardown.throw(exception)  # type: ignore[union-attr]
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/unraisableexception.py", line 95, in pytest_runtest_teardown
  |     yield from unraisable_exception_runtest_hook()
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/unraisableexception.py", line 65, in unraisable_exception_runtest_hook
  |     yield
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pluggy/src/pluggy/_callers.py", line 122, in _multicall
  |     teardown.throw(exception)  # type: ignore[union-attr]
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/logging.py", line 857, in pytest_runtest_teardown
  |     yield from self._runtest_for(item, "teardown")
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/logging.py", line 833, in _runtest_for
  |     yield
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pluggy/src/pluggy/_callers.py", line 122, in _multicall
  |     teardown.throw(exception)  # type: ignore[union-attr]
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/capture.py", line 883, in pytest_runtest_teardown
  |     return (yield)
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pluggy/src/pluggy/_callers.py", line 103, in _multicall
  |     res = hook_impl.function(*args)
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/runner.py", line 188, in pytest_runtest_teardown
  |     item.session._setupstate.teardown_exact(nextitem)
  |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/runner.py", line 557, in teardown_exact
  |     raise exceptions[0]
  | exceptiongroup.ExceptionGroup: errors while tearing down <Function test_pointer_down_closes_browsing_context> (3 sub-exceptions)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/runner.py", line 546, in teardown_exact
    |     fin()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/fixtures.py", line 1020, in finish
    |     raise exceptions[0]
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/fixtures.py", line 1009, in finish
    |     fin()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest-asyncio/pytest_asyncio/plugin.py", line 291, in finalizer
    |     event_loop.run_until_complete(async_finalizer())
    |   File "/AppleInternal/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    |     return future.result()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest-asyncio/pytest_asyncio/plugin.py", line 283, in async_finalizer
    |     await gen_obj.__anext__()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/webdriver/tests/support/fixtures.py", line 197, in session
    |     cleanup_session(_current_session)
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/webdriver/tests/support/helpers.py", line 84, in cleanup_session
    |     _ensure_valid_window(session)
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/webdriver/tests/support/helpers.py", line 17, in inner
    |     return f(*args, **kwargs)
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/webdriver/tests/support/helpers.py", line 44, in _ensure_valid_window
    |     session.window_handle
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/webdriver/webdriver/client.py", line 19, in inner
    |     assert session.session_id is not None
    | AssertionError
    +---------------- 2 ----------------
    | Traceback (most recent call last):
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/runner.py", line 546, in teardown_exact
    |     fin()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/fixtures.py", line 1020, in finish
    |     raise exceptions[0]
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/fixtures.py", line 1009, in finish
    |     fin()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/fixtures.py", line 893, in _teardown_yield_fixture
    |     next(it)
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/webdriver/tests/classic/perform_actions/conftest.py", line 78, in release_actions
    |     session.actions.release()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/webdriver/webdriver/client.py", line 19, in inner
    |     assert session.session_id is not None
    | AssertionError
    +---------------- 3 ----------------
    | Traceback (most recent call last):
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/runner.py", line 546, in teardown_exact
    |     fin()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/fixtures.py", line 1020, in finish
    |     raise exceptions[0]
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/fixtures.py", line 1009, in finish
    |     fin()
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/third_party/pytest/src/_pytest/fixtures.py", line 893, in _teardown_yield_fixture
    |     next(it)
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/webdriver/tests/support/fixtures_http.py", line 170, in http_new_tab
    |     session.window_handle = new_handle
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/webdriver/webdriver/client.py", line 21, in inner
    |     return func(self, *args, **kwargs)
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/webdriver/webdriver/client.py", line 655, in window_handle
    |     return self.send_session_command("POST", "window", body=body)
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/webdriver/webdriver/client.py", line 602, in send_session_command
    |     return self.send_command(method, url, body, timeout)
    |   File "/Volumes/gsnedders/projects/wpt/web-platform-tests/tools/webdriver/webdriver/client.py", line 566, in send_command
    |     raise err
    | webdriver.error.InvalidSessionIdException: invalid session id (404)
    +------------------------------------

And that shows we do indeed just end up implicitly creating a new session while trying to teardown our fixtures.

Can we just… get rid of this behaviour?

See also: #51816

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions