diff --git a/pytest.ini b/pytest.ini index 40774b205..778ae722c 100644 --- a/pytest.ini +++ b/pytest.ini @@ -79,7 +79,7 @@ qt_log_ignore = QItemSelectionModel: Selecting when no model has been set will result in a no-op. ^QSaveFile::commit: File \(.*[/\\]test_failing_flush0[/\\]foo\) is not open$ ^The following paths were searched for Qt WebEngine dictionaries:.* - # Qt 6.9 Beta 1 and 2 and 3 with Xvfb + # Qt 6.9 Beta 1-3 with Xvfb ^Backend texture is not a Vulkan texture\.$ # With offscreen platform plugin ^This plugin does not support (raise|propagateSizeHints)\(\)$ diff --git a/tests/conftest.py b/tests/conftest.py index 35c9baaf3..3972476a7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -213,11 +213,13 @@ def pytest_ignore_collect(collection_path: pathlib.Path) -> bool: @pytest.fixture(scope='session') -def qapp_args(): - """Make QtWebEngine unit tests run on older Qt versions + newer kernels.""" +def qapp_args() -> list[str]: + """Work around various issues when running QtWebEngine tests.""" args = [sys.argv[0], "--webEngineArgs"] if testutils.disable_seccomp_bpf_sandbox(): args.append(testutils.DISABLE_SECCOMP_BPF_FLAG) + if testutils.use_software_rendering(): + args.append(testutils.SOFTWARE_RENDERING_FLAG) # Disabling PaintHoldingCrossOrigin makes tests needing UI interaction with # QtWebEngine more reliable. diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py index bfb8ec519..6db4771e3 100644 --- a/tests/end2end/fixtures/quteprocess.py +++ b/tests/end2end/fixtures/quteprocess.py @@ -448,8 +448,11 @@ class QuteProc(testprocess.Process): '--qt-flag', 'disable-features=PaintHoldingCrossOrigin', '--qt-arg', 'geometry', '800x600+0+0'] - if self.request.config.webengine and testutils.disable_seccomp_bpf_sandbox(): - args += testutils.DISABLE_SECCOMP_BPF_ARGS + if self.request.config.webengine: + if testutils.disable_seccomp_bpf_sandbox(): + args += testutils.DISABLE_SECCOMP_BPF_ARGS + if testutils.use_software_rendering(): + args += testutils.SOFTWARE_RENDERING_ARGS args.append('about:blank') return args diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index 0c306a3e7..607293d19 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -45,8 +45,11 @@ def _base_args(config): else: args += ['--backend', 'webkit'] - if config.webengine and testutils.disable_seccomp_bpf_sandbox(): - args += testutils.DISABLE_SECCOMP_BPF_ARGS + if config.webengine: + if testutils.disable_seccomp_bpf_sandbox(): + args += testutils.DISABLE_SECCOMP_BPF_ARGS + if testutils.use_software_rendering(): + args += testutils.SOFTWARE_RENDERING_ARGS args.append('about:blank') return args diff --git a/tests/helpers/testutils.py b/tests/helpers/testutils.py index a123fb0d2..626115b60 100644 --- a/tests/helpers/testutils.py +++ b/tests/helpers/testutils.py @@ -264,6 +264,15 @@ def easyprivacy_txt(): return _decompress_gzip_datafile("easyprivacy.txt.gz") +def _has_qtwebengine() -> bool: + """Check whether QtWebEngine is available.""" + try: + from qutebrowser.qt import webenginecore # pylint: disable=unused-import + except ImportError: + return False + return True + + DISABLE_SECCOMP_BPF_FLAG = "--disable-seccomp-filter-sandbox" DISABLE_SECCOMP_BPF_ARGS = ["-s", "qt.chromium.sandboxing", "disable-seccomp-bpf"] @@ -294,18 +303,15 @@ def _needs_map_discard_workaround(webengine_version: utils.VersionNumber) -> boo return libc_version >= affected_glibc and kernel_version >= affected_kernel -def disable_seccomp_bpf_sandbox(): + +def disable_seccomp_bpf_sandbox() -> bool: """Check whether we need to disable the seccomp BPF sandbox. This is needed for some QtWebEngine setups, with older Qt versions but newer kernels. """ - try: - from qutebrowser.qt import webenginecore # pylint: disable=unused-import - except ImportError: - # no QtWebEngine available + if not _has_qtwebengine(): return False - versions = version.qtwebengine_versions(avoid_init=True) return ( versions.webengine == utils.VersionNumber(5, 15, 2) @@ -313,6 +319,23 @@ def disable_seccomp_bpf_sandbox(): ) +SOFTWARE_RENDERING_FLAG = "--disable-gpu" +SOFTWARE_RENDERING_ARGS = ["-s", "qt.force_software_rendering", "chromium"] + + +def use_software_rendering() -> bool: + """Check whether to enforce software rendering for tests.""" + if not _has_qtwebengine(): + return False + + versions = version.qtwebengine_versions(avoid_init=True) + return ( + # https://github.com/qutebrowser/qutebrowser/issues/8444#issuecomment-2569554046 + # not on CI, but unknown how to tell apart affected / unaffected systems + versions.webengine == utils.VersionNumber(6, 9) + ) + + def import_userscript(name): """Import a userscript via importlib.