diff options
author | Lembrun <amadeusk7@free.fr> | 2021-03-09 22:41:04 +0100 |
---|---|---|
committer | Lembrun <amadeusk7@free.fr> | 2021-03-09 22:41:04 +0100 |
commit | 9c056f288aefebbb95734fa3dc46a2405862405b (patch) | |
tree | 93a866f887638ca9f0a6e7a1977a71ef05591f38 /tests | |
parent | b57dfaf663f66de890e984dd814bf86a9c7a08a5 (diff) | |
parent | 0a38fff4c675b384289728a4d45f9c1fe1f9d4fc (diff) | |
download | qutebrowser-9c056f288aefebbb95734fa3dc46a2405862405b.tar.gz qutebrowser-9c056f288aefebbb95734fa3dc46a2405862405b.zip |
Merge branch 'master' into pathlib-/unit/commands
Diffstat (limited to 'tests')
-rw-r--r-- | tests/conftest.py | 6 | ||||
-rw-r--r-- | tests/end2end/features/editor.feature | 49 | ||||
-rw-r--r-- | tests/end2end/features/misc.feature | 12 | ||||
-rw-r--r-- | tests/end2end/features/qutescheme.feature | 2 | ||||
-rw-r--r-- | tests/end2end/features/sessions.feature | 5 | ||||
-rw-r--r-- | tests/end2end/features/tabs.feature | 5 | ||||
-rw-r--r-- | tests/end2end/features/test_editor_bdd.py | 37 | ||||
-rw-r--r-- | tests/unit/browser/webengine/test_webenginetab.py | 94 | ||||
-rw-r--r-- | tests/unit/completion/test_models.py | 11 | ||||
-rw-r--r-- | tests/unit/javascript/conftest.py | 7 | ||||
-rw-r--r-- | tests/unit/javascript/test_greasemonkey.py | 189 | ||||
-rw-r--r-- | tests/unit/misc/test_guiprocess.py | 2 |
12 files changed, 226 insertions, 193 deletions
diff --git a/tests/conftest.py b/tests/conftest.py index ea7381a2f..ee945ac4c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -109,12 +109,6 @@ def _apply_platform_markers(config, item): pytest.mark.skipif, sys.getfilesystemencoding() == 'ascii', "Skipped because of ASCII locale"), - - ('qtwebkit6021_xfail', - pytest.mark.xfail, - version.qWebKitVersion and # type: ignore[unreachable] - version.qWebKitVersion() == '602.1', - "Broken on WebKit 602.1") ] for searched_marker, new_marker_kind, condition, default_reason in markers: diff --git a/tests/end2end/features/editor.feature b/tests/end2end/features/editor.feature index 52756422c..47cb1230a 100644 --- a/tests/end2end/features/editor.feature +++ b/tests/end2end/features/editor.feature @@ -6,14 +6,14 @@ Feature: Opening external editors Scenario: Editing a URL When I open data/numbers/1.txt - And I set up a fake editor replacing "1.txt" by "2.txt" + And I setup a fake editor replacing "1.txt" by "2.txt" And I run :edit-url Then data/numbers/2.txt should be loaded Scenario: Editing a URL with -t When I run :tab-only And I open data/numbers/1.txt - And I set up a fake editor replacing "1.txt" by "2.txt" + And I setup a fake editor replacing "1.txt" by "2.txt" And I run :edit-url -t Then data/numbers/2.txt should be loaded And the following tabs should be open: @@ -24,7 +24,7 @@ Feature: Opening external editors When I set tabs.new_position.related to prev And I open data/numbers/1.txt And I run :tab-only - And I set up a fake editor replacing "1.txt" by "2.txt" + And I setup a fake editor replacing "1.txt" by "2.txt" And I run :edit-url -rt Then data/numbers/2.txt should be loaded And the following tabs should be open: @@ -34,7 +34,7 @@ Feature: Opening external editors Scenario: Editing a URL with -b When I run :tab-only And I open data/numbers/1.txt - And I set up a fake editor replacing "1.txt" by "2.txt" + And I setup a fake editor replacing "1.txt" by "2.txt" And I run :edit-url -b Then data/numbers/2.txt should be loaded And the following tabs should be open: @@ -45,7 +45,7 @@ Feature: Opening external editors When I run :window-only And I open data/numbers/1.txt in a new tab And I run :tab-only - And I set up a fake editor replacing "1.txt" by "2.txt" + And I setup a fake editor replacing "1.txt" by "2.txt" And I run :edit-url -w Then data/numbers/2.txt should be loaded And the session should look like: @@ -65,7 +65,7 @@ Feature: Opening external editors When I open data/numbers/1.txt in a new tab And I run :tab-only And I run :window-only - And I set up a fake editor replacing "1.txt" by "2.txt" + And I setup a fake editor replacing "1.txt" by "2.txt" And I run :edit-url -p Then data/numbers/2.txt should be loaded And the session should look like: @@ -90,13 +90,13 @@ Feature: Opening external editors Scenario: Editing a URL with invalid URL When I set url.auto_search to never And I open data/hello.txt - And I set up a fake editor replacing "http://localhost:(port)/data/hello.txt" by "foo!" + And I setup a fake editor replacing "http://localhost:(port)/data/hello.txt" by "foo!" And I run :edit-url Then the error "Invalid URL" should be shown Scenario: Spawning an editor successfully Given I have a fresh instance - When I set up a fake editor returning "foobar" + When I setup a fake editor returning "foobar" And I open data/editor.html And I run :click-element id qute-textarea And I wait for "Entering mode KeyMode.insert (reason: clicking input)" in the log @@ -105,7 +105,7 @@ Feature: Opening external editors Then the javascript message "text: foobar" should be logged Scenario: Spawning an editor in normal mode - When I set up a fake editor returning "foobar" + When I setup a fake editor returning "foobar" And I open data/editor.html And I run :click-element id qute-textarea And I wait for "Entering mode KeyMode.insert (reason: clicking input)" in the log @@ -119,7 +119,7 @@ Feature: Opening external editors # There's no guarantee that the tab gets deleted... @posix Scenario: Spawning an editor and closing the tab - When I set up a fake editor that writes "foobar" on save + When I setup a fake editor that writes "foobar" on save And I open data/editor.html And I run :click-element id qute-textarea And I wait for "Entering mode KeyMode.insert (reason: clicking input)" in the log @@ -134,7 +134,7 @@ Feature: Opening external editors # Could not get signals working on Windows @posix Scenario: Spawning an editor and saving - When I set up a fake editor that writes "foobar" on save + When I setup a fake editor that writes "foobar" on save And I open data/editor.html And I run :click-element id qute-textarea And I wait for "Entering mode KeyMode.insert (reason: clicking input)" in the log @@ -145,7 +145,7 @@ Feature: Opening external editors Then the javascript message "text: foobar" should be logged Scenario: Spawning an editor in caret mode - When I set up a fake editor returning "foobar" + When I setup a fake editor returning "foobar" And I open data/editor.html And I run :click-element id qute-textarea And I wait for "Entering mode KeyMode.insert (reason: clicking input)" in the log @@ -159,7 +159,7 @@ Feature: Opening external editors Then the javascript message "text: foobar" should be logged Scenario: Spawning an editor with existing text - When I set up a fake editor replacing "foo" by "bar" + When I setup a fake editor replacing "foo" by "bar" And I open data/editor.html And I run :click-element id qute-textarea And I wait for "Entering mode KeyMode.insert (reason: clicking input)" in the log @@ -173,20 +173,20 @@ Feature: Opening external editors Scenario: Edit a command and run it When I run :set-cmd-text :message-info foo - And I set up a fake editor replacing "foo" by "bar" + And I setup a fake editor replacing "foo" by "bar" And I run :edit-command --run Then the message "bar" should be shown And "Leaving mode KeyMode.command (reason: cmd accept)" should be logged Scenario: Edit a command and omit the start char - When I set up a fake editor returning "message-info foo" + When I setup a fake editor returning "message-info foo" And I run :edit-command Then the error "command must start with one of :/?" should be shown And "Leaving mode KeyMode.command *" should not be logged Scenario: Edit a command to be empty When I run :set-cmd-text : - When I set up a fake editor returning empty text + When I setup a fake editor returning empty text And I run :edit-command Then the error "command must start with one of :/?" should be shown And "Leaving mode KeyMode.command *" should not be logged @@ -194,13 +194,20 @@ Feature: Opening external editors ## select single file Scenario: Select one file with single command - When I set up a fake "single_file" fileselector selecting "tests/end2end/data/numbers/1.txt" + When I setup a fake single_file fileselector selecting "tests/end2end/data/numbers/1.txt" and writes to a temporary file + And I open data/fileselect.html + And I run :click-element id single_file + Then the javascript message "Files: 1.txt" should be logged + + Scenario: Select one file with single command that writes to stdout + When I setup a fake single_file fileselector selecting "tests/end2end/data/numbers/1.txt" and writes to stdout And I open data/fileselect.html And I run :click-element id single_file Then the javascript message "Files: 1.txt" should be logged Scenario: Select two files with single command - When I set up a fake "single_file" fileselector selecting "tests/end2end/data/numbers/1.txt tests/end2end/data/numbers/2.txt" + When I setup a fake single_file fileselector selecting "tests/end2end/data/numbers/1.txt tests/end2end/data/numbers/2.txt" and writes to a temporary file + And I open data/fileselect.html And I run :click-element id single_file Then the javascript message "Files: 1.txt" should be logged @@ -209,13 +216,15 @@ Feature: Opening external editors ## select multiple files Scenario: Select one file with multiple command - When I set up a fake "multiple_files" fileselector selecting "tests/end2end/data/numbers/1.txt" + When I setup a fake multiple_files fileselector selecting "tests/end2end/data/numbers/1.txt" and writes to a temporary file + And I open data/fileselect.html And I run :click-element id multiple_files Then the javascript message "Files: 1.txt" should be logged Scenario: Select two files with multiple command - When I set up a fake "multiple_files" fileselector selecting "tests/end2end/data/numbers/1.txt tests/end2end/data/numbers/2.txt" + When I setup a fake multiple_files fileselector selecting "tests/end2end/data/numbers/1.txt tests/end2end/data/numbers/2.txt" and writes to a temporary file + And I open data/fileselect.html And I run :click-element id multiple_files Then the javascript message "Files: 1.txt, 2.txt" should be logged diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index 351135fab..e6a02e038 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -140,7 +140,7 @@ Feature: Various utility commands. Scenario: :jseval --file using a file that doesn't exist as js-code When I run :jseval --file /nonexistentfile - Then the error "[Errno 2] No such file or directory: '/nonexistentfile'" should be shown + Then the error "[Errno 2] *: '/nonexistentfile'" should be shown And "No output or error" should not be logged # :debug-webaction @@ -528,13 +528,13 @@ Feature: Various utility commands. @qtwebkit_skip @no_invalid_lines @posix Scenario: Renderer crash When I run :open -t chrome://crash - Then "Renderer process crashed" should be logged + Then "Renderer process crashed (status *)" should be logged And "* 'Error loading chrome://crash/'" should be logged @qtwebkit_skip @no_invalid_lines @flaky Scenario: Renderer kill When I run :open -t chrome://kill - Then "Renderer process was killed" should be logged + Then "Renderer process was killed (status *)" should be logged And "* 'Error loading chrome://kill/'" should be logged # https://github.com/qutebrowser/qutebrowser/issues/2290 @@ -544,7 +544,7 @@ Feature: Various utility commands. And I open data/numbers/1.txt And I open data/numbers/2.txt in a new tab And I run :open chrome://kill - And I wait for "Renderer process was killed" in the log + And I wait for "Renderer process was killed (status *)" in the log And I open data/numbers/3.txt Then no crash should happen @@ -554,11 +554,11 @@ Feature: Various utility commands. When I open data/crashers/webrtc.html in a new tab And I run :reload And I wait until data/crashers/webrtc.html is loaded - Then "Renderer process crashed" should not be logged + Then "Renderer process crashed (status *)" should not be logged Scenario: InstalledApps crash When I open data/crashers/installedapp.html in a new tab - Then "Renderer process was killed" should not be logged + Then "Renderer process was killed (status *)" should not be logged ## Other diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index 286f8f80a..1424bbf09 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -215,7 +215,7 @@ Feature: Special qute:// pages Scenario: Running :pyeval --file using a non existing file When I run :debug-pyeval --file nonexistentfile - Then the error "[Errno 2] No such file or directory: 'nonexistentfile'" should be shown + Then the error "[Errno 2] *: 'nonexistentfile'" should be shown Scenario: Running :pyeval with --quiet When I run :debug-pyeval --quiet 1+1 diff --git a/tests/end2end/features/sessions.feature b/tests/end2end/features/sessions.feature index 0f0c015e0..e48947cbd 100644 --- a/tests/end2end/features/sessions.feature +++ b/tests/end2end/features/sessions.feature @@ -395,9 +395,10 @@ Feature: Saving and loading sessions And I run :session-load -c pin_session And I wait until data/numbers/3.txt is loaded And I run :tab-focus 2 - And I run :open hello world - Then the message "Tab is pinned!" should be shown + And I open data/numbers/4.txt + Then the message "Tab is pinned! Opening in new tab." should be shown And the following tabs should be open: - data/numbers/1.txt - data/numbers/2.txt (active) (pinned) + - data/numbers/4.txt - data/numbers/3.txt diff --git a/tests/end2end/features/tabs.feature b/tests/end2end/features/tabs.feature index ca0efefc4..7db054573 100644 --- a/tests/end2end/features/tabs.feature +++ b/tests/end2end/features/tabs.feature @@ -1534,10 +1534,11 @@ Feature: Tab management Scenario: :tab-pin open url When I open data/numbers/1.txt And I run :tab-pin - And I open data/numbers/2.txt without waiting - Then the message "Tab is pinned!" should be shown + And I open data/numbers/2.txt + Then the message "Tab is pinned! Opening in new tab." should be shown And the following tabs should be open: - data/numbers/1.txt (active) (pinned) + - data/numbers/2.txt Scenario: :tab-pin open url with tabs.pinned.frozen = false When I set tabs.pinned.frozen to false diff --git a/tests/end2end/features/test_editor_bdd.py b/tests/end2end/features/test_editor_bdd.py index 445691bee..40f77a0f7 100644 --- a/tests/end2end/features/test_editor_bdd.py +++ b/tests/end2end/features/test_editor_bdd.py @@ -32,7 +32,7 @@ bdd.scenarios('editor.feature') from qutebrowser.utils import utils -@bdd.when(bdd.parsers.parse('I set up a fake editor replacing "{text}" by ' +@bdd.when(bdd.parsers.parse('I setup a fake editor replacing "{text}" by ' '"{replacement}"')) def set_up_editor_replacement(quteproc, server, tmpdir, text, replacement): """Set up editor.command to a small python script doing a replacement.""" @@ -53,7 +53,7 @@ def set_up_editor_replacement(quteproc, server, tmpdir, text, replacement): quteproc.set_setting('editor.command', editor) -@bdd.when(bdd.parsers.parse('I set up a fake editor returning "{text}"')) +@bdd.when(bdd.parsers.parse('I setup a fake editor returning "{text}"')) def set_up_editor(quteproc, tmpdir, text): """Set up editor.command to a small python script inserting a text.""" script = tmpdir / 'script.py' @@ -67,7 +67,7 @@ def set_up_editor(quteproc, tmpdir, text): quteproc.set_setting('editor.command', editor) -@bdd.when(bdd.parsers.parse('I set up a fake editor returning empty text')) +@bdd.when(bdd.parsers.parse('I setup a fake editor returning empty text')) def set_up_editor_empty(quteproc, tmpdir): """Set up editor.command to a small python script inserting empty text.""" set_up_editor(quteproc, tmpdir, "") @@ -107,7 +107,7 @@ def editor_pid_watcher(tmpdir): return EditorPidWatcher(tmpdir) -@bdd.when(bdd.parsers.parse('I set up a fake editor that writes "{text}" on ' +@bdd.when(bdd.parsers.parse('I setup a fake editor that writes "{text}" on ' 'save')) def set_up_editor_wait(quteproc, tmpdir, text, editor_pid_watcher): """Set up editor.command to a small python script inserting a text.""" @@ -180,18 +180,31 @@ def save_editor_wait(tmpdir): os.kill(pid, signal.SIGUSR2) -@bdd.when(bdd.parsers.parse('I set up a fake "{kind}" fileselector ' - 'selecting "{files}"')) -def set_up_fileselector(quteproc, py_proc, kind, files): +@bdd.when(bdd.parsers.parse('I setup a fake {kind} fileselector ' + 'selecting "{files}" and writes to {output_type}')) +def set_up_fileselector(quteproc, py_proc, kind, files, output_type): """Set up fileselect.xxx.command to select the file(s).""" cmd, args = py_proc(r""" import os import sys - tmp_file = sys.argv[1] - with open(tmp_file, 'w') as f: - for selected_file in sys.argv[2:]: - f.write(os.path.abspath(selected_file) + "\n") + tmp_file = None + for i, arg in enumerate(sys.argv): + if arg.startswith('--file='): + tmp_file = arg[len('--file='):] + sys.argv.pop(i) + break + selected_files = sys.argv[1:] + if tmp_file is None: + for selected_file in selected_files: + print(os.path.abspath(selected_file)) + else: + with open(tmp_file, 'w') as f: + for selected_file in selected_files: + f.write(os.path.abspath(selected_file) + '\n') """) - fileselect_cmd = json.dumps([cmd, *args, '{}', *files.split(' ')]) + args += files.split(' ') + if output_type == "a temporary file": + args += ['--file={}'] + fileselect_cmd = json.dumps([cmd, *args]) quteproc.set_setting('fileselect.handler', 'external') quteproc.set_setting(f'fileselect.{kind}.command', fileselect_cmd) diff --git a/tests/unit/browser/webengine/test_webenginetab.py b/tests/unit/browser/webengine/test_webenginetab.py index 7827c379b..156f7d26f 100644 --- a/tests/unit/browser/webengine/test_webenginetab.py +++ b/tests/unit/browser/webengine/test_webenginetab.py @@ -20,6 +20,7 @@ """Test webenginetab.""" import logging +import textwrap import pytest QtWebEngineWidgets = pytest.importorskip("PyQt5.QtWebEngineWidgets") @@ -35,15 +36,38 @@ webenginetab = pytest.importorskip( pytestmark = pytest.mark.usefixtures('greasemonkey_manager') +class ScriptsHelper: + + """Helper to get the processed (usually Greasemonkey) scripts.""" + + def __init__(self, tab): + self._tab = tab + + def get_scripts(self, prefix='GM-'): + return [ + s for s in self._tab._widget.page().scripts().toList() + if s.name().startswith(prefix) + ] + + def get_script(self): + scripts = self.get_scripts() + assert len(scripts) == 1 + return scripts[0] + + def inject(self, scripts): + self._tab._scripts._inject_greasemonkey_scripts(scripts) + return self.get_scripts() + + class TestWebengineScripts: """Test the _WebEngineScripts utility class.""" @pytest.fixture - def webengine_scripts(self, webengine_tab): - return webengine_tab._scripts + def scripts_helper(self, webengine_tab): + return ScriptsHelper(webengine_tab) - def test_greasemonkey_undefined_world(self, webengine_scripts, caplog): + def test_greasemonkey_undefined_world(self, scripts_helper, caplog): """Make sure scripts with non-existent worlds are rejected.""" scripts = [ greasemonkey.GreasemonkeyScript( @@ -51,18 +75,16 @@ class TestWebengineScripts: ] with caplog.at_level(logging.ERROR, 'greasemonkey'): - webengine_scripts._inject_greasemonkey_scripts(scripts) + injected = scripts_helper.inject(scripts) assert len(caplog.records) == 1 msg = caplog.messages[0] assert "has invalid value for '@qute-js-world': Mars" in msg - collection = webengine_scripts._widget.page().scripts().toList() - assert not any(script.name().startswith('GM-') - for script in collection) + + assert not injected @pytest.mark.parametrize("worldid", [-1, 257]) - def test_greasemonkey_out_of_range_world(self, worldid, webengine_scripts, - caplog): + def test_greasemonkey_out_of_range_world(self, worldid, scripts_helper, caplog): """Make sure scripts with out-of-range worlds are rejected.""" scripts = [ greasemonkey.GreasemonkeyScript( @@ -70,19 +92,18 @@ class TestWebengineScripts: ] with caplog.at_level(logging.ERROR, 'greasemonkey'): - webengine_scripts._inject_greasemonkey_scripts(scripts) + injected = scripts_helper.inject(scripts) assert len(caplog.records) == 1 msg = caplog.messages[0] assert "has invalid value for '@qute-js-world': " in msg assert "should be between 0 and" in msg - collection = webengine_scripts._widget.page().scripts().toList() - assert not any(script.name().startswith('GM-') - for script in collection) + + assert not injected @pytest.mark.parametrize("worldid", [0, 10]) def test_greasemonkey_good_worlds_are_passed(self, worldid, - webengine_scripts, caplog): + scripts_helper, caplog): """Make sure scripts with valid worlds have it set.""" scripts = [ greasemonkey.GreasemonkeyScript( @@ -91,13 +112,11 @@ class TestWebengineScripts: ] with caplog.at_level(logging.ERROR, 'greasemonkey'): - webengine_scripts._inject_greasemonkey_scripts(scripts) + scripts_helper.inject(scripts) - collection = webengine_scripts._widget.page().scripts() - assert collection.toList()[-1].worldId() == worldid + assert scripts_helper.get_script().worldId() == worldid - def test_greasemonkey_document_end_workaround(self, monkeypatch, - webengine_scripts): + def test_greasemonkey_document_end_workaround(self, monkeypatch, scripts_helper): """Make sure document-end is forced when needed.""" monkeypatch.setattr(greasemonkey.objects, 'backend', usertypes.Backend.QtWebEngine) @@ -109,13 +128,42 @@ class TestWebengineScripts: ('run-at', 'document-start'), ], None) ] + scripts_helper.inject(scripts) - webengine_scripts._inject_greasemonkey_scripts(scripts) - - collection = webengine_scripts._widget.page().scripts() - script = collection.toList()[-1] + script = scripts_helper.get_script() assert script.injectionPoint() == QWebEngineScript.DocumentReady + @pytest.mark.parametrize('run_at, expected', [ + # UserScript::DocumentElementCreation + ('document-start', QWebEngineScript.DocumentCreation), + # UserScript::DocumentLoadFinished + ('document-end', QWebEngineScript.DocumentReady), + # UserScript::AfterLoad + ('document-idle', QWebEngineScript.Deferred), + # default according to https://wiki.greasespot.net/Metadata_Block#.40run-at + (None, QWebEngineScript.DocumentReady), + ]) + def test_greasemonkey_run_at_values(self, scripts_helper, run_at, expected): + if run_at is None: + script = """ + // ==UserScript== + // @name qutebrowser test userscript + // ==/UserScript== + """ + else: + script = f""" + // ==UserScript== + // @name qutebrowser test userscript + // @run-at {run_at} + // ==/UserScript== + """ + + script = textwrap.dedent(script.lstrip('\n')) + scripts = [greasemonkey.GreasemonkeyScript.parse(script)] + scripts_helper.inject(scripts) + + assert scripts_helper.get_script().injectionPoint() == expected + def test_notification_permission_workaround(): """Make sure the value for QWebEnginePage::Notifications is correct.""" diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py index 8a6b24557..22e9c6490 100644 --- a/tests/unit/completion/test_models.py +++ b/tests/unit/completion/test_models.py @@ -28,7 +28,7 @@ from datetime import datetime from unittest import mock import hypothesis -import hypothesis.strategies +import hypothesis.strategies as hst import pytest from PyQt5.QtCore import QUrl, QDateTime try: @@ -459,9 +459,10 @@ def test_filesystem_completion_model_interface(info, local_files_path): @hypothesis.given( - as_uri=hypothesis.strategies.booleans(), - add_sep=hypothesis.strategies.booleans(), - text=hypothesis.strategies.text(), + as_uri=hst.booleans(), + add_sep=hst.booleans(), + text=hst.text(alphabet=hst.characters( + blacklist_categories=['Cc'], blacklist_characters='\x00')), ) def test_filesystem_completion_hypothesis(info, as_uri, add_sep, text): if as_uri: @@ -1445,7 +1446,7 @@ def undo_completion_retains_sort_order(tabbed_browser_stubs, info): _check_completions(model, {"Closed tabs": expected}) -@hypothesis.given(text=hypothesis.strategies.text()) +@hypothesis.given(text=hst.text()) def test_listcategory_hypothesis(text): """Make sure we can't produce invalid patterns.""" cat = listcategory.ListCategory("test", []) diff --git a/tests/unit/javascript/conftest.py b/tests/unit/javascript/conftest.py index 47884687d..85d5ebe0a 100644 --- a/tests/unit/javascript/conftest.py +++ b/tests/unit/javascript/conftest.py @@ -28,6 +28,7 @@ import jinja2 from PyQt5.QtCore import QUrl import qutebrowser +from qutebrowser.utils import usertypes class JSTester: @@ -113,7 +114,7 @@ class JSTester: source = f.read() self.run(source, expected) - def run(self, source: str, expected, world=None) -> None: + def run(self, source: str, expected=usertypes.UNSET, world=None) -> None: """Run the given javascript source. Args: @@ -123,7 +124,9 @@ class JSTester: """ with self.qtbot.wait_callback() as callback: self.tab.run_js_async(source, callback, world=world) - callback.assert_called_with(expected) + + if expected is not usertypes.UNSET: + callback.assert_called_with(expected) @pytest.fixture diff --git a/tests/unit/javascript/test_greasemonkey.py b/tests/unit/javascript/test_greasemonkey.py index c28b9c8f7..3a3ea0294 100644 --- a/tests/unit/javascript/test_greasemonkey.py +++ b/tests/unit/javascript/test_greasemonkey.py @@ -25,7 +25,7 @@ import pytest import py.path # pylint: disable=no-name-in-module from PyQt5.QtCore import QUrl -from qutebrowser.utils import usertypes +from qutebrowser.utils import usertypes, version from qutebrowser.browser import greasemonkey from qutebrowser.misc import objects @@ -77,8 +77,7 @@ def test_get_scripts_by_url(url, expected_matches): gm_manager = greasemonkey.GreasemonkeyManager() scripts = gm_manager.scripts_for(QUrl(url)) - assert (len(scripts.start + scripts.end + scripts.idle) == - expected_matches) + assert len(scripts.start + scripts.end + scripts.idle) == expected_matches @pytest.mark.parametrize("url, expected_matches", [ @@ -102,8 +101,7 @@ def test_regex_includes_scripts_for(url, expected_matches): gm_manager = greasemonkey.GreasemonkeyManager() scripts = gm_manager.scripts_for(QUrl(url)) - assert (len(scripts.start + scripts.end + scripts.idle) == - expected_matches) + assert len(scripts.start + scripts.end + scripts.idle) == expected_matches def test_no_metadata(caplog): @@ -229,124 +227,87 @@ def test_required_scripts_are_included(download_stub, tmpdir): assert scripts[0].excludes -class TestWindowIsolation: +def test_window_isolation(js_tester, request): """Check that greasemonkey scripts get a shadowed global scope.""" + # Change something in the global scope + setup_script = "window.$ = 'global'" - @pytest.fixture - def setup(self): - # pylint: disable=attribute-defined-outside-init - class SetupData: - pass - ret = SetupData() - - # Change something in the global scope - ret.setup_script = "window.$ = 'global'" - - # Greasemonkey script to report back on its scope. - test_script = greasemonkey.GreasemonkeyScript.parse( - textwrap.dedent(""" - // ==UserScript== - // @name scopetest - // ==/UserScript== - // Check the thing the page set is set to the expected type - result.push(window.$); - result.push($); - // Now overwrite it - window.$ = 'shadowed'; - // And check everything is how the script would expect it to be - // after just writing to the "global" scope - result.push(window.$); - result.push($); - """) - ) - - # The compiled source of that scripts with some additional setup - # bookending it. - ret.test_script = "\n".join([ - """ - const result = []; - """, - test_script.code(), - """ - // Now check that the actual global scope has - // not been overwritten + # Greasemonkey script to report back on its scope. + test_gm_script = greasemonkey.GreasemonkeyScript.parse( + textwrap.dedent(""" + // ==UserScript== + // @name scopetest + // ==/UserScript== + // Check the thing the page set is set to the expected type + result.push(window.$); + result.push($); + // Now overwrite it + window.$ = 'shadowed'; + // And check everything is how the script would expect it to be + // after just writing to the "global" scope result.push(window.$); result.push($); - // And return our findings - result; - """ - ]) + """) + ) + + # The compiled source of that scripts with some additional setup + # bookending it. + test_script = "\n".join([ + """ + const result = []; + """, + test_gm_script.code(), + """ + // Now check that the actual global scope has + // not been overwritten + result.push(window.$); + result.push($); + // And return our findings + result; + """ + ]) - # What we expect the script to report back. - ret.expected = ["global", "global", - "shadowed", "shadowed", - "global", "global"] - return ret + # What we expect the script to report back. + expected = ["global", "global", "shadowed", "shadowed", "global", "global"] - def test_webengine(self, qtbot, webengineview, setup): - page = webengineview.page() - page.runJavaScript(setup.setup_script) + # The JSCore in 602.1 doesn't fully support Proxy. + xfail = False + if (js_tester.tab.backend == usertypes.Backend.QtWebKit and + version.qWebKitVersion() == '602.1'): + expected[-1] = 'shadowed' + expected[-2] = 'shadowed' + xfail = True - with qtbot.wait_callback() as callback: - page.runJavaScript(setup.test_script, callback) - callback.assert_called_with(setup.expected) + js_tester.run(setup_script) + js_tester.run(test_script, expected=expected) - # The JSCore in 602.1 doesn't fully support Proxy. - @pytest.mark.qtwebkit6021_xfail - def test_webkit(self, webview, setup): - elem = webview.page().mainFrame().documentElement() - elem.evaluateJavaScript(setup.setup_script) - result = elem.evaluateJavaScript(setup.test_script) - assert result == setup.expected + if xfail: + pytest.xfail("Broken on WebKit 602.1") -class TestSharedWindowProxy: +def test_shared_window_proxy(js_tester): """Check that all scripts have access to the same window proxy.""" + # Greasemonkey script to add a property to the window proxy. + test_script_a = greasemonkey.GreasemonkeyScript.parse( + textwrap.dedent(""" + // ==UserScript== + // @name a + // ==/UserScript== + // Set a value from script a + window.$ = 'test'; + """) + ).code() + + # Greasemonkey script to retrieve a property from the window proxy. + test_script_b = greasemonkey.GreasemonkeyScript.parse( + textwrap.dedent(""" + // ==UserScript== + // @name b + // ==/UserScript== + // Check that the value is accessible from script b + return [window.$, $]; + """) + ).code() - @pytest.fixture - def setup(self): - # pylint: disable=attribute-defined-outside-init - class SetupData: - pass - ret = SetupData() - - # Greasemonkey script to add a property to the window proxy. - ret.test_script_a = greasemonkey.GreasemonkeyScript.parse( - textwrap.dedent(""" - // ==UserScript== - // @name a - // ==/UserScript== - // Set a value from script a - window.$ = 'test'; - """) - ).code() - - # Greasemonkey script to retrieve a property from the window proxy. - ret.test_script_b = greasemonkey.GreasemonkeyScript.parse( - textwrap.dedent(""" - // ==UserScript== - // @name b - // ==/UserScript== - // Check that the value is accessible from script b - return [window.$, $]; - """) - ).code() - - # What we expect the script to report back. - ret.expected = ["test", "test"] - return ret - - def test_webengine(self, qtbot, webengineview, setup): - page = webengineview.page() - - with qtbot.wait_callback() as callback: - page.runJavaScript(setup.test_script_a, callback) - with qtbot.wait_callback() as callback: - page.runJavaScript(setup.test_script_b, callback) - callback.assert_called_with(setup.expected) - - def test_webkit(self, webview, setup): - elem = webview.page().mainFrame().documentElement() - elem.evaluateJavaScript(setup.test_script_a) - result = elem.evaluateJavaScript(setup.test_script_b) - assert result == setup.expected + js_tester.run(test_script_a) + js_tester.run(test_script_b, expected=["test", "test"]) diff --git a/tests/unit/misc/test_guiprocess.py b/tests/unit/misc/test_guiprocess.py index a2acad1ac..9e1b3916c 100644 --- a/tests/unit/misc/test_guiprocess.py +++ b/tests/unit/misc/test_guiprocess.py @@ -127,9 +127,11 @@ def test_start_output_message(proc, qtbot, caplog, message_mock, py_proc, if stdout_msg is not None: assert stdout_msg.level == usertypes.MessageLevel.info assert stdout_msg.text == 'stdout text' + assert proc.final_stdout.strip() == "stdout text", proc.final_stdout if stderr_msg is not None: assert stderr_msg.level == usertypes.MessageLevel.error assert stderr_msg.text == 'stderr text' + assert proc.final_stderr.strip() == "stderr text", proc.final_stderr def test_start_env(monkeypatch, qtbot, py_proc): |