beeware/toga

Linux Wayland: Test suite fails with two identical monitors

Open

#3,298 opened on Mar 28, 2025

View on GitHub
 (0 comments) (0 reactions) (0 assignees)Python (3,615 stars) (624 forks)batch import
buggood first issuegtklinux

Description

Describe the bug

If you run the test suite on Linux with two identical monitors, the test_screens tests which are part of the test_app module fails with an assertion error.

The test is assuming that each screen has unique origins and names, however with two identical monitors the names are the same.

Additionally, with GTK3 on Wayland, the screen[0] origin is not at (0, 0) which fails another part of the test. I need to test this more if these tests also fail on X.

Steps to reproduce

  1. cd testbed
  2. briefcase dev --test
  3. See AssertionError

Expected behavior

Tests should pass with all monitor combinations.

Screenshots

No response

Environment

  • Operating System: openSUSE Aeon
  • Python version: 3.13.2
  • Software versions:
    • Briefcase: 0.3.22
    • Toga: latest main
    • ...

Logs

tests/app/test_app.py::test_screens FAILED                               [  1%]

=================================== FAILURES ===================================
_________________________________ test_screens _________________________________
Traceback (most recent call last):
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/runner.py", line 341, in from_call
    result: TResult | None = func()
                             ~~~~^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/runner.py", line 242, in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_hooks.py", line 513, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    raise exception.with_traceback(exception.__traceback__)
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/threadexception.py", line 92, in pytest_runtest_call
    yield from thread_exception_runtest_hook()
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/threadexception.py", line 68, in thread_exception_runtest_hook
    yield
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/unraisableexception.py", line 95, in pytest_runtest_call
    yield from unraisable_exception_runtest_hook()
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/unraisableexception.py", line 70, in unraisable_exception_runtest_hook
    yield
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/logging.py", line 846, in pytest_runtest_call
    yield from self._runtest_for(item, "call")
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/logging.py", line 829, in _runtest_for
    yield
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/capture.py", line 880, in pytest_runtest_call
    return (yield)
            ^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/skipping.py", line 257, in pytest_runtest_call
    return (yield)
            ^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 103, in _multicall
    res = hook_impl.function(*args)
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/runner.py", line 174, in pytest_runtest_call
    item.runtest()
    ~~~~~~~~~~~~^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pytest_asyncio/plugin.py", line 533, in runtest
    super().runtest()
    ~~~~~~~~~~~~~~~^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/python.py", line 1627, in runtest
    self.ihook.pytest_pyfunc_call(pyfuncitem=self)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_hooks.py", line 513, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 182, in _multicall
    return outcome.get_result()
           ~~~~~~~~~~~~~~~~~~^^
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_result.py", line 100, in get_result
    raise exc.with_traceback(exc.__traceback__)
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pluggy/_callers.py", line 103, in _multicall
    res = hook_impl.function(*args)
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/_pytest/python.py", line 159, in pytest_pyfunc_call
    result = testfunction(**testargs)
  File "/home/dan/Projects/toga/.venv/lib/python3.13/site-packages/pytest_asyncio/plugin.py", line 1052, in inner
    _loop.run_until_complete(task)
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/dan/Projects/toga/testbed/tests/conftest.py", line 167, in run_until_complete
    return asyncio.run_coroutine_threadsafe(coro, self.loop).result()
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/dan/.pyenv/versions/3.13.2/lib/python3.13/concurrent/futures/_base.py", line 456, in result
    return self.__get_result()
           ~~~~~~~~~~~~~~~~~^^
  File "/home/dan/.pyenv/versions/3.13.2/lib/python3.13/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/home/dan/Projects/toga/testbed/tests/app/test_app.py", line 236, in test_screens
    assert len(screen_names) == len(unique_names)
AssertionError: assert 3 == 2
 +  where 3 = len(['0x095f', 'U32J59x', 'U32J59x'])
 +  and   2 = len({'0x095f', 'U32J59x'})
---------------------------- Captured stdout setup -----------------------------
Resetting main_window
=========================== short test summary info ============================
FAILED tests/app/test_app.py::test_screens - AssertionError: assert 3 == 2
 +  where 3 = len(['0x095f', 'U32J59x', 'U32J59x'])
 +  and   2 = len({'0x095f', 'U32J59x'})
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!

Additional context

No response

Contributor guide