From bd90ceb7b841d639cbf0593d49c4d39e07bef2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ri=C3=9Fe?= Date: Wed, 29 May 2024 13:29:55 +0200 Subject: [PATCH] WIP --- .github/workflows/testing-all-oses.yml | 8 ++++- tests/fixtures.py | 48 ++++++++++++++++++++------ 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/.github/workflows/testing-all-oses.yml b/.github/workflows/testing-all-oses.yml index 86fb996fc..cc5891114 100644 --- a/.github/workflows/testing-all-oses.yml +++ b/.github/workflows/testing-all-oses.yml @@ -48,6 +48,12 @@ jobs: # I have no idea yet on why this happens and how to fix it. # Even a module level skip is not enough, they need to be completely ignored. # TODO: fix those tests and drop the ignores - run: micromamba run -n ci env QT_QPA_PLATFORM=offscreen pytest -v -n logical --durations=20 --cov=mslib + run: micromamba run -n ci ${{ (startsWith(matrix.os, 'ubuntu') && 'xvfb-run') || ' ' }} pytest -v -n logical --durations=20 --cov=mslib --ignore=tests/_test_msui/test_sideview.py --ignore=tests/_test_msui/test_topview.py --ignore=tests/_test_msui/test_wms_control.py tests + - name: Upload screenshots artifact + if: ${{ !cancelled() }} + uses: actions/upload-artifact@v4 + with: + name: test-execution-screenshots + path: screenshots/ diff --git a/tests/fixtures.py b/tests/fixtures.py index 4005225ec..87f97c28a 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -23,6 +23,9 @@ See the License for the specific language governing permissions and limitations under the License. """ +import datetime +import pathlib +import shutil import pytest import mock import multiprocessing @@ -32,7 +35,7 @@ import eventlet import eventlet.wsgi -from PyQt5 import QtWidgets +from PyQt5 import QtWidgets, QtCore from contextlib import contextmanager from mslib.mscolab.conf import mscolab_settings from mslib.mscolab.server import APP, initialize_managers @@ -41,6 +44,30 @@ from tests.utils import is_url_response_ok +@contextmanager +def take_periodic_screenshots(qapp, worker_id): + screenshots_path = pathlib.Path("screenshots") + if screenshots_path.is_dir(): + shutil.rmtree(screenshots_path) + screenshots_path.mkdir() + + def _take_screenshot(): + img = qapp.primaryScreen().grabWindow(0) + img.save( + str( + screenshots_path + / f"{worker_id}_{datetime.datetime.now(tz=datetime.timezone.utc).strftime('%Y-%m-%dT%H%M%S')}.png" + ), + "png", + ) + timer = QtCore.QTimer() + timer.timeout.connect(_take_screenshot) + timer.setInterval(1000) + timer.start() + yield + timer.stop() + + @pytest.fixture def fail_if_open_message_boxes_left(): # Mock every MessageBox widget in the test suite to avoid unwanted freezes on unhandled error popups etc. @@ -70,16 +97,17 @@ def close_remaining_widgets(): @pytest.fixture -def qtbot(qtbot, fail_if_open_message_boxes_left, close_remaining_widgets): +def qtbot(worker_id, qtbot, qapp, fail_if_open_message_boxes_left, close_remaining_widgets): """Fixture that re-defines the qtbot fixture from pytest-qt with additional checks.""" - yield qtbot - # Wait for a while after the requesting test has finished. At time of writing this - # is required to (mostly) stabilize the coverage reports, because tests don't - # properly close their Qt-related stuff and therefore there is no guarantee about - # what the Qt event loop has or hasn't done yet. Waiting just gives it a bit more - # time to converge on the same result every time the tests are executed. This is a - # band-aid fix, the proper fix is to make sure each test cleans up after itself. - qtbot.wait(5000) + with take_periodic_screenshots(qapp, worker_id): + yield qtbot + # Wait for a while after the requesting test has finished. At time of writing this + # is required to (mostly) stabilize the coverage reports, because tests don't + # properly close their Qt-related stuff and therefore there is no guarantee about + # what the Qt event loop has or hasn't done yet. Waiting just gives it a bit more + # time to converge on the same result every time the tests are executed. This is a + # band-aid fix, the proper fix is to make sure each test cleans up after itself. + qtbot.wait(5000) @pytest.fixture(scope="session")