From c2210539a9e2be1deacf8df8f432e035d9b9b9f0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 27 Jul 2023 12:28:24 +0200 Subject: Drop 32bit Windows release support See #6050, still keeping open to track NSIS changes --- .github/workflows/nightly.yml | 25 ++++--------- scripts/dev/build_release.py | 84 +++++++++++++------------------------------ tox.ini | 2 +- 3 files changed, 31 insertions(+), 80 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2502d017b..18c12e053 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -19,47 +19,34 @@ jobs: toxenv: build-release-qt5 name: qt5-macos - os: windows-2019 - args: --64bit branch: main toxenv: build-release-qt5 - name: qt5-windows-64bit - - os: windows-2019 - args: --32bit - branch: main - toxenv: build-release-qt5 - name: qt5-windows-32bit - + name: qt5-windows - os: macos-11 args: --debug branch: main toxenv: build-release-qt5 name: qt5-macos-debug - os: windows-2019 - args: --64bit --debug - branch: main - toxenv: build-release-qt5 - name: qt5-windows-64bit-debug - - os: windows-2019 - args: --32bit --debug + args: --debug branch: main toxenv: build-release-qt5 - name: qt5-windows-32bit-debug + name: qt5-windows-debug - os: macos-11 toxenv: build-release name: macos - os: windows-2019 - args: --64bit toxenv: build-release - name: windows-64bit + name: windows - os: macos-11 args: --debug toxenv: build-release name: macos-debug - os: windows-2019 - args: --64bit --debug + args: --debug toxenv: build-release - name: windows-64bit-debug + name: windows-debug runs-on: "${{ matrix.os }}" timeout-minutes: 45 steps: diff --git a/scripts/dev/build_release.py b/scripts/dev/build_release.py index 1ddef5cc0..73689ea88 100755 --- a/scripts/dev/build_release.py +++ b/scripts/dev/build_release.py @@ -340,7 +340,7 @@ def build_mac( gh_token=gh_token) utils.print_title("Building .app via pyinstaller") - call_tox(f'pyinstaller-64bit{"-qt5" if qt5 else ""}', '-r', debug=debug) + call_tox(f'pyinstaller{"-qt5" if qt5 else ""}', '-r', debug=debug) utils.print_title("Patching .app") patch_mac_app(qt5=qt5) utils.print_title("Re-signing .app") @@ -388,18 +388,14 @@ def build_mac( ] -def _get_windows_python_path(x64: bool) -> pathlib.Path: +def _get_windows_python_path() -> pathlib.Path: """Get the path to Python.exe on Windows.""" parts = str(sys.version_info.major), str(sys.version_info.minor) ver = ''.join(parts) dot_ver = '.'.join(parts) - if x64: - path = rf'SOFTWARE\Python\PythonCore\{dot_ver}\InstallPath' - fallback = pathlib.Path('C:', f'Python{ver}', 'python.exe') - else: - path = rf'SOFTWARE\WOW6432Node\Python\PythonCore\{dot_ver}-32\InstallPath' - fallback = pathlib.Path('C:', f'Python{ver}-32', 'python.exe') + path = rf'SOFTWARE\Python\PythonCore\{dot_ver}\InstallPath' + fallback = pathlib.Path('C:', f'Python{ver}', 'python.exe') try: key = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, path) @@ -409,47 +405,39 @@ def _get_windows_python_path(x64: bool) -> pathlib.Path: def _build_windows_single( - *, x64: bool, + *, qt5: bool, skip_packaging: bool, debug: bool, ) -> List[Artifact]: - """Build on Windows for a single architecture.""" - human_arch = '64-bit' if x64 else '32-bit' - utils.print_title(f"Running pyinstaller {human_arch}") + """Build on Windows for a single build type.""" + utils.print_title("Running pyinstaller") dist_path = pathlib.Path("dist") - arch = "x64" if x64 else "x86" - out_path = dist_path / f'qutebrowser-{qutebrowser.__version__}-{arch}' + out_path = dist_path / f'qutebrowser-{qutebrowser.__version__}' _maybe_remove(out_path) - python = _get_windows_python_path(x64=x64) - suffix = "64bit" if x64 else "32bit" - if qt5: - # FIXME:qt6 does this regress 391623d5ec983ecfc4512c7305c4b7a293ac3872? - suffix += "-qt5" - call_tox(f'pyinstaller-{suffix}', '-r', python=python, debug=debug) + python = _get_windows_python_path() + # FIXME:qt6 does this regress 391623d5ec983ecfc4512c7305c4b7a293ac3872? + suffix = "-qt5" if qt5 else "" + call_tox(f'pyinstaller{suffix}', '-r', python=python, debug=debug) out_pyinstaller = dist_path / "qutebrowser" shutil.move(out_pyinstaller, out_path) exe_path = out_path / 'qutebrowser.exe' - utils.print_title(f"Verifying {human_arch} exe") + utils.print_title("Verifying exe") verify_windows_exe(exe_path) - utils.print_title(f"Running {human_arch} smoke test") + utils.print_title("Running smoke test") smoke_test(exe_path, debug=debug, qt5=qt5) if skip_packaging: return [] - utils.print_title(f"Packaging {human_arch}") + utils.print_title("Packaging") return _package_windows_single( - nsis_flags=[] if x64 else ['/DX86'], out_path=out_path, - filename_arch='amd64' if x64 else 'win32', - desc_arch=human_arch, - desc_suffix='' if x64 else ' (only for 32-bit Windows!)', debug=debug, qt5=qt5, ) @@ -458,8 +446,6 @@ def _build_windows_single( def build_windows( *, gh_token: str, skip_packaging: bool, - only_32bit: bool, - only_64bit: bool, qt5: bool, debug: bool, ) -> List[Artifact]: @@ -470,37 +456,23 @@ def build_windows( utils.print_title("Building Windows binaries") - artifacts = [] - from scripts.dev import gen_versioninfo utils.print_title("Updating VersionInfo file") gen_versioninfo.main() - if not only_32bit: - artifacts += _build_windows_single( - x64=True, - skip_packaging=skip_packaging, - debug=debug, - qt5=qt5, - ) - if not only_64bit and qt5: - artifacts += _build_windows_single( - x64=False, + artifacts = [ + _build_windows_single( skip_packaging=skip_packaging, debug=debug, qt5=qt5, - ) - + ), + ] return artifacts def _package_windows_single( *, - nsis_flags: List[str], out_path: pathlib.Path, - desc_arch: str, - desc_suffix: str, - filename_arch: str, debug: bool, qt5: bool, ) -> List[Artifact]: @@ -508,15 +480,14 @@ def _package_windows_single( artifacts = [] dist_path = pathlib.Path("dist") - utils.print_subtitle(f"Building {desc_arch} installer...") + utils.print_subtitle("Building installer...") subprocess.run(['makensis.exe', - f'/DVERSION={qutebrowser.__version__}', *nsis_flags, + f'/DVERSION={qutebrowser.__version__}', 'misc/nsis/qutebrowser.nsi'], check=True) name_parts = [ 'qutebrowser', str(qutebrowser.__version__), - filename_arch, ] if debug: name_parts.append('debug') @@ -527,16 +498,15 @@ def _package_windows_single( artifacts.append(Artifact( path=dist_path / name, mimetype='application/vnd.microsoft.portable-executable', - description=f'Windows {desc_arch} installer{desc_suffix}', + description='Windows installer', )) - utils.print_subtitle(f"Zipping {desc_arch} standalone...") + utils.print_subtitle("Zipping standalone...") zip_name_parts = [ 'qutebrowser', str(qutebrowser.__version__), 'windows', 'standalone', - filename_arch, ] if debug: zip_name_parts.append('debug') @@ -549,7 +519,7 @@ def _package_windows_single( artifacts.append(Artifact( path=zip_path, mimetype='application/zip', - description=f'Windows {desc_arch} standalone{desc_suffix}', + description='Windows standalone', )) return artifacts @@ -720,10 +690,6 @@ def main() -> None: help="Skip confirmation before uploading.") parser.add_argument('--skip-packaging', action='store_true', required=False, help="Skip Windows installer/zip generation or macOS DMG.") - parser.add_argument('--32bit', action='store_true', required=False, - help="Skip Windows 64 bit build.", dest='only_32bit') - parser.add_argument('--64bit', action='store_true', required=False, - help="Skip Windows 32 bit build.", dest='only_64bit') parser.add_argument('--debug', action='store_true', required=False, help="Build a debug build.") parser.add_argument('--qt5', action='store_true', required=False, @@ -754,8 +720,6 @@ def main() -> None: artifacts = build_windows( gh_token=gh_token, skip_packaging=args.skip_packaging, - only_32bit=args.only_32bit, - only_64bit=args.only_64bit, qt5=args.qt5, debug=args.debug, ) diff --git a/tox.ini b/tox.ini index 7616cac38..d9615fb27 100644 --- a/tox.ini +++ b/tox.ini @@ -181,7 +181,7 @@ commands = {envpython} scripts/dev/check_doc_changes.py {posargs} {envpython} scripts/asciidoc2html.py {posargs} -[testenv:pyinstaller-{64bit,32bit}{,-qt5}] +[testenv:pyinstaller{,-qt5}] basepython = {env:PYTHON:python3} passenv = APPDATA -- cgit v1.2.3-54-g00ecf From 34dcedf5128c351a1b44a3d453f848d7336bc1da Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Sat, 29 Jul 2023 08:18:06 +0800 Subject: qt6: let importlib import PyQt6.sip Currently, ":version" fails to show the sip version for Qt6. This is because the sip module can't imported in the same way as Qt5. In Qt5, the sip module can be imported after "from PyQt5.QtCore import *". In Qt 6, this is no longer the case, >>> from PyQt6.QtCore import * >>> import sip Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'sip' So let importlib import PyQt6.sip explicitly. --- qutebrowser/utils/version.py | 7 +++++-- tests/unit/utils/test_version.py | 8 ++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index fdaa12efb..65fca21f7 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -381,7 +381,6 @@ class ModuleInfo: def _create_module_info() -> Dict[str, ModuleInfo]: packages = [ - ('sip', ['SIP_VERSION_STR']), ('colorama', ['VERSION', '__version__']), ('jinja2', ['__version__']), ('pygments', ['__version__']), @@ -392,12 +391,16 @@ def _create_module_info() -> Dict[str, ModuleInfo]: if machinery.IS_QT5: packages += [ + ('sip', ['SIP_VERSION_STR']), ('PyQt5.QtWebEngineWidgets', []), ('PyQt5.QtWebEngine', ['PYQT_WEBENGINE_VERSION_STR']), ('PyQt5.QtWebKitWidgets', []), ] elif machinery.IS_QT6: - packages.append(('PyQt6.QtWebEngineCore', ['PYQT_WEBENGINE_VERSION_STR'])) + packages += [ + ('PyQt6.QtWebEngineCore', ['PYQT_WEBENGINE_VERSION_STR']), + ('PyQt6.sip', ['SIP_VERSION_STR']), + ] else: raise utils.Unreachable() diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index f78a6f12d..ce3912595 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -644,8 +644,8 @@ class TestModuleVersions: assert version._module_versions() == expected @pytest.mark.parametrize('module, idx, expected', [ - ('colorama', 1, 'colorama: no'), - ('adblock', 5, 'adblock: no'), + ('colorama', 0, 'colorama: no'), + ('adblock', 4, 'adblock: no'), ]) def test_missing_module(self, module, idx, expected, import_fake): """Test with a module missing. @@ -693,7 +693,7 @@ class TestModuleVersions: assert not mod_info.is_usable() expected = f"adblock: {fake_version} (< {mod_info.min_version}, outdated)" - assert version._module_versions()[5] == expected + assert version._module_versions()[4] == expected @pytest.mark.parametrize('attribute, expected_modules', [ ('VERSION', ['colorama']), @@ -720,7 +720,7 @@ class TestModuleVersions: expected = [] for name in import_fake.modules: mod_info = version.MODULE_INFO[name] - if name in expected_modules: + if name in expected_modules or ("sip" in expected_modules and name == "PyQt6.sip"): assert mod_info.get_version() == "1.2.3" expected.append('{}: 1.2.3'.format(name)) else: -- cgit v1.2.3-54-g00ecf From ea6c84e04b60fcef06356b11612109015fbefe76 Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 30 Jul 2023 11:02:56 +1200 Subject: Use full sip module for PyQt5 too. It's a change from before but it's strictly more accurate anyway, in the application we are always using sip from under the PyQt module, even if PyQt5 registers it as the plain `sip` too. And now it's consistent with what we have to do for PyQt6. --- qutebrowser/utils/version.py | 2 +- tests/unit/utils/test_version.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 65fca21f7..ce816b9fd 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -391,10 +391,10 @@ def _create_module_info() -> Dict[str, ModuleInfo]: if machinery.IS_QT5: packages += [ - ('sip', ['SIP_VERSION_STR']), ('PyQt5.QtWebEngineWidgets', []), ('PyQt5.QtWebEngine', ['PYQT_WEBENGINE_VERSION_STR']), ('PyQt5.QtWebKitWidgets', []), + ('PyQt5.sip', ['SIP_VERSION_STR']), ] elif machinery.IS_QT6: packages += [ diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index ce3912595..486270d70 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -697,7 +697,7 @@ class TestModuleVersions: @pytest.mark.parametrize('attribute, expected_modules', [ ('VERSION', ['colorama']), - ('SIP_VERSION_STR', ['sip']), + ('SIP_VERSION_STR', ['PyQt5.sip', 'PyQt6.sip']), (None, []), ]) def test_version_attribute(self, attribute, expected_modules, import_fake): @@ -720,7 +720,7 @@ class TestModuleVersions: expected = [] for name in import_fake.modules: mod_info = version.MODULE_INFO[name] - if name in expected_modules or ("sip" in expected_modules and name == "PyQt6.sip"): + if name in expected_modules: assert mod_info.get_version() == "1.2.3" expected.append('{}: 1.2.3'.format(name)) else: -- cgit v1.2.3-54-g00ecf From 6aa53a3c9b97598b2175a6984bbb8d2819e9bf54 Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 30 Jul 2023 11:06:54 +1200 Subject: Update docs --- doc/changelog.asciidoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 03dbbeeae..2006b4ab4 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -204,6 +204,9 @@ Fixed - Crash when the "herbe" notification presenter doesn't start correctly. - Crash when using `:print --pdf` with a directory where its parent directory did not exist. +- The `PyQt{5,6}.sip` version is now shown correctly in the :version|--version + output. Previously that showed the version from the standalone `sip` module + which was only set for PyQt5. (#7805) [[v2.5.4]] v2.5.4 (2023-03-13) -- cgit v1.2.3-54-g00ecf From 4049bac356d51df9a4943fa9a83abb09feb74a01 Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 31 Jul 2023 04:22:34 +0000 Subject: Update dependencies --- misc/requirements/requirements-dev.txt | 4 ++-- misc/requirements/requirements-flake8.txt | 6 +++--- misc/requirements/requirements-pylint.txt | 6 +++--- misc/requirements/requirements-sphinx.txt | 2 +- misc/requirements/requirements-tests.txt | 2 +- misc/requirements/requirements-tox.txt | 4 ++-- misc/requirements/requirements-yamllint.txt | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index 6655cbfde..03ee37edf 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -19,7 +19,7 @@ keyring==24.2.0 manhole==1.8.0 markdown-it-py==3.0.0 mdurl==0.1.2 -more-itertools==9.1.0 +more-itertools==10.0.0 packaging==23.1 pkginfo==1.9.6 ply==3.11 @@ -34,7 +34,7 @@ readme-renderer==40.0 requests==2.31.0 requests-toolbelt==1.0.0 rfc3986==2.0.0 -rich==13.4.2 +rich==13.5.0 SecretStorage==3.3.3 sip==6.7.10 six==1.16.0 diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt index 685542224..e16d6860f 100644 --- a/misc/requirements/requirements-flake8.txt +++ b/misc/requirements/requirements-flake8.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py attrs==23.1.0 -flake8==6.0.0 +flake8==6.1.0 flake8-bugbear==23.7.10 flake8-builtins==2.1.0 flake8-comprehensions==3.14.0 @@ -16,8 +16,8 @@ flake8-tidy-imports==4.10.0 flake8-tuple==0.4.1 mccabe==0.7.0 pep8-naming==0.13.3 -pycodestyle==2.10.0 +pycodestyle==2.11.0 pydocstyle==6.3.0 -pyflakes==3.0.1 +pyflakes==3.1.0 six==1.16.0 snowballstemmer==2.2.0 diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt index 62d7696eb..4975a725e 100644 --- a/misc/requirements/requirements-pylint.txt +++ b/misc/requirements/requirements-pylint.txt @@ -12,16 +12,16 @@ isort==5.12.0 lazy-object-proxy==1.9.0 mccabe==0.7.0 pefile==2023.2.7 -platformdirs==3.9.1 +platformdirs==3.10.0 pycparser==2.21 PyJWT==2.8.0 -pylint==2.17.4 +pylint==2.17.5 python-dateutil==2.8.2 ./scripts/dev/pylint_checkers requests==2.31.0 six==1.16.0 tomli==2.0.1 -tomlkit==0.11.8 +tomlkit==0.12.1 typing_extensions==4.7.1 uritemplate==4.1.1 # urllib3==2.0.4 diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt index 35b0e6257..fda124301 100644 --- a/misc/requirements/requirements-sphinx.txt +++ b/misc/requirements/requirements-sphinx.txt @@ -15,7 +15,7 @@ Pygments==2.15.1 pytz==2023.3 requests==2.31.0 snowballstemmer==2.2.0 -Sphinx==7.0.1 +Sphinx==7.1.1 sphinxcontrib-applehelp==1.0.4 sphinxcontrib-devhelp==1.0.2 sphinxcontrib-htmlhelp==2.0.1 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 9b99a577a..25fc4a334 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -23,7 +23,7 @@ jaraco.functools==3.8.0 Mako==1.2.4 manhole==1.8.0 # MarkupSafe==2.1.3 -more-itertools==9.1.0 +more-itertools==10.0.0 packaging==23.1 parse==1.19.1 parse-type==0.6.2 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index a4c7c4948..7341a88d3 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -7,11 +7,11 @@ distlib==0.3.7 filelock==3.12.2 packaging==23.1 pip==23.2.1 -platformdirs==3.9.1 +platformdirs==3.10.0 pluggy==1.2.0 pyproject-api==1.5.3 setuptools==68.0.0 tomli==2.0.1 tox==4.6.4 -virtualenv==20.24.1 +virtualenv==20.24.2 wheel==0.41.0 diff --git a/misc/requirements/requirements-yamllint.txt b/misc/requirements/requirements-yamllint.txt index a35c0ff58..fd9ea256f 100644 --- a/misc/requirements/requirements-yamllint.txt +++ b/misc/requirements/requirements-yamllint.txt @@ -1,5 +1,5 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -pathspec==0.11.1 +pathspec==0.11.2 PyYAML==6.0.1 yamllint==1.32.0 -- cgit v1.2.3-54-g00ecf From 36abc475d445c9878b566cc06c12e00da92464bb Mon Sep 17 00:00:00 2001 From: toofar Date: Wed, 2 Aug 2023 20:45:03 +1200 Subject: fix lint Seems the new flake8 release is pulling down a (somewhat) new pycodestyle that prefers is/is not over ==/!= when comparing exact types. They should behave the same. ref: #7807 --- tests/helpers/testutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/helpers/testutils.py b/tests/helpers/testutils.py index f6d7fcc4b..dc6fdac32 100644 --- a/tests/helpers/testutils.py +++ b/tests/helpers/testutils.py @@ -150,7 +150,7 @@ def partial_compare(val1, val2, *, indent=0): if val2 is Ellipsis: print_i("Ignoring ellipsis comparison", indent, error=True) return PartialCompareOutcome() - elif type(val1) != type(val2): # pylint: disable=unidiomatic-typecheck + elif type(val1) is not type(val2): outcome = PartialCompareOutcome( "Different types ({}, {}) -> False".format(type(val1).__name__, type(val2).__name__)) -- cgit v1.2.3-54-g00ecf From fc91c976d36ebe285315d90d4d518321813044d3 Mon Sep 17 00:00:00 2001 From: toofar Date: Wed, 2 Aug 2023 20:55:51 +1200 Subject: manual update of cryptography (and rich) When handling the automated dependancy update PR GH warned on push of a low priority security issue with cryptography. So updating that now. Rich has an update available too. ref: https://github.com/qutebrowser/qutebrowser/security/dependabot/32 ref: #7807 --- misc/requirements/requirements-dev.txt | 4 ++-- misc/requirements/requirements-pylint.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index 03ee37edf..c749ca345 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -6,7 +6,7 @@ bump2version==1.0.1 certifi==2023.7.22 cffi==1.15.1 charset-normalizer==3.2.0 -cryptography==41.0.2 +cryptography==41.0.3 docutils==0.20.1 github3.py==4.0.1 hunter==3.6.1 @@ -34,7 +34,7 @@ readme-renderer==40.0 requests==2.31.0 requests-toolbelt==1.0.0 rfc3986==2.0.0 -rich==13.5.0 +rich==13.5.2 SecretStorage==3.3.3 sip==6.7.10 six==1.16.0 diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt index 4975a725e..cd09e4bf2 100644 --- a/misc/requirements/requirements-pylint.txt +++ b/misc/requirements/requirements-pylint.txt @@ -4,7 +4,7 @@ astroid==2.15.6 certifi==2023.7.22 cffi==1.15.1 charset-normalizer==3.2.0 -cryptography==41.0.2 +cryptography==41.0.3 dill==0.3.7 github3.py==4.0.1 idna==3.4 -- cgit v1.2.3-54-g00ecf From 9f5df2071ffe11519420982ff3ab31c984dcf406 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 6 Aug 2023 00:02:47 +0200 Subject: doc: Update related projects list --- README.asciidoc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index 910a6b987..2b6bdfdd6 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -220,6 +220,7 @@ Active * 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) +* https://github.com/jun7/wyeb[wyeb] (C, GTK+ with WebKit2) * Chrome/Chromium addons: https://vimium.github.io/[Vimium] * Firefox addons (based on WebExtensions): @@ -227,9 +228,8 @@ Active https://addons.mozilla.org/en-GB/firefox/addon/vimium-ff/[Vimium-FF] * Addons for Firefox and Chrome: https://github.com/brookhong/Surfingkeys[Surfingkeys], - https://lydell.github.io/LinkHints/[Link Hints] (hinting only) -* Addons for Safari: - https://televator.net/vimari/[Vimari] + https://lydell.github.io/LinkHints/[Link Hints] (hinting only), + https://github.com/ueokande/vimmatic[Vimmatic] Inactive ~~~~~~~~ @@ -246,7 +246,6 @@ main inspiration for qutebrowser) * 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], @@ -263,6 +262,8 @@ main inspiration for qutebrowser) 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] +* Addons for Safari: + https://televator.net/vimari/[Vimari] License ------- -- cgit v1.2.3-54-g00ecf From 38223ecb404eb0352a87388059062cfa17126556 Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 7 Aug 2023 04:22:49 +0000 Subject: Update dependencies --- misc/requirements/requirements-dev.txt | 6 +++--- misc/requirements/requirements-mypy.txt | 6 +++--- misc/requirements/requirements-pyroma.txt | 2 +- misc/requirements/requirements-sphinx.txt | 4 ++-- misc/requirements/requirements-tests.txt | 8 ++++---- misc/requirements/requirements-tox.txt | 4 ++-- requirements.txt | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index c749ca345..c9590f1c5 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -19,12 +19,12 @@ keyring==24.2.0 manhole==1.8.0 markdown-it-py==3.0.0 mdurl==0.1.2 -more-itertools==10.0.0 +more-itertools==10.1.0 packaging==23.1 pkginfo==1.9.6 ply==3.11 pycparser==2.21 -Pygments==2.15.1 +Pygments==2.16.1 PyJWT==2.8.0 Pympler==1.0.1 pyproject_hooks==1.0.0 @@ -36,7 +36,7 @@ requests-toolbelt==1.0.0 rfc3986==2.0.0 rich==13.5.2 SecretStorage==3.3.3 -sip==6.7.10 +sip==6.7.11 six==1.16.0 tomli==2.0.1 twine==4.0.2 diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt index a47f25d3f..1e18a7ab2 100644 --- a/misc/requirements/requirements-mypy.txt +++ b/misc/requirements/requirements-mypy.txt @@ -1,6 +1,6 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -chardet==5.1.0 +chardet==5.2.0 diff-cover==7.7.0 importlib-resources==6.0.0 Jinja2==3.1.2 @@ -9,12 +9,12 @@ MarkupSafe==2.1.3 mypy==1.4.1 mypy-extensions==1.0.0 pluggy==1.2.0 -Pygments==2.15.1 +Pygments==2.16.1 PyQt5-stubs==5.15.6.0 tomli==2.0.1 types-colorama==0.4.15.12 types-docutils==0.20.0.1 -types-Pygments==2.15.0.2 +types-Pygments==2.16.0.0 types-PyYAML==6.0.12.11 types-setuptools==68.0.0.3 typing_extensions==4.7.1 diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt index 50078baeb..f574b4c26 100644 --- a/misc/requirements/requirements-pyroma.txt +++ b/misc/requirements/requirements-pyroma.txt @@ -6,7 +6,7 @@ charset-normalizer==3.2.0 docutils==0.20.1 idna==3.4 packaging==23.1 -Pygments==2.15.1 +Pygments==2.16.1 pyproject_hooks==1.0.0 pyroma==4.2 requests==2.31.0 diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt index fda124301..3557eab6c 100644 --- a/misc/requirements/requirements-sphinx.txt +++ b/misc/requirements/requirements-sphinx.txt @@ -11,11 +11,11 @@ importlib-metadata==6.8.0 Jinja2==3.1.2 MarkupSafe==2.1.3 packaging==23.1 -Pygments==2.15.1 +Pygments==2.16.1 pytz==2023.3 requests==2.31.0 snowballstemmer==2.2.0 -Sphinx==7.1.1 +Sphinx==7.1.2 sphinxcontrib-applehelp==1.0.4 sphinxcontrib-devhelp==1.0.2 sphinxcontrib-htmlhelp==2.0.1 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 25fc4a334..abd6ea727 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -13,23 +13,23 @@ execnet==2.0.2 filelock==3.12.2 Flask==2.3.2 hunter==3.6.1 -hypothesis==6.82.0 +hypothesis==6.82.2 idna==3.4 importlib-metadata==6.8.0 iniconfig==2.0.0 itsdangerous==2.1.2 -jaraco.functools==3.8.0 +jaraco.functools==3.8.1 # Jinja2==3.1.2 Mako==1.2.4 manhole==1.8.0 # MarkupSafe==2.1.3 -more-itertools==10.0.0 +more-itertools==10.1.0 packaging==23.1 parse==1.19.1 parse-type==0.6.2 pluggy==1.2.0 py-cpuinfo==9.0.0 -Pygments==2.15.1 +Pygments==2.16.1 pytest==7.4.0 pytest-bdd==6.1.1 pytest-benchmark==4.0.0 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index 7341a88d3..ae8fce6ff 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py cachetools==5.3.1 -chardet==5.1.0 +chardet==5.2.0 colorama==0.4.6 distlib==0.3.7 filelock==3.12.2 @@ -14,4 +14,4 @@ setuptools==68.0.0 tomli==2.0.1 tox==4.6.4 virtualenv==20.24.2 -wheel==0.41.0 +wheel==0.41.1 diff --git a/requirements.txt b/requirements.txt index b5bab3296..f10ab6f9b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ colorama==0.4.6 importlib-resources==6.0.0 ; python_version=="3.8.*" Jinja2==3.1.2 MarkupSafe==2.1.3 -Pygments==2.15.1 +Pygments==2.16.1 PyYAML==6.0.1 zipp==3.16.2 # Unpinned due to recompile_requirements.py limitations -- cgit v1.2.3-54-g00ecf From b5f71d2b503f015102d31b19b4e7535c95900168 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 7 Aug 2023 12:17:26 +0200 Subject: notifications: Don't complain on upgraded server spec version If a server gets fixed and now advertises spec 1.2, there is no reason we should complain about things. See https://github.com/phuhl/linux_notification_center/commit/5427acd551ce6dc4c74bdf8090904c6d254b74f1 --- doc/changelog.asciidoc | 1 + qutebrowser/browser/webengine/notification.py | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 2006b4ab4..d48e51e0d 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -202,6 +202,7 @@ Fixed - Crash when using QtWebKit with PAC and the file has an invalid encoding. - Crash with the "tiramisu" notification server. - Crash when the "herbe" notification presenter doesn't start correctly. +- Warning with recent versions of the "deadd" (aka "linux notification center") notification server. - Crash when using `:print --pdf` with a directory where its parent directory did not exist. - The `PyQt{5,6}.sip` version is now shown correctly in the :version|--version diff --git a/qutebrowser/browser/webengine/notification.py b/qutebrowser/browser/webengine/notification.py index 2edb2d538..6cc9cc074 100644 --- a/qutebrowser/browser/webengine/notification.py +++ b/qutebrowser/browser/webengine/notification.py @@ -856,12 +856,15 @@ class DBusNotificationAdapter(AbstractNotificationAdapter): log.misc.debug(f"Enabling quirks {quirks}") self._quirks = quirks - expected_spec_version = self._quirks.spec_version or self.SPEC_VERSION - if spec_version != expected_spec_version: + expected_spec_versions = [self.SPEC_VERSION] + if self._quirks.spec_version is not None: + expected_spec_versions.append(self._quirks.spec_version) + + if spec_version not in expected_spec_versions: log.misc.warning( f"Notification server ({name} {ver} by {vendor}) implements " - f"spec {spec_version}, but {expected_spec_version} was expected. " - f"If {name} is up to date, please report a qutebrowser bug.") + f"spec {spec_version}, but {'/'.join(expected_spec_versions)} was " + f"expected. If {name} is up to date, please report a qutebrowser bug.") # https://specifications.freedesktop.org/notification-spec/latest/ar01s08.html icon_key_overrides = { -- cgit v1.2.3-54-g00ecf From 585c4fbaa9ad92ac94b312880681397257ebea4f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Aug 2023 14:18:24 +0200 Subject: interceptor: Make sure redirect target URL is valid Catches issues with invalid URLs early instead of later in the code (e.g. when the brave adblocker runs on the URL). Hopefully helps catch issues with broken config.py hacks calling redirect(). --- qutebrowser/browser/webengine/interceptor.py | 7 +- .../browser/webengine/test_webengineinterceptor.py | 98 ++++++++++++++++++++-- 2 files changed, 99 insertions(+), 6 deletions(-) diff --git a/qutebrowser/browser/webengine/interceptor.py b/qutebrowser/browser/webengine/interceptor.py index ac0795803..161f5ffab 100644 --- a/qutebrowser/browser/webengine/interceptor.py +++ b/qutebrowser/browser/webengine/interceptor.py @@ -10,7 +10,7 @@ from qutebrowser.qt.webenginecore import (QWebEngineUrlRequestInterceptor, from qutebrowser.config import websettings, config from qutebrowser.browser import shared -from qutebrowser.utils import debug, log +from qutebrowser.utils import debug, log, qtutils from qutebrowser.extensions import interceptors from qutebrowser.misc import objects @@ -35,6 +35,11 @@ class WebEngineRequest(interceptors.Request): if self._webengine_info is None: raise interceptors.RedirectException("Request improperly initialized.") + try: + qtutils.ensure_valid(url) + except qtutils.QtValueError as e: + raise interceptors.RedirectException(f"Redirect to invalid URL: {e}") + # Redirecting a request that contains payload data is not allowed. # To be safe, abort on any request not in a whitelist. verb = self._webengine_info.requestMethod() diff --git a/tests/unit/browser/webengine/test_webengineinterceptor.py b/tests/unit/browser/webengine/test_webengineinterceptor.py index d579d60f7..506e65284 100644 --- a/tests/unit/browser/webengine/test_webengineinterceptor.py +++ b/tests/unit/browser/webengine/test_webengineinterceptor.py @@ -6,12 +6,15 @@ import pytest +import pytest_mock -pytest.importorskip('qutebrowser.qt.webenginecore') +pytest.importorskip("qutebrowser.qt.webenginecore") +from qutebrowser.qt.core import QUrl, QByteArray from qutebrowser.qt.webenginecore import QWebEngineUrlRequestInfo from qutebrowser.browser.webengine import interceptor +from qutebrowser.extensions import interceptors from qutebrowser.utils import qtutils from helpers import testutils @@ -19,10 +22,12 @@ from helpers import testutils def test_no_missing_resource_types(): request_interceptor = interceptor.RequestInterceptor() qb_keys = set(request_interceptor._resource_types.keys()) - qt_keys = set(testutils.enum_members( - QWebEngineUrlRequestInfo, - QWebEngineUrlRequestInfo.ResourceType, - ).values()) + qt_keys = set( + testutils.enum_members( + QWebEngineUrlRequestInfo, + QWebEngineUrlRequestInfo.ResourceType, + ).values() + ) assert qt_keys == qb_keys @@ -30,3 +35,86 @@ def test_resource_type_values(): request_interceptor = interceptor.RequestInterceptor() for qt_value, qb_item in request_interceptor._resource_types.items(): assert qtutils.extract_enum_val(qt_value) == qb_item.value + + +@pytest.fixture +def we_request( # a shrubbery! + mocker: pytest_mock.MockerFixture, +) -> interceptor.WebEngineRequest: + qt_info = mocker.Mock(spec=QWebEngineUrlRequestInfo) + qt_info.requestMethod.return_value = QByteArray(b"GET") + first_party_url = QUrl("https://firstparty.example.org/") + request_url = QUrl("https://request.example.org/") + return interceptor.WebEngineRequest( + first_party_url=first_party_url, + request_url=request_url, + webengine_info=qt_info, + ) + + +def test_block(we_request: interceptor.WebEngineRequest): + assert not we_request.is_blocked + we_request.block() + assert we_request.is_blocked + + +class TestRedirect: + + REDIRECT_URL = QUrl("https://redirect.example.com/") + + def test_redirect(self, we_request: interceptor.WebEngineRequest): + assert not we_request._redirected + we_request.redirect(self.REDIRECT_URL) + assert we_request._redirected + we_request._webengine_info.redirect.assert_called_once_with(self.REDIRECT_URL) + + + def test_twice(self, we_request: interceptor.WebEngineRequest): + we_request.redirect(self.REDIRECT_URL) + with pytest.raises( + interceptors.RedirectException, + match=r"Request already redirected.", + ): + we_request.redirect(self.REDIRECT_URL) + we_request._webengine_info.redirect.assert_called_once_with(self.REDIRECT_URL) + + + def test_invalid_method(self, we_request: interceptor.WebEngineRequest): + we_request._webengine_info.requestMethod.return_value = QByteArray(b"POST") + with pytest.raises( + interceptors.RedirectException, + match=( + r"Request method b'POST' for https://request.example.org/ does not " + r"support redirection." + ), + ): + we_request.redirect(self.REDIRECT_URL) + assert not we_request._webengine_info.redirect.called + + + def test_invalid_method_ignore_unsupported(self, we_request: interceptor.WebEngineRequest, caplog: pytest.LogCaptureFixture): + we_request._webengine_info.requestMethod.return_value = QByteArray(b"POST") + we_request.redirect(self.REDIRECT_URL, ignore_unsupported=True) + assert caplog.messages == [ + "Request method b'POST' for https://request.example.org/ does not support " + "redirection." + ] + assert not we_request._webengine_info.redirect.called + + + def test_improperly_initialized(self, we_request: interceptor.WebEngineRequest): + we_request._webengine_info = None + with pytest.raises( + interceptors.RedirectException, + match=r"Request improperly initialized.", + ): + we_request.redirect(self.REDIRECT_URL) + + def test_invalid_url(self, we_request: interceptor.WebEngineRequest): + url = QUrl() + assert not url.isValid() + with pytest.raises( + interceptors.RedirectException, + match=r"Redirect to invalid URL: PyQt6\.QtCore\.QUrl\(''\) is not valid", + ): + we_request.redirect(url) -- cgit v1.2.3-54-g00ecf From 346819b2945a8ae0e63c7ac0a28428faf79aad43 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Aug 2023 14:36:48 +0200 Subject: notifications: Handle org.freedesktop.DBus.Error.ServiceUnknown --- doc/changelog.asciidoc | 4 ++++ qutebrowser/browser/webengine/notification.py | 3 +++ 2 files changed, 7 insertions(+) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index d48e51e0d..b2b392a4c 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -202,12 +202,16 @@ Fixed - Crash when using QtWebKit with PAC and the file has an invalid encoding. - Crash with the "tiramisu" notification server. - Crash when the "herbe" notification presenter doesn't start correctly. +- Crash when no notification server is installed/available. - Warning with recent versions of the "deadd" (aka "linux notification center") notification server. - Crash when using `:print --pdf` with a directory where its parent directory did not exist. - The `PyQt{5,6}.sip` version is now shown correctly in the :version|--version output. Previously that showed the version from the standalone `sip` module which was only set for PyQt5. (#7805) +- When a `config.py` calls `.redirect()` via a request interceptor (which is + unsupported) and supplies an invalid redirect target URL, an exception is now + raised for the `.redirect()` call instead of later inside qutebrowser. [[v2.5.4]] v2.5.4 (2023-03-13) diff --git a/qutebrowser/browser/webengine/notification.py b/qutebrowser/browser/webengine/notification.py index 6cc9cc074..e8b2e27f1 100644 --- a/qutebrowser/browser/webengine/notification.py +++ b/qutebrowser/browser/webengine/notification.py @@ -113,6 +113,9 @@ class DBusError(Error): # https://crashes.qutebrowser.org/view/de62220a # after "Notification daemon did quit!" "org.freedesktop.DBus.Error.UnknownObject", + + # notmuch-sha1-ef7b6e9e79e5f2f6cba90224122288895c1fe0d8 + "org.freedesktop.DBus.Error.ServiceUnknown", } def __init__(self, msg: QDBusMessage) -> None: -- cgit v1.2.3-54-g00ecf From a1af49e252df11f9227088157df2ce3af1fdebba Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Aug 2023 15:08:00 +0200 Subject: Fix lint/tests --- tests/unit/browser/webengine/test_webengineinterceptor.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/unit/browser/webengine/test_webengineinterceptor.py b/tests/unit/browser/webengine/test_webengineinterceptor.py index 506e65284..099ba69d7 100644 --- a/tests/unit/browser/webengine/test_webengineinterceptor.py +++ b/tests/unit/browser/webengine/test_webengineinterceptor.py @@ -59,7 +59,6 @@ def test_block(we_request: interceptor.WebEngineRequest): class TestRedirect: - REDIRECT_URL = QUrl("https://redirect.example.com/") def test_redirect(self, we_request: interceptor.WebEngineRequest): @@ -68,7 +67,6 @@ class TestRedirect: assert we_request._redirected we_request._webengine_info.redirect.assert_called_once_with(self.REDIRECT_URL) - def test_twice(self, we_request: interceptor.WebEngineRequest): we_request.redirect(self.REDIRECT_URL) with pytest.raises( @@ -78,7 +76,6 @@ class TestRedirect: we_request.redirect(self.REDIRECT_URL) we_request._webengine_info.redirect.assert_called_once_with(self.REDIRECT_URL) - def test_invalid_method(self, we_request: interceptor.WebEngineRequest): we_request._webengine_info.requestMethod.return_value = QByteArray(b"POST") with pytest.raises( @@ -91,8 +88,11 @@ class TestRedirect: we_request.redirect(self.REDIRECT_URL) assert not we_request._webengine_info.redirect.called - - def test_invalid_method_ignore_unsupported(self, we_request: interceptor.WebEngineRequest, caplog: pytest.LogCaptureFixture): + def test_invalid_method_ignore_unsupported( + self, + we_request: interceptor.WebEngineRequest, + caplog: pytest.LogCaptureFixture, + ): we_request._webengine_info.requestMethod.return_value = QByteArray(b"POST") we_request.redirect(self.REDIRECT_URL, ignore_unsupported=True) assert caplog.messages == [ @@ -101,7 +101,6 @@ class TestRedirect: ] assert not we_request._webengine_info.redirect.called - def test_improperly_initialized(self, we_request: interceptor.WebEngineRequest): we_request._webengine_info = None with pytest.raises( @@ -115,6 +114,6 @@ class TestRedirect: assert not url.isValid() with pytest.raises( interceptors.RedirectException, - match=r"Redirect to invalid URL: PyQt6\.QtCore\.QUrl\(''\) is not valid", + match=r"Redirect to invalid URL: PyQt\d\.QtCore\.QUrl\(''\) is not valid", ): we_request.redirect(url) -- cgit v1.2.3-54-g00ecf From 89b91105022be0216d8fb323b20fd15e1391af28 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Aug 2023 17:16:47 +0200 Subject: Prevent setting giant window titles See #7801 --- qutebrowser/mainwindow/tabbedbrowser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py index 85f683133..98cb67cb2 100644 --- a/qutebrowser/mainwindow/tabbedbrowser.py +++ b/qutebrowser/mainwindow/tabbedbrowser.py @@ -316,6 +316,8 @@ class TabbedBrowser(QWidget): fields['id'] = self._win_id title = title_format.format(**fields) + # prevent hanging WMs and similar issues with giant URLs + title = utils.elide(title, 1024) self._window().setWindowTitle(title) -- cgit v1.2.3-54-g00ecf From 1976f1acdd99a1f904b77d6a90e49bcd74bc587f Mon Sep 17 00:00:00 2001 From: Philipp Albrecht Date: Sun, 23 Jul 2023 18:04:31 +0200 Subject: Add package job to tox.ini This is still *very* basic, but it serves its purpose of failing for warnings during package build. I verified that `tox -e package` is failing by introducing some warnings with this change: ```diff diff --git a/setup.py b/setup.py index feb949595..6810eaf1e 100755 --- a/setup.py +++ b/setup.py @@ -51,8 +51,7 @@ def _get_constant(name): try: common.write_git_file() setuptools.setup( - packages=setuptools.find_namespace_packages(include=['qutebrowser', - 'qutebrowser.*']), + packages=setuptools.find_namespace_packages(include=['qutebrowser']), include_package_data=True, entry_points={'gui_scripts': ['qutebrowser = qutebrowser.qutebrowser:main']}, ``` --- tox.ini | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tox.ini b/tox.ini index 7616cac38..83cf8fb1d 100644 --- a/tox.ini +++ b/tox.ini @@ -280,3 +280,13 @@ deps = commands = !qt5: {envpython} {toxinidir}/scripts/dev/build_release.py {posargs} qt5: {envpython} {toxinidir}/scripts/dev/build_release.py --qt5 {posargs} + +[testenv:package] +basepython = {env:PYTHON:python3} +setenv = + PYTHONWARNINGS=error + VIRTUALENV_PIP=23.2 +deps = + -r{toxinidir}/requirements.txt + -r{toxinidir}/misc/requirements/requirements-dev.txt +commands = {envpython} -m build -- cgit v1.2.3-54-g00ecf From 7d445e6617db061a5755561ea1023c09bcb3ee77 Mon Sep 17 00:00:00 2001 From: Philipp Albrecht Date: Mon, 24 Jul 2023 13:20:17 +0200 Subject: Add CI job for package build We want to run a package build in CI with warnings turned into exceptions, in order to catch issues in CI (e.g. DeprecationWarning). --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1612a4eb..14d642491 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,7 @@ jobs: args: "-f gcc" # For problem matchers - testenv: yamllint - testenv: actionlint + - testenv: package steps: - uses: actions/checkout@v3 with: -- cgit v1.2.3-54-g00ecf From e20bba8d91ffe450a855e4e75612bc6683327a36 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 25 Jul 2023 16:26:37 +0200 Subject: Don't fail on weird pip warning We got a `DeprecationWarning` during the package build, which we were not able to reproduce locally. For now we just don't turn this particular `DeprecationWarning` into an exception to not fail CI. --- tox.ini | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 83cf8fb1d..4f5bd56e7 100644 --- a/tox.ini +++ b/tox.ini @@ -284,8 +284,7 @@ commands = [testenv:package] basepython = {env:PYTHON:python3} setenv = - PYTHONWARNINGS=error - VIRTUALENV_PIP=23.2 + PYTHONWARNINGS=error,default:pkg_resources is deprecated as an API.:DeprecationWarning deps = -r{toxinidir}/requirements.txt -r{toxinidir}/misc/requirements/requirements-dev.txt -- cgit v1.2.3-54-g00ecf From b7a470025da53e03ff52da712b18fdd0cc20acf7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Aug 2023 12:03:52 +0200 Subject: mypy: Improve typing for cmdutils/qute_args See https://github.com/python/mypy/issues/2087 --- qutebrowser/api/cmdutils.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/qutebrowser/api/cmdutils.py b/qutebrowser/api/cmdutils.py index 067ebca92..0c367c6bf 100644 --- a/qutebrowser/api/cmdutils.py +++ b/qutebrowser/api/cmdutils.py @@ -35,7 +35,7 @@ Possible values: import inspect -from typing import Any, Callable, Iterable +from typing import Any, Callable, Iterable, Protocol, Optional, Dict, cast from qutebrowser.utils import qtutils from qutebrowser.commands import command, cmdexc @@ -90,7 +90,21 @@ def check_exclusive(flags: Iterable[bool], names: Iterable[str]) -> None: raise CommandError("Only one of {} can be given!".format(argstr)) -_CmdHandlerType = Callable[..., Any] +_CmdHandlerFunc = Callable[..., Any] + + +class _CmdHandlerType(Protocol): + + """A qutebrowser command function, which had qute_args patched on it. + + Applying @cmdutils.argument to a function will patch it with a qute_args attribute. + Below, we cast the decorated function to _CmdHandlerType to make mypy aware of this. + """ + + qute_args: Optional[Dict[str, command.ArgInfo]] + + def __call__(self, *args: Any, **kwargs: Any) -> Any: + ... class register: # noqa: N801,N806 pylint: disable=invalid-name @@ -118,7 +132,7 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name # The arguments to pass to Command. self._kwargs = kwargs - def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType: + def __call__(self, func: _CmdHandlerFunc) -> _CmdHandlerType: """Register the command before running the function. Gets called when a function should be decorated. @@ -158,7 +172,8 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name # This is checked by future @cmdutils.argument calls so they fail # (as they'd be silently ignored otherwise) - func.qute_args = None # type: ignore[attr-defined] + func = cast(_CmdHandlerType, func) + func.qute_args = None return func @@ -210,19 +225,21 @@ class argument: # noqa: N801,N806 pylint: disable=invalid-name self._argname = argname # The name of the argument to handle. self._kwargs = kwargs # Valid ArgInfo members. - def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType: + def __call__(self, func: _CmdHandlerFunc) -> _CmdHandlerType: funcname = func.__name__ if self._argname not in inspect.signature(func).parameters: raise ValueError("{} has no argument {}!".format(funcname, self._argname)) + + func = cast(_CmdHandlerType, func) if not hasattr(func, 'qute_args'): - func.qute_args = {} # type: ignore[attr-defined] + func.qute_args = {} elif func.qute_args is None: raise ValueError("@cmdutils.argument got called above (after) " "@cmdutils.register for {}!".format(funcname)) arginfo = command.ArgInfo(**self._kwargs) - func.qute_args[self._argname] = arginfo # type: ignore[attr-defined] + func.qute_args[self._argname] = arginfo return func -- cgit v1.2.3-54-g00ecf From 9e21e2e86bee5b0de42fe28153dd1bcb0aa51d27 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Aug 2023 13:23:33 +0200 Subject: tests: Handle PermissionError for waitpid in test_restart While not documented that way: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/cwait?view=msvc-170 It looks like that Windows sometimes sets errno to EACCES here (causing a PermissionError): > os.waitpid(pid, 0) # pid, options... positional-only :( E PermissionError: [Errno 13] Permission denied I have no idea why it happens, but it results in flaky tests on CI. We aren't particularly interested in this (we just want to make sure the process is cleaned up before the next test runs...), so let's just ignore this. --- tests/end2end/test_invocations.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index e31aa3ecb..af81781f6 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -937,6 +937,7 @@ def test_restart(request, quteproc_new): # If the new process hangs, this will hang too. # Still better than just ignoring it, so we can fix it if something is broken. os.waitpid(pid, 0) # pid, options... positional-only :( - except ChildProcessError: - # Already gone + except (ChildProcessError, PermissionError): + # Already gone. Even if not documented, Windows seems to raise PermissionError + # here... pass -- cgit v1.2.3-54-g00ecf From 0b200207dd01d1e6e806ce4e6b91cb4327437d6b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Aug 2023 14:27:39 +0200 Subject: Add --all to :{quick,book}mark-del Needed mostly for urlmarks BDD tests so they can clear things between tests. Hopefully with --all, this won't be accidentally triggered by users. Preparation for #7815 --- doc/changelog.asciidoc | 2 ++ doc/help/commands.asciidoc | 10 ++++++++-- qutebrowser/browser/commands.py | 24 +++++++++++++++++++++--- qutebrowser/browser/urlmarks.py | 5 +++++ tests/end2end/features/test_urlmarks_bdd.py | 9 +++++++++ tests/end2end/features/urlmarks.feature | 29 +++++++++++++++++++++++++++++ 6 files changed, 74 insertions(+), 5 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index b2b392a4c..5deb381f7 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -67,6 +67,8 @@ Added - New `colors.webpage.darkmode.increase_text_contrast` setting for Qt 6.3+ - New `fonts.tooltip`, `colors.tooltip.bg` and `colors.tooltip.fg` settings. - New `log-qt-events` debug flag for `-D` +- New `--all` flags for `:bookmark-del` and `:quickmark-del` to delete all + quickmarks/bookmarks. Removed ~~~~~~~ diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 7f0abc71d..6577a9ddf 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -204,7 +204,7 @@ If no url and title are provided, then save the current page as a bookmark. If a [[bookmark-del]] === bookmark-del -Syntax: +:bookmark-del ['url']+ +Syntax: +:bookmark-del [*--all*] ['url']+ Delete a bookmark. @@ -212,6 +212,9 @@ Delete a bookmark. * +'url'+: The url of the bookmark to delete. If not given, use the current page's url. +==== optional arguments +* +*-a*+, +*--all*+: If given, delete all bookmarks. + ==== note * This command does not split arguments after the last argument and handles quotes literally. @@ -998,7 +1001,7 @@ You can view all saved quickmarks on the link:qute://bookmarks[bookmarks page]. [[quickmark-del]] === quickmark-del -Syntax: +:quickmark-del ['name']+ +Syntax: +:quickmark-del [*--all*] ['name']+ Delete a quickmark. @@ -1007,6 +1010,9 @@ Delete a quickmark. if there are more than one). +==== optional arguments +* +*-a*+, +*--all*+: Delete all quickmarks. + ==== note * This command does not split arguments after the last argument and handles quotes literally. diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 7efb69511..2889b630c 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1235,21 +1235,30 @@ class CommandDispatcher: @cmdutils.register(instance='command-dispatcher', scope='window', maxsplit=0) @cmdutils.argument('name', completion=miscmodels.quickmark) - def quickmark_del(self, name=None): + def quickmark_del(self, name=None, all_=False): """Delete a quickmark. Args: name: The name of the quickmark to delete. If not given, delete the quickmark for the current page (choosing one arbitrarily if there are more than one). + all_: Delete all quickmarks. """ quickmark_manager = objreg.get('quickmark-manager') + + if all_: + if name is not None: + raise cmdutils.CommandError("Cannot specify name and --all") + quickmark_manager.clear() + return + if name is None: url = self._current_url() try: name = quickmark_manager.get_by_qurl(url) except urlmarks.DoesNotExistError as e: raise cmdutils.CommandError(str(e)) + try: quickmark_manager.delete(name) except KeyError: @@ -1320,18 +1329,27 @@ class CommandDispatcher: @cmdutils.register(instance='command-dispatcher', scope='window', maxsplit=0) @cmdutils.argument('url', completion=miscmodels.bookmark) - def bookmark_del(self, url=None): + def bookmark_del(self, url=None, all_=False): """Delete a bookmark. Args: url: The url of the bookmark to delete. If not given, use the current page's url. + all_: If given, delete all bookmarks. """ + bookmark_manager = objreg.get('bookmark-manager') + if all_: + if url is not None: + raise cmdutils.CommandError("Cannot specify url and --all") + bookmark_manager.clear() + return + if url is None: url = self._current_url().toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded) + try: - objreg.get('bookmark-manager').delete(url) + bookmark_manager.delete(url) except KeyError: raise cmdutils.CommandError("Bookmark '{}' not found!".format(url)) message.info("Removed bookmark {}".format(url)) diff --git a/qutebrowser/browser/urlmarks.py b/qutebrowser/browser/urlmarks.py index 2a060f5ef..2d2563a1a 100644 --- a/qutebrowser/browser/urlmarks.py +++ b/qutebrowser/browser/urlmarks.py @@ -98,6 +98,11 @@ class UrlMarkManager(QObject): del self.marks[key] self.changed.emit() + def clear(self): + """Delete all marks.""" + self.marks.clear() + self.changed.emit() + class QuickmarkManager(UrlMarkManager): diff --git a/tests/end2end/features/test_urlmarks_bdd.py b/tests/end2end/features/test_urlmarks_bdd.py index 1b21098cd..6d4172085 100644 --- a/tests/end2end/features/test_urlmarks_bdd.py +++ b/tests/end2end/features/test_urlmarks_bdd.py @@ -4,6 +4,7 @@ import os.path +import pytest import pytest_bdd as bdd from helpers import testutils @@ -11,6 +12,14 @@ from helpers import testutils bdd.scenarios('urlmarks.feature') +@pytest.fixture(autouse=True) +def clear_marks(quteproc): + """Clear all existing marks between tests.""" + yield + quteproc.send_cmd(':quickmark-del --all') + quteproc.send_cmd(':bookmark-del --all') + + def _check_marks(quteproc, quickmarks, expected, contains): """Make sure the given line does (not) exist in the bookmarks. diff --git a/tests/end2end/features/urlmarks.feature b/tests/end2end/features/urlmarks.feature index 00fd14fb6..e8f4a9e77 100644 --- a/tests/end2end/features/urlmarks.feature +++ b/tests/end2end/features/urlmarks.feature @@ -86,6 +86,22 @@ Feature: quickmarks and bookmarks And I run :bookmark-del http://localhost:(port)/data/numbers/5.txt Then the bookmark file should not contain "http://localhost:*/data/numbers/5.txt " + Scenario: Deleting all bookmarks + When I open data/numbers/1.txt + And I run :bookmark-add + And I open data/numbers/2.txt + And I run :bookmark-add + And I run :bookmark-del --all + Then the bookmark file should not contain "http://localhost:*/data/numbers/1.txt" + And the bookmark file should not contain "http://localhost:*/data/numbers/2.txt" + + Scenario: Deleting all bookmarks with url + When I open data/numbers/1.txt + And I run :bookmark-add + And I run :bookmark-del --all https://example.org + Then the error "Cannot specify url and --all" should be shown + And the bookmark file should contain "http://localhost:*/data/numbers/1.txt" + Scenario: Deleting the current page's bookmark if it doesn't exist When I open data/hello.txt And I run :bookmark-del @@ -210,6 +226,19 @@ Feature: quickmarks and bookmarks And I run :quickmark-del eighteen Then the quickmark file should not contain "eighteen http://localhost:*/data/numbers/18.txt " + Scenario: Deleting all quickmarks + When I run :quickmark-add http://localhost:(port)/data/numbers/1.txt one + When I run :quickmark-add http://localhost:(port)/data/numbers/2.txt two + And I run :quickmark-del --all + Then the quickmark file should not contain "one http://localhost:*/data/numbers/1.txt" + And the quickmark file should not contain "two http://localhost:*/data/numbers/2.txt" + + Scenario: Deleting all quickmarks with name + When I run :quickmark-add http://localhost:(port)/data/numbers/1.txt one + And I run :quickmark-del --all invalid + Then the error "Cannot specify name and --all" should be shown + And the quickmark file should contain "one http://localhost:*/data/numbers/1.txt" + Scenario: Deleting the current page's quickmark if it has none When I open data/hello.txt And I run :quickmark-del -- cgit v1.2.3-54-g00ecf From 8defe1ae44c1c524e937ae08ed16052ee0724e0f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Aug 2023 15:28:28 +0200 Subject: Require user interaction for hints on qute:// pages With Qt 6.3+, user interaction is required to navigate outside of qute:// from a qute:// page. Fixes #7815 See #7220 - should be revisited once we have a qute-bookmarks:// instead where we can adjust permissions when registering the URL handler. --- qutebrowser/browser/webengine/webengineelem.py | 13 ++++++++++++- tests/end2end/features/urlmarks.feature | 7 +++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/webengine/webengineelem.py b/qutebrowser/browser/webengine/webengineelem.py index d383c1aa7..a0148148d 100644 --- a/qutebrowser/browser/webengine/webengineelem.py +++ b/qutebrowser/browser/webengine/webengineelem.py @@ -11,7 +11,7 @@ from qutebrowser.qt.core import QRect, QEventLoop from qutebrowser.qt.widgets import QApplication from qutebrowser.qt.webenginecore import QWebEngineSettings -from qutebrowser.utils import log, javascript, urlutils, usertypes, utils +from qutebrowser.utils import log, javascript, urlutils, usertypes, utils, version from qutebrowser.browser import webelem if TYPE_CHECKING: @@ -213,6 +213,17 @@ class WebEngineElement(webelem.AbstractWebElement): return True if baseurl.scheme() == url.scheme(): # e.g. a qute:// link return False + + # Qt 6.3+ needs an user interaction to allow navigations from qute:// to + # outside qute:// (like e.g. on qute://bookmarks). + versions = version.qtwebengine_versions() + if ( + baseurl.scheme() == "qute" and + url.scheme() != "qute" and + versions.webengine >= utils.VersionNumber(6, 3) + ): + return True + return url.scheme() not in urlutils.WEBENGINE_SCHEMES def _click_editable(self, click_target: usertypes.ClickTarget) -> None: diff --git a/tests/end2end/features/urlmarks.feature b/tests/end2end/features/urlmarks.feature index e8f4a9e77..65e6c051a 100644 --- a/tests/end2end/features/urlmarks.feature +++ b/tests/end2end/features/urlmarks.feature @@ -262,3 +262,10 @@ Feature: quickmarks and bookmarks And I run :bookmark-add And I open qute://bookmarks Then the page should contain the plaintext "Test title" + + Scenario: Following a bookmark + When I open data/numbers/1.txt in a new tab + And I run :bookmark-add + And I open qute://bookmarks + And I hint with args "links current" and follow a + Then data/numbers/1.txt should be loaded -- cgit v1.2.3-54-g00ecf From 216a9f9a9b7386823decf3c2c8a6124a86e2cad8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Aug 2023 16:32:24 +0200 Subject: Make qute://start search work with QtWebEngine 6.3+ Until we look at #7220 proper (thus splitting this into a qute-start:// which could probably have more permissions to do remote requests), we'll need to do with somewhat of a hack to allow this even if QtWebEngine does not. Given the very limited scope (only from qute://start, only opening the search engine URL, only with a form submitted request), this should be acceptable without compromsing security in any way. Fixes #7790 --- qutebrowser/browser/browsertab.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index b6cc303cf..82ef84a3d 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -30,7 +30,7 @@ if TYPE_CHECKING: from qutebrowser.keyinput import modeman from qutebrowser.config import config, websettings from qutebrowser.utils import (utils, objreg, usertypes, log, qtutils, - urlutils, message, jinja) + urlutils, message, jinja, version) from qutebrowser.misc import miscwidgets, objects, sessions from qutebrowser.browser import eventfilter, inspector from qutebrowser.qt import sip @@ -1169,6 +1169,23 @@ class AbstractTab(QWidget): navigation.url.errorString())) navigation.accepted = False + # WORKAROUND for QtWebEngine >= 6.3 not allowing form requests from + # qute:// to outside domains. + if ( + self.url() == QUrl("qute://start/") and + navigation.navigation_type == navigation.Type.form_submitted and + navigation.url.matches( + QUrl(config.val.url.searchengines['DEFAULT']), + QUrl.UrlFormattingOption.RemoveQuery) and + objects.backend == usertypes.Backend.QtWebEngine and + version.qtwebengine_versions().webengine >= utils.VersionNumber(6, 3) + ): + log.webview.debug( + "Working around qute://start loading issue for " + f"{navigation.url.toDisplayString()}") + navigation.accepted = False + self.load_url(navigation.url) + @pyqtSlot(bool) def _on_load_finished(self, ok: bool) -> None: assert self._widget is not None -- cgit v1.2.3-54-g00ecf From fc843f39440e10f918d57b86c7043658a48d7366 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Aug 2023 16:53:52 +0200 Subject: Fix lint/tests --- qutebrowser/browser/browsertab.py | 2 +- qutebrowser/browser/commands.py | 2 ++ qutebrowser/browser/webengine/webengineelem.py | 2 +- qutebrowser/utils/urlutils.py | 3 +++ tests/end2end/features/qutescheme.feature | 11 +++++++++++ tests/end2end/features/urlmarks.feature | 6 ++++-- 6 files changed, 22 insertions(+), 4 deletions(-) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 82ef84a3d..442628717 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -1176,7 +1176,7 @@ class AbstractTab(QWidget): navigation.navigation_type == navigation.Type.form_submitted and navigation.url.matches( QUrl(config.val.url.searchengines['DEFAULT']), - QUrl.UrlFormattingOption.RemoveQuery) and + urlutils.FormatOption.REMOVE_QUERY) and objects.backend == usertypes.Backend.QtWebEngine and version.qtwebengine_versions().webengine >= utils.VersionNumber(6, 3) ): diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 2889b630c..83a846b85 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1250,6 +1250,7 @@ class CommandDispatcher: if name is not None: raise cmdutils.CommandError("Cannot specify name and --all") quickmark_manager.clear() + message.info("Quickmarks cleared.") return if name is None: @@ -1342,6 +1343,7 @@ class CommandDispatcher: if url is not None: raise cmdutils.CommandError("Cannot specify url and --all") bookmark_manager.clear() + message.info("Bookmarks cleared.") return if url is None: diff --git a/qutebrowser/browser/webengine/webengineelem.py b/qutebrowser/browser/webengine/webengineelem.py index a0148148d..20c3a36d4 100644 --- a/qutebrowser/browser/webengine/webengineelem.py +++ b/qutebrowser/browser/webengine/webengineelem.py @@ -214,7 +214,7 @@ class WebEngineElement(webelem.AbstractWebElement): if baseurl.scheme() == url.scheme(): # e.g. a qute:// link return False - # Qt 6.3+ needs an user interaction to allow navigations from qute:// to + # Qt 6.3+ needs a user interaction to allow navigations from qute:// to # outside qute:// (like e.g. on qute://bookmarks). versions = version.qtwebengine_versions() if ( diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index c347ae53b..0b571946d 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -39,6 +39,7 @@ if machinery.IS_QT6: REMOVE_SCHEME = QUrl.UrlFormattingOption.RemoveScheme REMOVE_PASSWORD = QUrl.UrlFormattingOption.RemovePassword + REMOVE_QUERY = QUrl.UrlFormattingOption.RemoveQuery else: UrlFlagsType = Union[ QUrl.FormattingOptions, @@ -74,6 +75,8 @@ else: _QtFormattingOptions, QUrl.UrlFormattingOption.RemoveScheme) REMOVE_PASSWORD = cast( _QtFormattingOptions, QUrl.UrlFormattingOption.RemovePassword) + REMOVE_QUERY = cast( + _QtFormattingOptions, QUrl.UrlFormattingOption.RemoveQuery) # URL schemes supported by QtWebEngine diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index 85f68661a..76686162c 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -300,3 +300,14 @@ Feature: Special qute:// pages Scenario: Open qute://gpl When I open qute://gpl Then the page should contain the plaintext "GNU GENERAL PUBLIC LICENSE" + + # qute://start + + Scenario: Seaching on qute://start + When I set url.searchengines to {"DEFAULT": "http://localhost:(port)/data/title.html?q={}"} + And I open qute://start + And I run :click-element id search-field + And I wait for "Entering mode KeyMode.insert *" in the log + And I press the keys "test" + And I press the key "" + Then data/title.html?q=test should be loaded diff --git a/tests/end2end/features/urlmarks.feature b/tests/end2end/features/urlmarks.feature index 65e6c051a..1c97ec322 100644 --- a/tests/end2end/features/urlmarks.feature +++ b/tests/end2end/features/urlmarks.feature @@ -92,7 +92,8 @@ Feature: quickmarks and bookmarks And I open data/numbers/2.txt And I run :bookmark-add And I run :bookmark-del --all - Then the bookmark file should not contain "http://localhost:*/data/numbers/1.txt" + Then the message "Bookmarks cleared." should be shown + And the bookmark file should not contain "http://localhost:*/data/numbers/1.txt" And the bookmark file should not contain "http://localhost:*/data/numbers/2.txt" Scenario: Deleting all bookmarks with url @@ -230,7 +231,8 @@ Feature: quickmarks and bookmarks When I run :quickmark-add http://localhost:(port)/data/numbers/1.txt one When I run :quickmark-add http://localhost:(port)/data/numbers/2.txt two And I run :quickmark-del --all - Then the quickmark file should not contain "one http://localhost:*/data/numbers/1.txt" + Then the message "Quickmarks cleared." should be shown + And the quickmark file should not contain "one http://localhost:*/data/numbers/1.txt" And the quickmark file should not contain "two http://localhost:*/data/numbers/2.txt" Scenario: Deleting all quickmarks with name -- cgit v1.2.3-54-g00ecf