summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/bleeding.yml2
-rw-r--r--doc/changelog.asciidoc16
-rw-r--r--doc/help/commands.asciidoc1
-rw-r--r--doc/help/settings.asciidoc10
-rw-r--r--misc/requirements/requirements-check-manifest.txt4
-rw-r--r--misc/requirements/requirements-dev.txt8
-rw-r--r--misc/requirements/requirements-flake8.txt4
-rw-r--r--misc/requirements/requirements-mypy.txt8
-rw-r--r--misc/requirements/requirements-pyinstaller.txt2
-rw-r--r--misc/requirements/requirements-pylint.txt4
-rw-r--r--misc/requirements/requirements-pyroma.txt4
-rw-r--r--misc/requirements/requirements-sphinx.txt14
-rw-r--r--misc/requirements/requirements-tests.txt20
-rw-r--r--misc/requirements/requirements-tox.txt10
-rw-r--r--qutebrowser/browser/commands.py27
-rw-r--r--qutebrowser/components/misccommands.py5
-rw-r--r--qutebrowser/config/configdata.yml11
-rw-r--r--qutebrowser/keyinput/basekeyparser.py3
-rw-r--r--qutebrowser/mainwindow/tabbedbrowser.py5
-rw-r--r--requirements.txt6
-rw-r--r--scripts/dev/recompile_requirements.py4
-rw-r--r--tests/conftest.py70
-rw-r--r--tests/end2end/conftest.py2
-rw-r--r--tests/end2end/features/tabs.feature58
-rw-r--r--tests/unit/keyinput/test_basekeyparser.py11
-rw-r--r--tests/unit/utils/test_version.py21
-rw-r--r--tox.ini2
27 files changed, 253 insertions, 79 deletions
diff --git a/.github/workflows/bleeding.yml b/.github/workflows/bleeding.yml
index 766f535d7..435141e56 100644
--- a/.github/workflows/bleeding.yml
+++ b/.github/workflows/bleeding.yml
@@ -58,7 +58,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
- python-version: 3.9
+ python-version: "3.10"
- name: Get asciidoc
uses: actions/checkout@v2
with:
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc
index f86b84622..36861b802 100644
--- a/doc/changelog.asciidoc
+++ b/doc/changelog.asciidoc
@@ -24,6 +24,21 @@ Changed
- Improved message if a spawned process wasn't found and a Flatpak container is
in use.
+- The `:tab-move` command now takes `start` and `end` as `index` to move a tab
+ to the first/last position.
+- Tests now automatically pick the backend (QtWebKit/QtWebEngine) based on
+ what's available. The `QUTE_BDD_WEBENGINE` environment variable and
+ `--qute-bdd-webengine` argument got replaced by `QUTE_TESTS_BACKEND` and
+ `--qute-backend` respectively, which can be set to either `webengine` or
+ `webkit`.
+- Using `:tab-give` or `:tab-take` on the last tab in a window now always
+ closes that window, no matter what `tabs.last_close` is set to.
+
+Added
+~~~~~
+
+- New `input.match_counts` option which allows to turn off count matching for
+ more emacs-like bindings.
[[v2.4.1]]
v2.4.1 (unreleased)
@@ -36,6 +51,7 @@ Fixed
binaries (in certain rare environments).
- Speculative fix for a qutebrowser crash when the notification daemon crashes
while showing the notification.
+- Fix crash when using `:screenshot` with an invalid `--rect` argument.
[[v2.4.0]]
v2.4.0 (2021-10-21)
diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc
index 8c11e15cc..442c136a7 100644
--- a/doc/help/commands.asciidoc
+++ b/doc/help/commands.asciidoc
@@ -1431,6 +1431,7 @@ If neither is given, move it to the first position.
==== positional arguments
* +'index'+: `+` or `-` to move relative to the current tab by count, or a default of 1 space.
A tab index to move to that index.
+ `start` and `end` to move to the start and the end.
==== count
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 60c229078..4ca5c2517 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -269,6 +269,7 @@
|<<input.insert_mode.leave_on_load,input.insert_mode.leave_on_load>>|Leave insert mode when starting a new page load.
|<<input.insert_mode.plugins,input.insert_mode.plugins>>|Switch to insert mode when clicking flash and other plugins.
|<<input.links_included_in_focus_chain,input.links_included_in_focus_chain>>|Include hyperlinks in the keyboard focus chain when tabbing.
+|<<input.match_counts,input.match_counts>>|Interpret number prefixes as counts for bindings.
|<<input.media_keys,input.media_keys>>|Whether the underlying Chromium should handle media keys.
|<<input.mouse.back_forward_buttons,input.mouse.back_forward_buttons>>|Enable back and forward buttons on the mouse.
|<<input.mouse.rocker_gestures,input.mouse.rocker_gestures>>|Enable Opera-like mouse rocker gestures.
@@ -3557,6 +3558,15 @@ Type: <<types,Bool>>
Default: +pass:[true]+
+[[input.match_counts]]
+=== input.match_counts
+Interpret number prefixes as counts for bindings.
+This enables for vi-like bindings that can be prefixed with a number to indicate a count. Disabling it allows for emacs-like bindings where number keys are passed through (according to `input.forward_unbound_keys`) instead.
+
+Type: <<types,Bool>>
+
+Default: +pass:[true]+
+
[[input.media_keys]]
=== input.media_keys
Whether the underlying Chromium should handle media keys.
diff --git a/misc/requirements/requirements-check-manifest.txt b/misc/requirements/requirements-check-manifest.txt
index 21843c4ae..c61218ba3 100644
--- a/misc/requirements/requirements-check-manifest.txt
+++ b/misc/requirements/requirements-check-manifest.txt
@@ -2,8 +2,8 @@
build==0.7.0
check-manifest==0.47
-packaging==21.2
+packaging==21.3
pep517==0.12.0
-pyparsing==2.4.7
+pyparsing==3.0.6
toml==0.10.2
tomli==1.2.2
diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt
index 34234a50b..0dd45cebc 100644
--- a/misc/requirements/requirements-dev.txt
+++ b/misc/requirements/requirements-dev.txt
@@ -3,18 +3,18 @@
bump2version==1.0.1
certifi==2021.10.8
cffi==1.15.0
-charset-normalizer==2.0.7
-cryptography==35.0.0
+charset-normalizer==2.0.8
+cryptography==36.0.0
Deprecated==1.2.13
github3.py==3.0.0
hunter==3.3.8
idna==3.3
jwcrypto==1.0
manhole==1.8.0
-packaging==21.2
+packaging==21.3
pycparser==2.21
Pympler==0.9
-pyparsing==2.4.7
+pyparsing==3.0.6
PyQt-builder==1.12.2
python-dateutil==2.8.2
requests==2.26.0
diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt
index 08b75e2bf..1d1f5eebc 100644
--- a/misc/requirements/requirements-flake8.txt
+++ b/misc/requirements/requirements-flake8.txt
@@ -2,7 +2,7 @@
attrs==21.2.0
flake8==4.0.1
-flake8-bugbear==21.9.2
+flake8-bugbear==21.11.28
flake8-builtins==1.5.3
flake8-comprehensions==3.7.0
flake8-copyright==0.2.2
@@ -21,4 +21,4 @@ pycodestyle==2.8.0
pydocstyle==6.1.1
pyflakes==2.4.0
six==1.16.0
-snowballstemmer==2.1.0
+snowballstemmer==2.2.0
diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt
index 4d5f08e49..ce64972b3 100644
--- a/misc/requirements/requirements-mypy.txt
+++ b/misc/requirements/requirements-mypy.txt
@@ -2,10 +2,10 @@
chardet==4.0.0
diff-cover==6.4.2
-importlib-metadata==4.8.1
+importlib-metadata==4.8.2
importlib-resources==5.4.0
inflect==5.3.0
-Jinja2==3.0.2
+Jinja2==3.0.3
jinja2-pluralize==0.3.0
lxml==4.6.4
MarkupSafe==2.0.1
@@ -16,6 +16,6 @@ Pygments==2.10.0
PyQt5-stubs==5.15.2.0
toml==0.10.2
types-dataclasses==0.6.1
-types-PyYAML==6.0.0
-typing-extensions==3.10.0.2
+types-PyYAML==6.0.1
+typing_extensions==4.0.0
zipp==3.6.0
diff --git a/misc/requirements/requirements-pyinstaller.txt b/misc/requirements/requirements-pyinstaller.txt
index 8d5567e67..9a53c11cd 100644
--- a/misc/requirements/requirements-pyinstaller.txt
+++ b/misc/requirements/requirements-pyinstaller.txt
@@ -1,5 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
altgraph==0.17.2
-pyinstaller==4.6
+pyinstaller==4.7
pyinstaller-hooks-contrib==2021.3
diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt
index afb692789..c26af6406 100644
--- a/misc/requirements/requirements-pylint.txt
+++ b/misc/requirements/requirements-pylint.txt
@@ -3,8 +3,8 @@
astroid==2.3.3 # rq.filter: < 2.4
certifi==2021.10.8
cffi==1.15.0
-charset-normalizer==2.0.7
-cryptography==35.0.0
+charset-normalizer==2.0.8
+cryptography==36.0.0
Deprecated==1.2.13
future==0.18.2
github3.py==3.0.0
diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt
index 8849014be..a76402053 100644
--- a/misc/requirements/requirements-pyroma.txt
+++ b/misc/requirements/requirements-pyroma.txt
@@ -1,8 +1,8 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
certifi==2021.10.8
-charset-normalizer==2.0.7
-docutils==0.18
+charset-normalizer==2.0.8
+docutils==0.18.1
idna==3.3
Pygments==2.10.0
pyroma==3.2
diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt
index 86553bb4c..b7f013853 100644
--- a/misc/requirements/requirements-sphinx.txt
+++ b/misc/requirements/requirements-sphinx.txt
@@ -3,19 +3,19 @@
alabaster==0.7.12
Babel==2.9.1
certifi==2021.10.8
-charset-normalizer==2.0.7
+charset-normalizer==2.0.8
docutils==0.17.1
idna==3.3
-imagesize==1.2.0
-Jinja2==3.0.2
+imagesize==1.3.0
+Jinja2==3.0.3
MarkupSafe==2.0.1
-packaging==21.2
+packaging==21.3
Pygments==2.10.0
-pyparsing==2.4.7
+pyparsing==3.0.6
pytz==2021.3
requests==2.26.0
-snowballstemmer==2.1.0
-Sphinx==4.2.0
+snowballstemmer==2.2.0
+Sphinx==4.3.1
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt
index a3a48adea..b15a23c08 100644
--- a/misc/requirements/requirements-tests.txt
+++ b/misc/requirements/requirements-tests.txt
@@ -3,28 +3,28 @@
attrs==21.2.0
beautifulsoup4==4.10.0
certifi==2021.10.8
-charset-normalizer==2.0.7
+charset-normalizer==2.0.8
cheroot==8.5.2
click==8.0.3
-coverage==6.1.1
+coverage==6.2
EasyProcess==0.3
execnet==1.9.0
-filelock==3.3.2
+filelock==3.4.0
Flask==2.0.2
glob2==0.7
hunter==3.3.8
-hypothesis==6.24.2
+hypothesis==6.28.1
icdiff==2.0.4
idna==3.3
iniconfig==1.1.1
itsdangerous==2.0.1
jaraco.functools==3.4.0
-# Jinja2==3.0.2
-Mako==1.1.5
+# Jinja2==3.0.3
+Mako==1.1.6
manhole==1.8.0
# MarkupSafe==2.0.1
-more-itertools==8.10.0
-packaging==21.2
+more-itertools==8.12.0
+packaging==21.3
parse==1.19.0
parse-type==0.5.2
pluggy==1.0.0
@@ -32,7 +32,7 @@ pprintpp==0.4.0
py==1.11.0
py-cpuinfo==8.0.0
Pygments==2.10.0
-pyparsing==2.4.7
+pyparsing==3.0.6
pytest==6.2.5
pytest-bdd==4.1.0
pytest-benchmark==3.4.1
@@ -51,7 +51,7 @@ requests==2.26.0
requests-file==1.5.1
six==1.16.0
sortedcontainers==2.4.0
-soupsieve==2.3
+soupsieve==2.3.1
tldextract==3.1.2
toml==0.10.2
tomli==1.2.2
diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt
index a069ca44b..a2a57808b 100644
--- a/misc/requirements/requirements-tox.txt
+++ b/misc/requirements/requirements-tox.txt
@@ -1,15 +1,15 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-backports.entry-points-selectable==1.1.0
+backports.entry-points-selectable==1.1.1
distlib==0.3.3
-filelock==3.3.2
-packaging==21.2
+filelock==3.4.0
+packaging==21.3
pip==21.3.1
platformdirs==2.4.0
pluggy==1.0.0
py==1.11.0
-pyparsing==2.4.7
-setuptools==58.5.3
+pyparsing==3.0.6
+setuptools==59.4.0
six==1.16.0
toml==0.10.2
tox==3.24.4
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
index f3438aaa8..796bb2eb3 100644
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -451,7 +451,7 @@ class CommandDispatcher:
self._open(tab.url(), tab=True)
if not keep:
- tabbed_browser.close_tab(tab, add_undo=False)
+ tabbed_browser.close_tab(tab, add_undo=False, transfer=True)
@cmdutils.register(instance='command-dispatcher', scope='window')
@cmdutils.argument('win_id', completion=miscmodels.window)
@@ -500,7 +500,8 @@ class CommandDispatcher:
tabbed_browser.tabopen(self._current_url())
if not keep:
self._tabbed_browser.close_tab(self._current_widget(),
- add_undo=False)
+ add_undo=False,
+ transfer=True)
def _back_forward(self, tab, bg, window, count, forward, index=None):
"""Helper function for :back/:forward."""
@@ -1004,11 +1005,10 @@ class CommandDispatcher:
raise cmdutils.CommandError("There's no tab with index {}!".format(
index))
- @cmdutils.register(instance='command-dispatcher', scope='window')
- @cmdutils.argument('index', choices=['+', '-'])
- @cmdutils.argument('count', value=cmdutils.Value.count)
- def tab_move(self, index: Union[str, int] = None,
- count: int = None) -> None:
+ @cmdutils.register(instance="command-dispatcher", scope="window")
+ @cmdutils.argument("index", choices=["+", "-", "start", "end"])
+ @cmdutils.argument("count", value=cmdutils.Value.count)
+ def tab_move(self, index: Union[str, int] = None, count: int = None) -> None:
"""Move the current tab according to the argument and [count].
If neither is given, move it to the first position.
@@ -1017,24 +1017,29 @@ class CommandDispatcher:
index: `+` or `-` to move relative to the current tab by
count, or a default of 1 space.
A tab index to move to that index.
+ `start` and `end` to move to the start and the end.
count: If moving relatively: Offset.
If moving absolutely: New position (default: 0). This
overrides the index argument, if given.
"""
- if index in ['+', '-']:
+ if index in ["+", "-"]:
# relative moving
new_idx = self._current_index()
delta = 1 if count is None else count
- if index == '-':
+ if index == "-":
new_idx -= delta
- elif index == '+': # pragma: no branch
+ elif index == "+": # pragma: no branch
new_idx += delta
if config.val.tabs.wrap:
new_idx %= self._count()
else:
# absolute moving
- if count is not None:
+ if index == "start":
+ new_idx = 0
+ elif index == "end":
+ new_idx = self._count() - 1
+ elif count is not None:
new_idx = count - 1
elif index is not None:
assert isinstance(index, int)
diff --git a/qutebrowser/components/misccommands.py b/qutebrowser/components/misccommands.py
index 120806bfe..8eaae045f 100644
--- a/qutebrowser/components/misccommands.py
+++ b/qutebrowser/components/misccommands.py
@@ -183,7 +183,10 @@ def screenshot(
raise cmdutils.CommandError(
f"File {filename} already exists (use --force to overwrite)")
- qrect = None if rect is None else utils.parse_rect(rect)
+ try:
+ qrect = None if rect is None else utils.parse_rect(rect)
+ except ValueError as e:
+ raise cmdutils.CommandError(str(e))
pic = tab.grab_pixmap(qrect)
if pic is None:
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index e034fe8f5..3c5dc6f2f 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -1794,6 +1794,17 @@ input.media_keys:
On Linux, disabling this also disables Chromium's MPRIS integration.
+input.match_counts:
+ default: true
+ type: Bool
+ desc: >-
+ Interpret number prefixes as counts for bindings.
+
+ This enables for vi-like bindings that can be prefixed with a number to
+ indicate a count.
+ Disabling it allows for emacs-like bindings where number keys are passed
+ through (according to `input.forward_unbound_keys`) instead.
+
## keyhint
keyhint.blacklist:
diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py
index 7e688dab1..4db1d5d76 100644
--- a/qutebrowser/keyinput/basekeyparser.py
+++ b/qutebrowser/keyinput/basekeyparser.py
@@ -254,6 +254,9 @@ class BaseKeyParser(QObject):
def _match_count(self, sequence: keyutils.KeySequence,
dry_run: bool) -> bool:
"""Try to match a key as count."""
+ if not config.val.input.match_counts:
+ return False
+
txt = str(sequence[-1]) # To account for sequences changed above.
if (txt in string.digits and self._supports_count and
not (not self._count and txt == '0')):
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
index e081284ee..8c6ac2424 100644
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -406,15 +406,16 @@ class TabbedBrowser(QWidget):
else:
yes_action()
- def close_tab(self, tab, *, add_undo=True, new_undo=True):
+ def close_tab(self, tab, *, add_undo=True, new_undo=True, transfer=False):
"""Close a tab.
Args:
tab: The QWebView to be closed.
add_undo: Whether the tab close can be undone.
new_undo: Whether the undo entry should be a new item in the stack.
+ transfer: Whether the tab is closing because it is moving to a new window.
"""
- if config.val.tabs.tabs_are_windows:
+ if config.val.tabs.tabs_are_windows or transfer:
last_close = 'close'
else:
last_close = config.val.tabs.last_close
diff --git a/requirements.txt b/requirements.txt
index 0805ad6cc..e088ca805 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,11 +3,11 @@
adblock==0.5.0
colorama==0.4.4
dataclasses==0.6 ; python_version<"3.7"
-importlib-metadata==4.8.1 ; python_version<"3.8"
+importlib-metadata==4.8.2 ; python_version<"3.8"
importlib-resources==5.4.0 ; python_version<"3.9"
-Jinja2==3.0.2
+Jinja2==3.0.3
MarkupSafe==2.0.1
Pygments==2.10.0
PyYAML==6.0
-typing-extensions==3.10.0.2
+typing_extensions==4.0.0 ; python_version<"3.8"
zipp==3.6.0
diff --git a/scripts/dev/recompile_requirements.py b/scripts/dev/recompile_requirements.py
index ed5473971..1b9759eb8 100644
--- a/scripts/dev/recompile_requirements.py
+++ b/scripts/dev/recompile_requirements.py
@@ -155,11 +155,11 @@ CHANGELOG_URLS = {
'cheroot': 'https://cheroot.cherrypy.org/en/latest/history.html',
'certifi': 'https://ccadb-public.secure.force.com/mozilla/IncludedCACertificateReport',
'chardet': 'https://github.com/chardet/chardet/releases',
- 'charset-normalizer': 'https://github.com/Ousret/charset_normalizer/commits/master',
+ 'charset-normalizer': 'https://github.com/Ousret/charset_normalizer/blob/master/CHANGELOG.md',
'idna': 'https://github.com/kjd/idna/blob/master/HISTORY.rst',
'tldextract': 'https://github.com/john-kurkowski/tldextract/blob/master/CHANGELOG.md',
'backports.entry-points-selectable': 'https://github.com/jaraco/backports.entry_points_selectable/blob/main/CHANGES.rst',
- 'typing-extensions': 'https://github.com/python/typing/commits/master/typing_extensions',
+ 'typing_extensions': 'https://github.com/python/typing/commits/master/typing_extensions',
'diff-cover': 'https://github.com/Bachmann1234/diff_cover/blob/master/CHANGELOG',
'pytest-icdiff': 'https://github.com/hjwp/pytest-icdiff/blob/master/HISTORY.rst',
'icdiff': 'https://github.com/jeffkaufman/icdiff/blob/master/ChangeLog',
diff --git a/tests/conftest.py b/tests/conftest.py
index 40631af34..26cc04345 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -214,20 +214,74 @@ def pytest_addoption(parser):
help="Delay between qutebrowser commands.")
parser.addoption('--qute-profile-subprocs', action='store_true',
default=False, help="Run cProfile for subprocesses.")
- parser.addoption('--qute-bdd-webengine', action='store_true',
- help='Use QtWebEngine for BDD tests')
+ parser.addoption('--qute-backend', action='store',
+ choices=['webkit', 'webengine'], help='Set backend for BDD tests')
def pytest_configure(config):
- webengine_arg = config.getoption('--qute-bdd-webengine')
- webengine_env = os.environ.get('QUTE_BDD_WEBENGINE', 'false')
- config.webengine = webengine_arg or webengine_env == 'true'
- # Fail early if QtWebEngine is not available
- if config.webengine:
- import PyQt5.QtWebEngineWidgets
+ backend = _select_backend(config)
+ config.webengine = backend == 'webengine'
+
earlyinit.configure_pyqt()
+def _select_backend(config):
+ """Select the backend for running tests.
+
+ The backend is auto-selected in the following manner:
+ 1. Use QtWebKit if available
+ 2. Otherwise use QtWebEngine as a fallback
+
+ Auto-selection is overridden by either passing a backend via
+ `--qute-backend=<backend>` or setting the environment variable
+ `QUTE_TESTS_BACKEND=<backend>`.
+
+ Args:
+ config: pytest config
+
+ Raises:
+ ImportError if the selected backend is not available.
+
+ Returns:
+ The selected backend as a string (e.g. 'webkit').
+ """
+ backend_arg = config.getoption('--qute-backend')
+ backend_env = os.environ.get('QUTE_TESTS_BACKEND')
+
+ backend = backend_arg or backend_env or _auto_select_backend()
+
+ # Fail early if selected backend is not available
+ if backend == 'webkit':
+ import PyQt5.QtWebKitWidgets
+ elif backend == 'webengine':
+ import PyQt5.QtWebEngineWidgets
+ else:
+ raise utils.Unreachable(backend)
+
+ return backend
+
+
+def _auto_select_backend():
+ try:
+ # Try to use QtWebKit as the default backend
+ import PyQt5.QtWebKitWidgets
+ return 'webkit'
+ except ImportError:
+ # Try to use QtWebEngine as a fallback and fail early
+ # if that's also not available
+ import PyQt5.QtWebEngineWidgets
+ return 'webengine'
+
+
+def pytest_report_header(config):
+ if config.webengine:
+ backend_version = version.qtwebengine_versions(avoid_init=True)
+ else:
+ backend_version = version.qWebKitVersion()
+
+ return f'backend: {backend_version}'
+
+
@pytest.fixture(scope='session', autouse=True)
def check_display(request):
if utils.is_linux and not os.environ.get('DISPLAY', ''):
diff --git a/tests/end2end/conftest.py b/tests/end2end/conftest.py
index a4a089cea..16170d460 100644
--- a/tests/end2end/conftest.py
+++ b/tests/end2end/conftest.py
@@ -165,7 +165,7 @@ if not getattr(sys, 'frozen', False):
def pytest_collection_modifyitems(config, items):
- """Apply @qtwebengine_* markers; skip unittests with QUTE_BDD_WEBENGINE."""
+ """Apply @qtwebengine_* markers."""
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-75884
# (note this isn't actually fixed properly before Qt 5.15)
header_bug_fixed = qtutils.version_check('5.15', compiled=False)
diff --git a/tests/end2end/features/tabs.feature b/tests/end2end/features/tabs.feature
index c9d983755..3715d5765 100644
--- a/tests/end2end/features/tabs.feature
+++ b/tests/end2end/features/tabs.feature
@@ -633,6 +633,27 @@ Feature: Tab management
- data/numbers/1.txt (active)
- data/numbers/3.txt
+ Scenario: :tab-move with absolute position
+ When I open data/numbers/1.txt
+ And I open data/numbers/2.txt in a new tab
+ And I open data/numbers/3.txt in a new tab
+ And I run :tab-focus 1
+ And I run :tab-move end
+ Then the following tabs should be open:
+ - data/numbers/2.txt
+ - data/numbers/3.txt
+ - data/numbers/1.txt (active)
+
+ Scenario: :tab-move with absolute position
+ When I open data/numbers/1.txt
+ And I open data/numbers/2.txt in a new tab
+ And I open data/numbers/3.txt in a new tab
+ And I run :tab-move start
+ Then the following tabs should be open:
+ - data/numbers/3.txt (active)
+ - data/numbers/1.txt
+ - data/numbers/2.txt
+
Scenario: Make sure :tab-move retains metadata
When I open data/title.html
And I open data/hello.txt in a new tab
@@ -1349,6 +1370,25 @@ Feature: Tab management
And I run :tab-take 0/1
Then the error "Can't take tabs when using windows as tabs" should be shown
+ @windows_skip
+ Scenario: Close the last tab of a window when taken by another window
+ Given I have a fresh instance
+ When I open data/numbers/1.txt
+ And I run :tab-only
+ And I open data/numbers/2.txt in a new window
+ And I set tabs.last_close to ignore
+ And I run :tab-take 1/1
+ And I wait until data/numbers/2.txt is loaded
+ Then the session should look like:
+ windows:
+ - tabs:
+ - history:
+ - url: about:blank
+ - url: http://localhost:*/data/numbers/1.txt
+ - active: true
+ history:
+ - url: http://localhost:*/data/numbers/2.txt
+
# :tab-give
@xfail_norun # Needs qutewm
@@ -1406,6 +1446,24 @@ Feature: Tab management
And I run :tab-give 0
Then the error "Can't give tabs when using windows as tabs" should be shown
+ @windows_skip
+ Scenario: Close the last tab of a window when given to another window
+ Given I have a fresh instance
+ When I open data/numbers/1.txt
+ And I run :tab-only
+ And I open data/numbers/2.txt in a new window
+ And I set tabs.last_close to ignore
+ And I run :tab-give 1
+ And I wait until data/numbers/1.txt is loaded
+ Then the session should look like:
+ windows:
+ - tabs:
+ - active: true
+ history:
+ - url: http://localhost:*/data/numbers/2.txt
+ - history:
+ - url: http://localhost:*/data/numbers/1.txt
+
# Other
Scenario: Using :tab-next after closing last tab (#1448)
diff --git a/tests/unit/keyinput/test_basekeyparser.py b/tests/unit/keyinput/test_basekeyparser.py
index 30ee36301..84068bf47 100644
--- a/tests/unit/keyinput/test_basekeyparser.py
+++ b/tests/unit/keyinput/test_basekeyparser.py
@@ -346,3 +346,14 @@ def test_clear_keystring_empty(qtbot, keyparser):
keyparser._sequence = keyseq('')
with qtbot.assert_not_emitted(keyparser.keystring_updated):
keyparser.clear_keystring()
+
+
+def test_respect_config_when_matching_counts(keyparser, config_stub):
+ """Don't match counts if disabled in the config."""
+ config_stub.val.input.match_counts = False
+
+ info = keyutils.KeyInfo(Qt.Key_1, Qt.NoModifier)
+ keyparser.handle(info.to_event())
+
+ assert not keyparser._sequence
+ assert not keyparser._count
diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py
index 6c57cb3d3..1ffbe3c09 100644
--- a/tests/unit/utils/test_version.py
+++ b/tests/unit/utils/test_version.py
@@ -484,17 +484,20 @@ class TestGitStrSubprocess:
@needs_git
def test_real_git(self, git_repo):
"""Test with a real git repository."""
- branch_name = subprocess.run(
- ['git', 'config', 'init.defaultBranch'],
- check=False,
- stdout=subprocess.PIPE,
- encoding='utf-8',
- ).stdout.strip()
- if not branch_name:
- branch_name = 'master'
+ def _get_git_setting(name, default):
+ return subprocess.run(
+ ['git', 'config', '--default', default, name],
+ check=True,
+ stdout=subprocess.PIPE,
+ encoding='utf-8',
+ ).stdout.strip()
ret = version._git_str_subprocess(str(git_repo))
- assert ret == f'6e4b65a on {branch_name} (1970-01-01 01:00:00 +0100)'
+ branch_name = _get_git_setting('init.defaultBranch', 'master')
+ abbrev_length = int(_get_git_setting('core.abbrev', '7'))
+ expected_sha = '6e4b65a529c0ab78fb370c1527d5809f7436b8f3'[:abbrev_length]
+
+ assert ret == f'{expected_sha} on {branch_name} (1970-01-01 01:00:00 +0100)'
def test_missing_dir(self, tmp_path):
"""Test with a directory which doesn't exist."""
diff --git a/tox.ini b/tox.ini
index 271bf4241..f52d7b158 100644
--- a/tox.ini
+++ b/tox.ini
@@ -13,7 +13,6 @@ minversion = 3.15
setenv =
PYTEST_QT_API=pyqt5
pyqt{,512,513,514,515,5150}: LINK_PYQT_SKIP=true
- pyqt{,512,513,514,515,5150}: QUTE_BDD_WEBENGINE=true
cov: PYTEST_ADDOPTS=--cov --cov-report xml --cov-report=html --cov-report=
passenv = PYTHON DISPLAY XAUTHORITY HOME USERNAME USER CI XDG_* QUTE_* DOCKER QT_QUICK_BACKEND PY_COLORS DBUS_SESSION_BUS_ADDRESS
basepython =
@@ -42,7 +41,6 @@ commands =
basepython = {env:PYTHON:python3}
setenv =
PYTEST_QT_API=pyqt5
- QUTE_BDD_WEBENGINE=true
pip_pre = true
deps = -r{toxinidir}/misc/requirements/requirements-tests-bleeding.txt
commands_pre = pip install --index-url https://www.riverbankcomputing.com/pypi/simple/ --pre --upgrade PyQt5 PyQtWebEngine