diff options
author | Florian Bruhin <me@the-compiler.org> | 2021-02-15 13:54:16 +0100 |
---|---|---|
committer | Florian Bruhin <me@the-compiler.org> | 2021-02-15 13:54:16 +0100 |
commit | 21089415434485b6cdb4949fef35fba8a3a9c48c (patch) | |
tree | 1dcfd440fbc865bab8db44f492d12d4957ac3dad | |
parent | 36b8d955b6ccabd7374f09339c6f157cb13f3958 (diff) | |
download | qutebrowser-21089415434485b6cdb4949fef35fba8a3a9c48c.tar.gz qutebrowser-21089415434485b6cdb4949fef35fba8a3a9c48c.zip |
Avoid calling versions.webengine_versions() without QtWebEngine
Alternatively, it would have been possible to move the backend library
checking from backendproblem.py to earlyinit.py entirely. However, this
would lead to less user-friendly dialogs, as we can't e.g. offer a
button to switch the backend setting.
Fixes #6161
-rw-r--r-- | qutebrowser/config/qtargs.py | 13 | ||||
-rw-r--r-- | tests/end2end/test_invocations.py | 43 | ||||
-rw-r--r-- | tests/unit/config/test_qtargs.py | 17 |
3 files changed, 73 insertions, 0 deletions
diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py index 7f971e2a0..66fa10339 100644 --- a/qutebrowser/config/qtargs.py +++ b/qutebrowser/config/qtargs.py @@ -58,6 +58,19 @@ def qt_args(namespace: argparse.Namespace) -> List[str]: assert objects.backend == usertypes.Backend.QtWebKit, objects.backend return argv + try: + from qutebrowser.browser.webengine import webenginesettings + except ImportError: + # This code runs before a QApplication is available, so before + # backendproblem.py is run to actually inform the user of the missing + # backend. Thus, we could end up in a situation where we're here, but + # QtWebEngine isn't actually available. + # We shouldn't call _qtwebengine_args() in this case as it relies on + # QtWebEngine actually being importable, e.g. in + # version.qtwebengine_versions(). + log.init.debug("QtWebEngine requested, but unavailable...") + return argv + special_prefixes = (_ENABLE_FEATURES, _DISABLE_FEATURES, _BLINK_SETTINGS) special_flags = [flag for flag in argv if flag.startswith(special_prefixes)] argv = [flag for flag in argv if not flag.startswith(special_prefixes)] diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index 30b998c02..6bf9fe623 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -23,6 +23,7 @@ import configparser import subprocess import sys import logging +import importlib import re import json @@ -660,3 +661,45 @@ def test_dark_mode(webengine_versions, quteproc_new, request, color = testutils.Color(img.pixelColor(pos)) # For pytest debug output assert color == expected + + +def test_unavailable_backend(request, quteproc_new): + """Test starting with a backend which isn't available. + + If we use --qute-bdd-webengine, we test with QtWebKit here; otherwise we test with + QtWebEngine. If both are available, the test is skipped. + + This ensures that we don't accidentally use backend-specific code before checking + that the chosen backend is actually available - i.e., that the error message is + properly printed, rather than an unhandled exception. + """ + qtwe_module = "PyQt5.QtWebEngineWidgets" + qtwk_module = "PyQt5.QtWebKitWidgets" + # Note we want to try the *opposite* backend here. + if request.config.webengine: + pytest.importorskip(qtwe_module) + module = qtwk_module + backend = 'webkit' + else: + pytest.importorskip(qtwk_module) + module = qtwe_module + backend = 'webengine' + + try: + importlib.import_module(module) + except ImportError: + pass + else: + pytest.skip(f"{module} is available") + + args = [ + '--debug', '--json-logging', '--no-err-windows', + '--backend', backend, + '--temp-basedir' + ] + quteproc_new.exit_expected = True + quteproc_new.start(args) + line = quteproc_new.wait_for( + message=('*qutebrowser tried to start with the Qt* backend but failed ' + 'because * could not be imported.*')) + line.expected = True diff --git a/tests/unit/config/test_qtargs.py b/tests/unit/config/test_qtargs.py index 6bc1b2873..55acb4bb1 100644 --- a/tests/unit/config/test_qtargs.py +++ b/tests/unit/config/test_qtargs.py @@ -105,6 +105,23 @@ class TestQtArgs: assert arg in args +def test_no_webengine_available(monkeypatch, config_stub, parser, stubs): + """Test that we don't fail if QtWebEngine is requested but unavailable. + + Note this is not inside TestQtArgs because we don't want the reduce_args patching + here. + """ + monkeypatch.setattr(qtargs.objects, 'backend', usertypes.Backend.QtWebEngine) + monkeypatch.setattr(qtargs.version, 'webenginesettings', None) + + fake = stubs.ImportFake({'qutebrowser.browser.webengine': False}, monkeypatch) + fake.patch() + + parsed = parser.parse_args([]) + args = qtargs.qt_args(parsed) + assert args == [sys.argv[0]] + + @pytest.mark.usefixtures('reduce_args') class TestWebEngineArgs: |