summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.flake813
-rw-r--r--README.asciidoc21
-rw-r--r--doc/changelog.asciidoc5
-rw-r--r--doc/help/settings.asciidoc1
-rw-r--r--misc/requirements/requirements-dev.txt6
-rw-r--r--misc/requirements/requirements-flake8.txt4
-rw-r--r--misc/requirements/requirements-flake8.txt-raw1
-rw-r--r--misc/requirements/requirements-mypy.txt6
-rw-r--r--misc/requirements/requirements-pylint.txt2
-rw-r--r--misc/requirements/requirements-pyroma.txt2
-rw-r--r--misc/requirements/requirements-qutebrowser.txt-raw2
-rw-r--r--misc/requirements/requirements-sphinx.txt2
-rw-r--r--misc/requirements/requirements-tests.txt6
-rw-r--r--misc/requirements/requirements-tox.txt7
-rw-r--r--qutebrowser/browser/webengine/notification.py13
-rw-r--r--qutebrowser/config/configdata.yml3
-rw-r--r--qutebrowser/keyinput/eventfilter.py2
-rw-r--r--qutebrowser/mainwindow/tabwidget.py22
-rw-r--r--requirements.txt5
-rw-r--r--scripts/dev/recompile_requirements.py5
-rw-r--r--tests/end2end/features/notifications.feature8
-rw-r--r--tests/end2end/test_insert_mode.py2
-rw-r--r--tests/helpers/fixtures.py2
-rw-r--r--tests/unit/browser/test_caret.py2
-rw-r--r--tests/unit/browser/test_history.py2
-rw-r--r--tests/unit/browser/test_inspector.py3
-rw-r--r--tests/unit/browser/webkit/test_webkitelem.py2
-rw-r--r--tests/unit/completion/test_completionwidget.py4
-rw-r--r--tests/unit/completion/test_models.py4
-rw-r--r--tests/unit/config/test_configcommands.py4
-rw-r--r--tests/unit/config/test_configfiles.py1
-rw-r--r--tests/unit/config/test_configtypes.py1
-rw-r--r--tests/unit/config/test_configutils.py2
-rw-r--r--tests/unit/config/test_qtargs.py2
-rw-r--r--tests/unit/config/test_websettings.py2
-rw-r--r--tests/unit/misc/test_guiprocess.py4
-rw-r--r--tests/unit/misc/test_miscwidgets.py2
-rw-r--r--tests/unit/utils/test_log.py2
-rw-r--r--tests/unit/utils/test_qtutils.py5
-rw-r--r--tests/unit/utils/test_resources.py2
40 files changed, 115 insertions, 69 deletions
diff --git a/.flake8 b/.flake8
index 5cfa2e76c..9110dc54c 100644
--- a/.flake8
+++ b/.flake8
@@ -41,6 +41,9 @@ exclude = .*,__pycache__,resources.py
# W503: like break before binary operator
# W504: line break after binary operator
# FI15: __future__ import "generator_stop" missing
+# PT004: fixture '{name}' does not return anything, add leading underscore
+# PT011: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
+# PT012: pytest.raises() block should contain a single simple statement
ignore =
B001,B008,B305,
E128,E226,E265,E501,E402,E266,E722,E731,
@@ -49,8 +52,11 @@ ignore =
P101,P102,P103,
D102,D103,D106,D107,D104,D105,D209,D211,D401,D402,D403,D412,D413,
A003,
- W503, W504
- FI15
+ W503, W504,
+ FI15,
+ PT004,
+ PT011,
+ PT012
min-version = 3.6.1
max-complexity = 12
per-file-ignores =
@@ -62,3 +68,6 @@ per-file-ignores =
copyright-check = True
copyright-regexp = # Copyright [\d-]+ .*
copyright-min-file-size = 110
+pytest-fixture-no-parentheses = True
+pytest-mark-no-parentheses = True
+pytest-parametrize-names-type = csv
diff --git a/README.asciidoc b/README.asciidoc
index 20644cb34..a5d3af9ff 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -202,22 +202,17 @@ Active
~~~~~~
* https://fanglingsu.github.io/vimb/[vimb] (C, GTK+ with WebKit2)
-* https://github.com/jun7/wyeb[wyeb] (C, GTK+ with WebKit2)
* https://luakit.github.io/luakit/[luakit] (C/Lua, GTK+ with WebKit2)
* https://nyxt.atlas.engineer/[Nyxt browser] (formerly "Next browser", Lisp, Emacs-like but also offers Vim bindings, QtWebEngine or GTK+/WebKit2 - note there was a https://jgkamat.gitlab.io/blog/next-rce.html[critical remote code execution in 2019] which was handled quite badly)
* https://vieb.dev/[Vieb] (JavaScript, Electron)
* https://surf.suckless.org/[surf] (C, GTK+ with WebKit1/WebKit2)
* Chrome/Chromium addons:
- https://vimium.github.io/[Vimium],
- https://github.com/dcchambers/vb4c[vb4c] (fork of cVim)
+ https://vimium.github.io/[Vimium]
* Firefox addons (based on WebExtensions):
- https://github.com/tridactyl/tridactyl[Tridactyl],
- https://addons.mozilla.org/en-GB/firefox/addon/vimium-ff/[Vimium-FF] (experimental),
- https://github.com/ueokande/vim-vixen[Vim Vixen],
- https://github.com/amedama41/vvimpulation[VVimpulation]
+ https://tridactyl.xyz/[Tridactyl],
+ https://addons.mozilla.org/en-GB/firefox/addon/vimium-ff/[Vimium-FF]
* Addons for Firefox and Chrome:
https://github.com/brookhong/Surfingkeys[Surfingkeys],
- https://krabby.netlify.com/[Krabby],
https://lydell.github.io/LinkHints/[Link Hints] (hinting only)
* Addons for Safari:
https://televator.net/vimari/[Vimari]
@@ -232,23 +227,27 @@ main inspiration for qutebrowser)
QtWebEngine, https://github.com/parkouss/webmacs/issues/137[unmaintained])
* https://sourceforge.net/p/vimprobable/wiki/Home/[vimprobable] (C, GTK+ with
WebKit1)
-* https://wiki.archlinux.org/index.php?title=Jumanji[jumanji] (C, GTK+ with WebKit1,
-original site is gone but the Arch Linux wiki has some data)
+* https://pwmt.org/projects/jumanji/[jumanji] (C, GTK+ with WebKit1)
* http://conkeror.org/[conkeror] (Javascript, Emacs-like, XULRunner/Gecko)
* https://www.uzbl.org/[uzbl] (C, GTK+ with WebKit1/WebKit2)
* https://github.com/conformal/xombrero[xombrero] (C, GTK+ with WebKit1)
* https://github.com/linkdd/cream-browser[Cream Browser] (C, GTK+ with WebKit1)
+* https://github.com/jun7/wyeb[wyeb] (C, GTK+ with WebKit2)
* Firefox addons (not based on WebExtensions or no recent activity):
http://www.vimperator.org/[Vimperator],
http://bug.5digits.org/pentadactyl/index[Pentadactyl],
https://github.com/akhodakivskiy/VimFx[VimFx] (seems to offer a
https://gir.st/blog/legacyfox.htm[hack] to run on modern Firefox releases),
- https://github.com/shinglyu/QuantumVim[QuantumVim]
+ https://github.com/shinglyu/QuantumVim[QuantumVim],
+ https://github.com/ueokande/vim-vixen[Vim Vixen] (ESR only),
+ https://github.com/amedama41/vvimpulation[VVimpulation],
+ https://krabby.netlify.com/[Krabby]
* Chrome/Chromium addons:
https://github.com/k2nr/ViChrome/[ViChrome],
https://github.com/jinzhu/vrome[Vrome],
https://github.com/lusakasa/saka-key[Saka Key] (https://github.com/lusakasa/saka-key/issues/171[unmaintained]),
https://github.com/1995eaton/chromium-vim[cVim],
+ https://github.com/dcchambers/vb4c[vb4c] (fork of cVim, https://github.com/dcchambers/vb4c/issues/23#issuecomment-810694017[unmaintained]),
https://glee.github.io/[GleeBox]
License
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc
index 6b2746c96..5e34f5fbc 100644
--- a/doc/changelog.asciidoc
+++ b/doc/changelog.asciidoc
@@ -39,12 +39,17 @@ Changed
`menuitem`, `menuitemcheckbox` and `menuitemradio`).
- Using e.g. `:bind --mode=passthrough` now scrolls to the passthrough section
on the `qute://bindings` page.
+- Clicking on a notification now tries to focus the tab where the notification
+ is coming from. Note this might not work properly if there is more than one
+ tab from the same host open.
Added
~~~~~
- New `input.match_counts` option which allows to turn off count matching for
more emacs-like bindings.
+- New `{relative_index}` field for `tabs.title.format` (and `.pinned_format`)
+ which shows relative tab numbers.
Fixed
~~~~~
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 7435fd31f..b8705749a 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -4388,6 +4388,7 @@ The following placeholders are defined:
* `{index}`: Index of this tab.
* `{aligned_index}`: Index of this tab padded with spaces to have the same
width.
+* `{relative_index}`: Index of this tab relative to the current tab.
* `{id}`: Internal tab ID of this tab.
* `{scroll_pos}`: Page scroll position.
* `{host}`: Host of the current web page.
diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt
index 932ab161e..dc2041598 100644
--- a/misc/requirements/requirements-dev.txt
+++ b/misc/requirements/requirements-dev.txt
@@ -16,13 +16,13 @@ idna==3.3
importlib-metadata==4.10.0
jeepney==0.7.1
jwcrypto==1.0
-keyring==23.4.0
+keyring==23.5.0
manhole==1.8.0
packaging==21.3
pep517==0.12.0
pkginfo==1.8.2
pycparser==2.21
-Pygments==2.10.0
+Pygments==2.11.1
Pympler==1.0.1
pyparsing==3.0.6
PyQt-builder==1.12.2
@@ -42,4 +42,4 @@ uritemplate==4.1.1
# urllib3==1.26.7
webencodings==0.5.1
wrapt==1.13.3
-zipp==3.6.0
+zipp==3.7.0
diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt
index fc7568e9a..2f13b4733 100644
--- a/misc/requirements/requirements-flake8.txt
+++ b/misc/requirements/requirements-flake8.txt
@@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-attrs==21.2.0
+attrs==21.4.0
flake8==4.0.1
flake8-bugbear==21.11.29
flake8-builtins==1.5.3
@@ -11,7 +11,9 @@ flake8-deprecated==1.3
flake8-docstrings==1.6.0
flake8-future-import==0.4.6
flake8-mock==0.3
+flake8-plugin-utils==1.3.2
flake8-polyfill==1.0.2
+flake8-pytest-style==1.6.0
flake8-string-format==0.3.0
flake8-tidy-imports==4.5.0
flake8-tuple==0.4.1
diff --git a/misc/requirements/requirements-flake8.txt-raw b/misc/requirements/requirements-flake8.txt-raw
index 1bdca6974..59908897c 100644
--- a/misc/requirements/requirements-flake8.txt-raw
+++ b/misc/requirements/requirements-flake8.txt-raw
@@ -11,6 +11,7 @@ flake8-mock
flake8-string-format
flake8-tidy-imports
flake8-tuple
+flake8-pytest-style
pep8-naming
pydocstyle
pyflakes
diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt
index dc20c9d69..0b40fa31f 100644
--- a/misc/requirements/requirements-mypy.txt
+++ b/misc/requirements/requirements-mypy.txt
@@ -10,10 +10,10 @@ MarkupSafe==2.0.1
mypy==0.930
mypy-extensions==0.4.3
pluggy==1.0.0
-Pygments==2.10.0
+Pygments==2.11.1
PyQt5-stubs==5.15.2.0
tomli==2.0.0
-types-dataclasses==0.6.1
+types-dataclasses==0.6.2
types-PyYAML==6.0.1
typing_extensions==4.0.1
-zipp==3.6.0
+zipp==3.7.0
diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt
index 2e1b57e31..2ea50cb8f 100644
--- a/misc/requirements/requirements-pylint.txt
+++ b/misc/requirements/requirements-pylint.txt
@@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-astroid==2.9.0
+astroid==2.9.1
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.9
diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt
index 4b98b6dad..cdb3b388f 100644
--- a/misc/requirements/requirements-pyroma.txt
+++ b/misc/requirements/requirements-pyroma.txt
@@ -4,7 +4,7 @@ certifi==2021.10.8
charset-normalizer==2.0.9
docutils==0.18.1
idna==3.3
-Pygments==2.10.0
+Pygments==2.11.1
pyroma==3.2
requests==2.26.0
urllib3==1.26.7
diff --git a/misc/requirements/requirements-qutebrowser.txt-raw b/misc/requirements/requirements-qutebrowser.txt-raw
index 9f2e369a1..139d599f8 100644
--- a/misc/requirements/requirements-qutebrowser.txt-raw
+++ b/misc/requirements/requirements-qutebrowser.txt-raw
@@ -21,3 +21,5 @@ typing_extensions # from importlib-metadata
# Python 3.6
#@ add: importlib-metadata<4.9 ; python_version=="3.6.*"
+#@ markers: zipp python_version>="3.7"
+#@ add: zipp<3.7 ; python_version=="3.6.*"
diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt
index 6fc36a3c1..687b1cd00 100644
--- a/misc/requirements/requirements-sphinx.txt
+++ b/misc/requirements/requirements-sphinx.txt
@@ -10,7 +10,7 @@ imagesize==1.3.0
Jinja2==3.0.3
MarkupSafe==2.0.1
packaging==21.3
-Pygments==2.10.0
+Pygments==2.11.1
pyparsing==3.0.6
pytz==2021.3
requests==2.26.0
diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt
index e3ced54f6..7d17cc661 100644
--- a/misc/requirements/requirements-tests.txt
+++ b/misc/requirements/requirements-tests.txt
@@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-attrs==21.2.0
+attrs==21.4.0
beautifulsoup4==4.10.0
certifi==2021.10.8
charset-normalizer==2.0.9
@@ -13,7 +13,7 @@ filelock==3.4.2 ; python_version>="3.7"
Flask==2.0.2
glob2==0.7
hunter==3.4.3
-hypothesis==6.32.1 ; python_version>="3.7"
+hypothesis==6.34.1 ; python_version>="3.7"
icdiff==2.0.4
idna==3.3
iniconfig==1.1.1
@@ -31,7 +31,7 @@ pluggy==1.0.0
pprintpp==0.4.0
py==1.11.0
py-cpuinfo==8.0.0
-Pygments==2.10.0
+Pygments==2.11.1
pyparsing==3.0.6
pytest==6.2.5
pytest-bdd==4.1.0
diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt
index 914a9904f..d1a85cebe 100644
--- a/misc/requirements/requirements-tox.txt
+++ b/misc/requirements/requirements-tox.txt
@@ -1,6 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-backports.entry-points-selectable==1.1.1
distlib==0.3.4
filelock==3.4.2 ; python_version>="3.7"
packaging==21.3
@@ -9,11 +8,11 @@ platformdirs==2.4.1 ; python_version>="3.7"
pluggy==1.0.0
py==1.11.0
pyparsing==3.0.6
-setuptools==60.1.0 ; python_version>="3.7"
+setuptools==60.2.0 ; python_version>="3.7"
six==1.16.0
toml==0.10.2
-tox==3.24.4
-virtualenv==20.10.0
+tox==3.24.5
+virtualenv==20.13.0
wheel==0.37.1
setuptools<60 ; python_version=="3.6.*"
filelock==3.4.1 ; python_version=="3.6.*"
diff --git a/qutebrowser/browser/webengine/notification.py b/qutebrowser/browser/webengine/notification.py
index e943e44e9..69c702aec 100644
--- a/qutebrowser/browser/webengine/notification.py
+++ b/qutebrowser/browser/webengine/notification.py
@@ -65,7 +65,7 @@ if TYPE_CHECKING:
from qutebrowser.config import config
from qutebrowser.misc import objects
-from qutebrowser.utils import qtutils, log, utils, debug, message, version
+from qutebrowser.utils import qtutils, log, utils, debug, message, version, objreg
from qutebrowser.qt import sip
@@ -368,6 +368,17 @@ class NotificationBridgePresenter(QObject):
# https://www.riverbankcomputing.com/pipermail/pyqt/2020-May/042918.html
log.misc.debug(f"Ignoring click request for notification {notification_id} "
"due to PyQt bug")
+ return
+ self._focus_first_matching_tab(notification)
+
+ def _focus_first_matching_tab(self, notification: "QWebEngineNotification") -> None:
+ for win_id in objreg.window_registry:
+ tabbedbrowser = objreg.get("tabbed-browser", window=win_id, scope="window")
+ for idx, tab in enumerate(tabbedbrowser.widgets()):
+ if tab.url().matches(notification.origin(), QUrl.RemovePath):
+ tabbedbrowser.widget.setCurrentIndex(idx)
+ return
+ log.misc.debug(f"No matching tab found for {notification.origin()}")
def _drop_adapter(self) -> None:
"""Drop the currently active adapter (if any).
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index c2619ac1f..b0d9c6364 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -2171,6 +2171,7 @@ tabs.title.format:
- title_sep
- index
- aligned_index
+ - relative_index
- id
- scroll_pos
- host
@@ -2190,6 +2191,7 @@ tabs.title.format:
* `{index}`: Index of this tab.
* `{aligned_index}`: Index of this tab padded with spaces to have the same
width.
+ * `{relative_index}`: Index of this tab relative to the current tab.
* `{id}`: Internal tab ID of this tab.
* `{scroll_pos}`: Page scroll position.
* `{host}`: Host of the current web page.
@@ -2210,6 +2212,7 @@ tabs.title.format_pinned:
- title_sep
- index
- aligned_index
+ - relative_index
- id
- scroll_pos
- host
diff --git a/qutebrowser/keyinput/eventfilter.py b/qutebrowser/keyinput/eventfilter.py
index 4d016bea6..f0d85b0ec 100644
--- a/qutebrowser/keyinput/eventfilter.py
+++ b/qutebrowser/keyinput/eventfilter.py
@@ -35,7 +35,7 @@ class EventFilter(QObject):
Attributes:
_activated: Whether the EventFilter is currently active.
- _handlers; A {QEvent.Type: callable} dict with the handlers for an
+ _handlers: A {QEvent.Type: callable} dict with the handlers for an
event.
"""
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
index 07b1e5bef..0e95b7745 100644
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -136,18 +136,31 @@ class TabWidget(QTabWidget):
(fmt is None or ('{' + field + '}') not in fmt)):
return
+ def right_align(num):
+ return str(num).rjust(len(str(self.count())))
+
+ def left_align(num):
+ return str(num).ljust(len(str(self.count())))
+
+ bar = self.tabBar()
+ cur_idx = bar.currentIndex()
+ if idx == cur_idx:
+ rel_idx = left_align(idx + 1) + " "
+ else:
+ rel_idx = " " + right_align(abs(idx - cur_idx))
+
fields = self.get_tab_fields(idx)
fields['current_title'] = fields['current_title'].replace('&', '&&')
fields['index'] = idx + 1
- fields['aligned_index'] = str(idx + 1).rjust(len(str(self.count())))
+ fields['aligned_index'] = right_align(idx + 1)
+ fields['relative_index'] = rel_idx
title = '' if fmt is None else fmt.format(**fields)
- tabbar = self.tabBar()
# Only change the tab title if it changes, setting the tab title causes
# a size recalculation which is slow.
- if tabbar.tabText(idx) != title:
- tabbar.setTabText(idx, title)
+ if bar.tabText(idx) != title:
+ bar.setTabText(idx, title)
def get_tab_fields(self, idx):
"""Get the tab field data."""
@@ -305,6 +318,7 @@ class TabWidget(QTabWidget):
def _on_current_changed(self, index):
"""Emit the tab_index_changed signal if the current tab changed."""
self.tabBar().on_current_changed()
+ self.update_tab_titles()
self.tab_index_changed.emit(index, self.count())
@pyqtSlot()
diff --git a/requirements.txt b/requirements.txt
index 7528da7d4..8d1151dd7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,8 +7,9 @@ importlib-metadata==4.10.0 ; python_version=="3.7.*"
importlib-resources==5.4.0 ; python_version<"3.9"
Jinja2==3.0.3
MarkupSafe==2.0.1
-Pygments==2.10.0
+Pygments==2.11.1
PyYAML==6.0
typing_extensions==4.0.1 ; python_version<"3.8"
-zipp==3.6.0
+zipp==3.7.0 ; python_version>="3.7"
importlib-metadata<4.9 ; python_version=="3.6.*"
+zipp<3.7 ; python_version=="3.6.*"
diff --git a/scripts/dev/recompile_requirements.py b/scripts/dev/recompile_requirements.py
index 185770132..dc56380bf 100644
--- a/scripts/dev/recompile_requirements.py
+++ b/scripts/dev/recompile_requirements.py
@@ -95,11 +95,13 @@ CHANGELOG_URLS = {
'flake8-mock': 'https://github.com/aleGpereira/flake8-mock#changes',
'flake8-polyfill': 'https://gitlab.com/pycqa/flake8-polyfill/-/blob/master/CHANGELOG.rst',
'flake8-string-format': 'https://github.com/xZise/flake8-string-format#changes',
+ 'flake8-plugin-utils': 'https://github.com/afonasev/flake8-plugin-utils#change-log',
+ 'flake8-pytest-style': 'https://github.com/m-burst/flake8-pytest-style#change-log',
'pep8-naming': 'https://github.com/PyCQA/pep8-naming/blob/master/CHANGELOG.rst',
'pycodestyle': 'https://github.com/PyCQA/pycodestyle/blob/master/CHANGES.txt',
'pyflakes': 'https://github.com/PyCQA/pyflakes/blob/master/NEWS.rst',
'cffi': 'https://github.com/python-cffi/release-doc/blob/master/doc/source/whatsnew.rst',
- 'astroid': 'https://github.com/PyCQA/astroid/blob/2.4/ChangeLog',
+ 'astroid': 'https://github.com/PyCQA/astroid/blob/main/ChangeLog',
'pytest-instafail': 'https://github.com/pytest-dev/pytest-instafail/blob/master/CHANGES.rst',
'coverage': 'https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst',
'colorama': 'https://github.com/tartley/colorama/blob/master/CHANGELOG.rst',
@@ -158,7 +160,6 @@ CHANGELOG_URLS = {
'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/blob/master/typing_extensions/CHANGELOG',
'diff-cover': 'https://github.com/Bachmann1234/diff_cover/blob/master/CHANGELOG',
'pytest-icdiff': 'https://github.com/hjwp/pytest-icdiff/blob/master/HISTORY.rst',
diff --git a/tests/end2end/features/notifications.feature b/tests/end2end/features/notifications.feature
index 08c5f725f..cd34793ef 100644
--- a/tests/end2end/features/notifications.feature
+++ b/tests/end2end/features/notifications.feature
@@ -4,7 +4,8 @@ Feature: Notifications
HTML5 notification API interaction
Background:
- Given I open data/javascript/notifications.html
+ Given I clean up open tabs
+ And I open data/javascript/notifications.html
And I set content.notifications.enabled to true
And I run :click-element id button
And I clean up the notification server
@@ -120,8 +121,13 @@ Feature: Notifications
Scenario: User clicks presented notification
When I run :click-element id show-button
And I wait for the javascript message "notification shown"
+ And I open about:blank in a new tab
And I click the notification
Then the javascript message "notification clicked" should be logged
+ And the following tabs should be open:
+ - about:blank
+ - data/javascript/notifications.html (active)
+ - about:blank
@pyqtwebengine<5.15.0
Scenario: User clicks presented notification (old Qt)
diff --git a/tests/end2end/test_insert_mode.py b/tests/end2end/test_insert_mode.py
index e829f25a6..47e481b3d 100644
--- a/tests/end2end/test_insert_mode.py
+++ b/tests/end2end/test_insert_mode.py
@@ -22,7 +22,7 @@
import pytest
-@pytest.mark.parametrize(['file_name', 'elem_id', 'source', 'input_text'], [
+@pytest.mark.parametrize('file_name, elem_id, source, input_text', [
('textarea.html', 'qute-textarea', 'clipboard', 'qutebrowser'),
('textarea.html', 'qute-textarea', 'keypress', 'superqutebrowser'),
('input.html', 'qute-input', 'clipboard', 'amazingqutebrowser'),
diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py
index dd902eb7d..cc362290f 100644
--- a/tests/helpers/fixtures.py
+++ b/tests/helpers/fixtures.py
@@ -632,7 +632,7 @@ def redirect_webengine_data(data_tmpdir, monkeypatch):
monkeypatch.setenv('HOME', str(data_tmpdir))
-@pytest.fixture()
+@pytest.fixture
def short_tmpdir():
"""A short temporary directory for a XDG_RUNTIME_DIR."""
with tempfile.TemporaryDirectory() as tdir:
diff --git a/tests/unit/browser/test_caret.py b/tests/unit/browser/test_caret.py
index 288471ea0..86014040d 100644
--- a/tests/unit/browser/test_caret.py
+++ b/tests/unit/browser/test_caret.py
@@ -70,7 +70,7 @@ class Selection:
self._qtbot.wait(50)
- assert False, 'Failed to get selection!'
+ pytest.fail('Failed to get selection!')
def check_multiline(self, expected, *, strip=False):
self.check(textwrap.dedent(expected).strip(), strip=strip)
diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py
index 7906d385c..51a9effb8 100644
--- a/tests/unit/browser/test_history.py
+++ b/tests/unit/browser/test_history.py
@@ -141,7 +141,7 @@ class TestDelete:
class TestAdd:
- @pytest.fixture()
+ @pytest.fixture
def mock_time(self, mocker):
m = mocker.patch('qutebrowser.browser.history.time')
m.time.return_value = 12345
diff --git a/tests/unit/browser/test_inspector.py b/tests/unit/browser/test_inspector.py
index f7f532050..61ac9510d 100644
--- a/tests/unit/browser/test_inspector.py
+++ b/tests/unit/browser/test_inspector.py
@@ -151,4 +151,5 @@ def test_detach_after_toggling(hidden_again, needs_recreate,
else:
with qtbot.assert_not_emitted(fake_inspector.recreate):
fake_inspector.set_position(inspector.Position.window)
- assert fake_inspector.isVisible() and fake_inspector.isWindow()
+ assert fake_inspector.isVisible()
+ assert fake_inspector.isWindow()
diff --git a/tests/unit/browser/webkit/test_webkitelem.py b/tests/unit/browser/webkit/test_webkitelem.py
index 3ccf573ff..f7cc3e8c2 100644
--- a/tests/unit/browser/webkit/test_webkitelem.py
+++ b/tests/unit/browser/webkit/test_webkitelem.py
@@ -866,8 +866,6 @@ class TestIsEditable:
@pytest.mark.parametrize('setting, tagname, attributes, editable', [
(True, 'embed', {}, True),
- (True, 'embed', {}, True),
- (False, 'applet', {}, False),
(False, 'applet', {}, False),
(True, 'object', {'type': 'application/foo'}, True),
(False, 'object', {'type': 'application/foo'}, False),
diff --git a/tests/unit/completion/test_completionwidget.py b/tests/unit/completion/test_completionwidget.py
index 9a1bc99dd..074228332 100644
--- a/tests/unit/completion/test_completionwidget.py
+++ b/tests/unit/completion/test_completionwidget.py
@@ -37,13 +37,13 @@ def completionview(qtbot, status_command_stub, config_stub, win_registry,
mocker.patch('qutebrowser.completion.completer.Completer', autospec=True)
mocker.patch(
'qutebrowser.completion.completiondelegate.CompletionItemDelegate',
- new=lambda *_: None)
+ return_value=None)
view = completionwidget.CompletionView(cmd=status_command_stub, win_id=0)
qtbot.add_widget(view)
return view
-@pytest.fixture()
+@pytest.fixture
def model():
return completionmodel.CompletionModel()
diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py
index c20fe293c..9e6743083 100644
--- a/tests/unit/completion/test_models.py
+++ b/tests/unit/completion/test_models.py
@@ -76,7 +76,7 @@ def _check_completions(model, expected):
assert sum(model.column_widths) == 100
-@pytest.fixture()
+@pytest.fixture
def cmdutils_stub(monkeypatch, stubs):
"""Patch the cmdutils module to provide fake commands."""
return monkeypatch.setattr(objects, 'commands', {
@@ -93,7 +93,7 @@ def cmdutils_stub(monkeypatch, stubs):
})
-@pytest.fixture()
+@pytest.fixture
def configdata_stub(config_stub, monkeypatch, configdata_init):
"""Patch the configdata module to provide fake data."""
monkeypatch.setattr(configdata, 'DATA', collections.OrderedDict([
diff --git a/tests/unit/config/test_configcommands.py b/tests/unit/config/test_configcommands.py
index 384eb92ab..6dd09cee3 100644
--- a/tests/unit/config/test_configcommands.py
+++ b/tests/unit/config/test_configcommands.py
@@ -27,7 +27,7 @@ from PyQt5.QtCore import QUrl
from qutebrowser.config import configcommands
from qutebrowser.api import cmdutils
-from qutebrowser.utils import usertypes, urlmatch
+from qutebrowser.utils import usertypes, urlmatch, utils
from qutebrowser.keyinput import keyutils
from qutebrowser.misc import objects
@@ -529,7 +529,7 @@ class TestSource:
pyfile = config_tmpdir / 'sourced.py'
arg = 'sourced.py'
else:
- assert False, location
+ raise utils.Unreachable(location)
pyfile.write_text('\n'.join(['config.load_autoconfig(False)',
'c.content.javascript.enabled = False']),
diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py
index fe51f896f..760992e15 100644
--- a/tests/unit/config/test_configfiles.py
+++ b/tests/unit/config/test_configfiles.py
@@ -1481,7 +1481,6 @@ class TestConfigPyWriter:
def init_patch(qapp, fake_save_manager, config_tmpdir, data_tmpdir,
config_stub, monkeypatch):
monkeypatch.setattr(configfiles, 'state', None)
- yield
def test_init(init_patch, config_tmpdir):
diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py
index 66b152937..ef3007f71 100644
--- a/tests/unit/config/test_configtypes.py
+++ b/tests/unit/config/test_configtypes.py
@@ -1876,7 +1876,6 @@ class TestShellCommand:
@pytest.mark.parametrize('kwargs, val', [
({'placeholder': True}, '[foo, bar]'),
({'placeholder': True}, '[foo, "{", "}", bar'),
- ({'placeholder': True}, '[foo, bar]'),
({'placeholder': True}, '[foo, "{fi", "le}", bar'),
# Like valid ones but with wrong placeholder
diff --git a/tests/unit/config/test_configutils.py b/tests/unit/config/test_configutils.py
index 89db342b7..3fc5cd561 100644
--- a/tests/unit/config/test_configutils.py
+++ b/tests/unit/config/test_configutils.py
@@ -318,13 +318,11 @@ class TestFontFamilies:
@pytest.mark.parametrize('families, quote, expected', [
(['family'], True, 'family'),
(['family1', 'family2'], True, 'family1, family2'),
- (['family'], True, 'family'),
(['space family', 'alien'], True, '"space family", alien'),
(['comma,family', 'period'], True, '"comma,family", period'),
(['family'], False, 'family'),
(['family1', 'family2'], False, 'family1, family2'),
- (['family'], False, 'family'),
(['space family', 'alien'], False, 'space family, alien'),
(['comma,family', 'period'], False, 'comma,family, period'),
])
diff --git a/tests/unit/config/test_qtargs.py b/tests/unit/config/test_qtargs.py
index 4c31c5b07..d95382624 100644
--- a/tests/unit/config/test_qtargs.py
+++ b/tests/unit/config/test_qtargs.py
@@ -324,7 +324,6 @@ class TestWebEngineArgs:
("light", "5.15.0", False),
("light", "5.15.1", False),
("light", "5.15.2", False),
- ("light", "5.15.2", False),
("light", "5.15.3", False),
("light", "6.0.0", False),
@@ -333,7 +332,6 @@ class TestWebEngineArgs:
("auto", "5.15.0", False),
("auto", "5.15.1", False),
("auto", "5.15.2", False),
- ("auto", "5.15.2", False),
("auto", "5.15.3", False),
("auto", "6.0.0", False),
])
diff --git a/tests/unit/config/test_websettings.py b/tests/unit/config/test_websettings.py
index 7601c7c24..f42563727 100644
--- a/tests/unit/config/test_websettings.py
+++ b/tests/unit/config/test_websettings.py
@@ -24,7 +24,7 @@ from qutebrowser.misc import objects
from qutebrowser.utils import usertypes
-@pytest.mark.parametrize([
+@pytest.mark.parametrize([ # noqa: PT006
'user_agent', 'os_info', 'webkit_version',
'upstream_browser_key', 'upstream_browser_version', 'qt_key'
], [
diff --git a/tests/unit/misc/test_guiprocess.py b/tests/unit/misc/test_guiprocess.py
index faf2006de..c664757fd 100644
--- a/tests/unit/misc/test_guiprocess.py
+++ b/tests/unit/misc/test_guiprocess.py
@@ -31,7 +31,7 @@ from qutebrowser.api import cmdutils
from qutebrowser.qt import sip
-@pytest.fixture()
+@pytest.fixture
def proc(qtbot, caplog):
"""A fixture providing a GUIProcess and cleaning it up after the test."""
p = guiprocess.GUIProcess('testprocess')
@@ -46,7 +46,7 @@ def proc(qtbot, caplog):
p._proc.waitForFinished()
-@pytest.fixture()
+@pytest.fixture
def fake_proc(monkeypatch, stubs):
"""A fixture providing a GUIProcess with a mocked QProcess."""
p = guiprocess.GUIProcess('testprocess')
diff --git a/tests/unit/misc/test_miscwidgets.py b/tests/unit/misc/test_miscwidgets.py
index 6e1919ec3..3c5c1eef1 100644
--- a/tests/unit/misc/test_miscwidgets.py
+++ b/tests/unit/misc/test_miscwidgets.py
@@ -38,7 +38,7 @@ class TestCommandLineEdit:
cmd_edit.set_prompt(':')
qtbot.add_widget(cmd_edit)
assert cmd_edit.text() == ''
- yield cmd_edit
+ return cmd_edit
def test_position(self, qtbot, cmd_edit):
"""Test cursor position based on the prompt."""
diff --git a/tests/unit/utils/test_log.py b/tests/unit/utils/test_log.py
index 7b0f5293e..9f5a15065 100644
--- a/tests/unit/utils/test_log.py
+++ b/tests/unit/utils/test_log.py
@@ -348,7 +348,7 @@ class TestHideQtWarning:
"""Tests for hide_qt_warning/QtWarningFilter."""
- @pytest.fixture()
+ @pytest.fixture
def qt_logger(self):
return logging.getLogger('qt-tests')
diff --git a/tests/unit/utils/test_qtutils.py b/tests/unit/utils/test_qtutils.py
index 6309e46b5..ad9adf032 100644
--- a/tests/unit/utils/test_qtutils.py
+++ b/tests/unit/utils/test_qtutils.py
@@ -51,8 +51,7 @@ else:
test_file = None
-@pytest.mark.parametrize(['qversion', 'compiled', 'pyqt', 'version', 'exact',
- 'expected'], [
+@pytest.mark.parametrize('qversion, compiled, pyqt, version, exact, expected', [
# equal versions
('5.14.0', None, None, '5.14.0', False, True),
('5.14.0', None, None, '5.14.0', True, True), # exact=True
@@ -741,7 +740,7 @@ class TestPyQIODevice:
with pytest.raises(io.UnsupportedOperation):
pyqiodev.seek(0, whence)
- @pytest.mark.flaky()
+ @pytest.mark.flaky
def test_qprocess(self, py_proc):
"""Test PyQIODevice with a QProcess which is non-sequential.
diff --git a/tests/unit/utils/test_resources.py b/tests/unit/utils/test_resources.py
index 738fadd37..6a11ff588 100644
--- a/tests/unit/utils/test_resources.py
+++ b/tests/unit/utils/test_resources.py
@@ -65,7 +65,7 @@ class TestReadFile:
'qutebrowser/html/unrelatedhtml',
]
- yield zipfile.Path(zip_path) / 'qutebrowser'
+ return zipfile.Path(zip_path) / 'qutebrowser'
@pytest.fixture(params=['pathlib', 'zipfile'])
def resource_root(self, request):