From af875f4b8f3b9ccc784601749de99ffd80e17661 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 20 Nov 2015 07:05:16 +0100 Subject: [PATCH] Add a :fake-key command. Closes #556. See #551. --- CHANGELOG.asciidoc | 2 ++ doc/help/commands.asciidoc | 15 ++++++++++ qutebrowser/browser/commands.py | 37 ++++++++++++++++++++++++ tests/integration/data/misc/fakekey.html | 22 ++++++++++++++ tests/integration/features/misc.feature | 34 ++++++++++++++++++++++ 5 files changed, 110 insertions(+) create mode 100644 tests/integration/data/misc/fakekey.html diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index f17ae552c..51a90d33a 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -51,6 +51,8 @@ Added - `:set-cmd-text` has a new `--append` argument to append to the current statusbar text. - qutebrowser now uses `~/.netrc` if available to authenticate via HTTP. +- New `:fake-key` command to send a fake keypress to a website or to + qutebrowser. Changed ~~~~~~~ diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 98081479d..559011aaf 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -19,6 +19,7 @@ |<>|Open the last/[count]th download. |<>|Remove the last/[count]th download from the list. |<>|Retry the first failed/[count]th download. +|<>|Send a fake keypress or key string to the website or qutebrowser. |<>|Go forward in the history of the current tab. |<>|Toggle fullscreen mode. |<>|Show help about a command or setting. @@ -197,6 +198,20 @@ Retry the first failed/[count]th download. ==== count The index of the download to cancel. +[[fake-key]] +=== fake-key +Syntax: +:fake-key [*--global*] 'keystring'+ + +Send a fake keypress or key string to the website or qutebrowser. + +:fake-key xy - sends the keychain 'xy' :fake-key - sends Ctrl-x :fake-key - sends the escape key + +==== positional arguments +* +'keystring'+: The keystring to send. + +==== optional arguments +* +*-g*+, +*--global*+: If given, the keys are sent to the qutebrowser UI. + [[forward]] === forward Syntax: +:forward [*--tab*] [*--bg*] [*--window*]+ diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 92b9edb82..3cd4bcd9f 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1684,3 +1684,40 @@ class CommandDispatcher: message.info(self._win_id, out[:5000] + ' [...trimmed...]') else: message.info(self._win_id, out) + + @cmdutils.register(instance='command-dispatcher', scope='window') + def fake_key(self, keystring, global_=False): + """Send a fake keypress or key string to the website or qutebrowser. + + :fake-key xy - sends the keychain 'xy' + :fake-key - sends Ctrl-x + :fake-key - sends the escape key + + Args: + keystring: The keystring to send. + global_: If given, the keys are sent to the qutebrowser UI. + """ + try: + keyinfos = utils.parse_keystring(keystring) + except utils.KeyParseError as e: + raise cmdexc.CommandError(str(e)) + + for keyinfo in keyinfos: + press_event = QKeyEvent(QEvent.KeyPress, keyinfo.key, + keyinfo.modifiers, keyinfo.text) + release_event = QKeyEvent(QEvent.KeyRelease, keyinfo.key, + keyinfo.modifiers, keyinfo.text) + + if global_: + receiver = QApplication.focusWindow() + if receiver is None: + raise cmdexc.CommandError("No focused window!") + else: + try: + receiver = objreg.get('webview', scope='tab', + tab='current') + except KeyError: + raise cmdexc.CommandError("No focused webview!") + + QApplication.postEvent(receiver, press_event) + QApplication.postEvent(receiver, release_event) diff --git a/tests/integration/data/misc/fakekey.html b/tests/integration/data/misc/fakekey.html new file mode 100644 index 000000000..9f12d238a --- /dev/null +++ b/tests/integration/data/misc/fakekey.html @@ -0,0 +1,22 @@ + + + + + Fake keypresses + + + + This page logs keypresses via console.log. + + diff --git a/tests/integration/features/misc.feature b/tests/integration/features/misc.feature index 85c058334..269b3aeaf 100644 --- a/tests/integration/features/misc.feature +++ b/tests/integration/features/misc.feature @@ -113,3 +113,37 @@ Feature: Various utility commands. And I run :inspector And I run :inspector Then no crash should happen + + # :fake-key + + Scenario: :fake-key with an unparsable key + When I run :fake-key + Then the error "Could not parse 'blub': Got unknown key." should be shown. + + Scenario: :fake-key sending key to the website + When I set general -> log-javascript-console to true + And I open data/misc/fakekey.html + And I run :fake-key x + Then the javascript message "key press: 88" should be logged + And the javascript message "key release: 88" should be logged + + Scenario: :fake-key sending special key to the website + When I set general -> log-javascript-console to true + And I open data/misc/fakekey.html + And I run :fake-key + Then the javascript message "key press: 27" should be logged + And the javascript message "key release: 27" should be logged + + Scenario: :fake-key sending keychain to the website + When I set general -> log-javascript-console to true + And I open data/misc/fakekey.html + And I run :fake-key xy + Then the javascript message "key press: 88" should be logged + And the javascript message "key release: 88" should be logged + And the javascript message "key press: 89" should be logged + And the javascript message "key release: 89" should be logged + + Scenario: :fake-key sending keypress to qutebrowser + When I run :fake-key -g x + And I wait for "got keypress in mode KeyMode.normal - delegating to " in the log + Then no crash should happen