summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorLembrun <amadeusk7@free.fr>2021-03-09 22:41:04 +0100
committerLembrun <amadeusk7@free.fr>2021-03-09 22:41:04 +0100
commit9c056f288aefebbb95734fa3dc46a2405862405b (patch)
tree93a866f887638ca9f0a6e7a1977a71ef05591f38 /tests
parentb57dfaf663f66de890e984dd814bf86a9c7a08a5 (diff)
parent0a38fff4c675b384289728a4d45f9c1fe1f9d4fc (diff)
downloadqutebrowser-9c056f288aefebbb95734fa3dc46a2405862405b.tar.gz
qutebrowser-9c056f288aefebbb95734fa3dc46a2405862405b.zip
Merge branch 'master' into pathlib-/unit/commands
Diffstat (limited to 'tests')
-rw-r--r--tests/conftest.py6
-rw-r--r--tests/end2end/features/editor.feature49
-rw-r--r--tests/end2end/features/misc.feature12
-rw-r--r--tests/end2end/features/qutescheme.feature2
-rw-r--r--tests/end2end/features/sessions.feature5
-rw-r--r--tests/end2end/features/tabs.feature5
-rw-r--r--tests/end2end/features/test_editor_bdd.py37
-rw-r--r--tests/unit/browser/webengine/test_webenginetab.py94
-rw-r--r--tests/unit/completion/test_models.py11
-rw-r--r--tests/unit/javascript/conftest.py7
-rw-r--r--tests/unit/javascript/test_greasemonkey.py189
-rw-r--r--tests/unit/misc/test_guiprocess.py2
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):