summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2021-02-15 13:54:16 +0100
committerFlorian Bruhin <me@the-compiler.org>2021-02-15 13:54:16 +0100
commit21089415434485b6cdb4949fef35fba8a3a9c48c (patch)
tree1dcfd440fbc865bab8db44f492d12d4957ac3dad
parent36b8d955b6ccabd7374f09339c6f157cb13f3958 (diff)
downloadqutebrowser-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.py13
-rw-r--r--tests/end2end/test_invocations.py43
-rw-r--r--tests/unit/config/test_qtargs.py17
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: