summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2022-06-20 16:43:35 +0200
committerFlorian Bruhin <me@the-compiler.org>2022-06-20 16:44:24 +0200
commit4df7aedf2b2e1f844e8f0ba55bb6fdcafcfa8ec8 (patch)
tree6809be279358018dc5d23ec3d9d0f6e966631807
parentd286b2aa47df3f2fa5a1543f9fef4423c826a614 (diff)
downloadqutebrowser-4df7aedf2b2e1f844e8f0ba55bb6fdcafcfa8ec8.tar.gz
qutebrowser-4df7aedf2b2e1f844e8f0ba55bb6fdcafcfa8ec8.zip
tests: Improve greasemonkey tests
-rw-r--r--tests/unit/javascript/test_greasemonkey.py201
1 files changed, 194 insertions, 7 deletions
diff --git a/tests/unit/javascript/test_greasemonkey.py b/tests/unit/javascript/test_greasemonkey.py
index 679fc9409..b298b1216 100644
--- a/tests/unit/javascript/test_greasemonkey.py
+++ b/tests/unit/javascript/test_greasemonkey.py
@@ -18,8 +18,8 @@
"""Tests for qutebrowser.browser.greasemonkey."""
-import logging
import textwrap
+import logging
import pathlib
import pytest
@@ -48,8 +48,17 @@ pytestmark = [
@pytest.fixture
-def gm_manager() -> greasemonkey.GreasemonkeyManager:
- return greasemonkey.GreasemonkeyManager()
+def gm_manager(monkeypatch) -> greasemonkey.GreasemonkeyManager:
+ gmm = greasemonkey.GreasemonkeyManager()
+ monkeypatch.setattr(greasemonkey, "gm_manager", gmm)
+ return gmm
+
+
+@pytest.fixture
+def wrong_path_setup():
+ wrong_path = _scripts_dir() / "test1.user.js"
+ wrong_path.mkdir()
+ _save_script(test_gm_script, "test2.user.js")
def _scripts_dir() -> pathlib.Path:
@@ -78,12 +87,100 @@ def test_all(gm_manager):
assert all_scripts[0].name == name
-def test_load_error(gm_manager):
+@pytest.mark.parametrize("header, expected", [
+ # defaults
+ (
+ [],
+ {
+ "name": "test.user.js",
+ "namespace": None,
+ "includes": ['*'],
+ "matches": [],
+ "excludes": [],
+ "run_at": None,
+ "runs_on_sub_frames": True,
+ "jsworld": "main",
+ }
+ ),
+ # include/exclude/match
+ (
+ ["@include https://example.org"],
+ {
+ "includes": ['https://example.org'],
+ "excludes": [],
+ "matches": [],
+ }
+ ),
+ (
+ ["@include https://example.org", "@include https://example.com"],
+ {
+ "includes": ['https://example.org', 'https://example.com'],
+ "excludes": [],
+ "matches": [],
+ }
+ ),
+ (
+ ["@match https://example.org"],
+ {"includes": [], "excludes": [], "matches": ['https://example.org']}
+ ),
+ (
+ ["@match https://example.org", "@exclude_match https://example.com"],
+ {
+ "includes": [],
+ "excludes": ['https://example.com'],
+ "matches": ['https://example.org'],
+ }
+ ),
+ (
+ ["@exclude https://example.org"],
+ {"includes": ['*'], "excludes": ['https://example.org'], "matches": []}
+ ),
+ (
+ ["@exclude https://example.org", "@exclude_match https://example.com"],
+ {
+ "includes": ['*'],
+ "excludes": ['https://example.org', 'https://example.com'],
+ "matches": [],
+ }
+ ),
+ # name / namespace
+ (["@name testfoo"], {"name": "testfoo", "namespace": None}),
+ (["@namespace testbar"], {"name": "test.user.js", "namespace": "testbar"}),
+ (
+ ["@name testfoo", "@namespace testbar"],
+ {"name": "testfoo", "namespace": "testbar"},
+ ),
+ # description
+ (
+ ["@description Replace ads by cat pictures"],
+ {"description": "Replace ads by cat pictures"},
+ ),
+ # noframes
+ (["@noframes"], {"runs_on_sub_frames": False}),
+ (["@noframes blabla"], {"runs_on_sub_frames": False}), # FIXME intended?
+ # requires
+ (["@require stuff.js"], {"requires": ["stuff.js"]}),
+ # qute-js-world
+ (["@qute-js-world main"], {"jsworld": "main"}),
+])
+def test_attributes(header, expected):
+ lines = [
+ "// ==UserScript==",
+ *(f'// {line}' for line in header),
+ "// ==/UserScript==",
+ "console.log('Hello World')",
+ ]
+ source = "\n".join(lines)
+ print(source)
+ script = greasemonkey.GreasemonkeyScript.parse(source, filename="test.user.js")
+
+ actual = {k: getattr(script, k) for k in expected}
+ assert actual == expected
+
+
+def test_load_error(gm_manager, wrong_path_setup):
"""Test behavior when a script fails loading."""
name = "qutebrowser test userscript"
- wrong_path = _scripts_dir() / "test1.user.js"
- wrong_path.mkdir()
- _save_script(test_gm_script, "test2.user.js")
result = gm_manager.load_scripts()
assert len(result.successful) == 1
@@ -246,6 +343,17 @@ class TestForceDocumentEnd:
script = self._get_script(namespace=namespace, name=name)
assert script.needs_document_end_workaround() == force
+ @pytest.mark.parametrize('namespace, name', [
+ ('http://userstyles.org', 'foobar'),
+ ('https://github.com/ParticleCore', 'Iridium'),
+ ('https://github.com/ParticleCore', 'Foo'),
+ ('https://example.org', 'Iridium'),
+ ])
+ def test_webkit(self, monkeypatch, namespace, name):
+ monkeypatch.setattr(objects, 'backend', usertypes.Backend.QtWebKit)
+ script = self._get_script(namespace=namespace, name=name)
+ assert not script.needs_document_end_workaround()
+
def test_required_scripts_are_included(gm_manager, download_stub, tmp_path):
test_require_script = textwrap.dedent("""
@@ -362,6 +470,38 @@ def test_shared_window_proxy(js_tester):
js_tester.run(test_script_b, expected=["test", "test"])
+@pytest.mark.parametrize("run_at, start, end, idle, with_warning", [
+ ("document-start", True, False, False, False),
+ ("document-end", False, True, False, False),
+ ("document-idle", False, False, True, False),
+ ("", False, True, False, False),
+ ("bla", False, True, False, True),
+])
+def test_run_at(gm_manager, run_at, start, end, idle, with_warning, caplog):
+ script = greasemonkey.GreasemonkeyScript.parse(
+ textwrap.dedent(f"""
+ // ==UserScript==
+ // @name run-at-tester
+ // @run-at {run_at}
+ // ==/UserScript==
+ return document.readyState;
+ """)
+ )
+
+ if with_warning:
+ with caplog.at_level(logging.WARNING):
+ gm_manager.add_script(script)
+ msg = ("Script run-at-tester has invalid run-at defined, defaulting to "
+ "document-end")
+ assert caplog.messages == [msg]
+ else:
+ gm_manager.add_script(script)
+
+ assert gm_manager._run_start == ([script] if start else [])
+ assert gm_manager._run_end == ([script] if end else [])
+ assert gm_manager._run_idle == ([script] if idle else [])
+
+
@pytest.mark.parametrize("scripts, expected", [
([], "No Greasemonkey scripts loaded"),
(
@@ -401,3 +541,50 @@ def test_load_results_errors(errors, expected):
results = greasemonkey.LoadResults()
results.errors = errors
assert results.error_str() == expected
+
+
+@pytest.mark.parametrize("quiet", [False, True])
+def test_greasemonkey_reload(gm_manager, quiet, message_mock):
+ _save_script(test_gm_script, 'test.user.js')
+ assert not gm_manager.all_scripts()
+ greasemonkey.greasemonkey_reload(quiet=quiet)
+ assert gm_manager.all_scripts()
+
+ if quiet:
+ assert not message_mock.messages
+ else:
+ msg = 'Loaded Greasemonkey scripts:\n\nqutebrowser test userscript'
+ assert message_mock.getmsg().text == msg
+
+
+@pytest.mark.parametrize("quiet", [False, True])
+def test_greasemonkey_reload_errors(gm_manager, caplog, message_mock, wrong_path_setup,
+ quiet):
+ assert not gm_manager.all_scripts()
+ with caplog.at_level(logging.ERROR):
+ greasemonkey.greasemonkey_reload(quiet=quiet)
+ assert len(gm_manager.all_scripts()) == 1
+
+ text = "Greasemonkey scripts failed to load:\n\ntest1.user.js"
+ msg = message_mock.messages[-1]
+ assert msg.level == usertypes.MessageLevel.error
+ assert msg.text.startswith(text)
+
+
+def test_init(monkeypatch, message_mock):
+ monkeypatch.setattr(greasemonkey, "gm_manager", None)
+ _save_script(test_gm_script, 'test.user.js')
+ greasemonkey.init()
+ assert not message_mock.messages
+ assert len(greasemonkey.gm_manager.all_scripts()) == 1
+
+
+def test_init_errors(monkeypatch, message_mock, wrong_path_setup, caplog):
+ monkeypatch.setattr(greasemonkey, "gm_manager", None)
+ with caplog.at_level(logging.ERROR):
+ greasemonkey.init()
+
+ assert len(greasemonkey.gm_manager.all_scripts()) == 1
+ msg = message_mock.getmsg(usertypes.MessageLevel.error)
+ text = "Greasemonkey scripts failed to load:\n\ntest1.user.js"
+ assert msg.text.startswith(text)