summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2019-07-11 09:45:33 +0200
committerFlorian Bruhin <me@the-compiler.org>2019-07-11 09:45:33 +0200
commit94f576d84cf4eb51c46596eed7ccd87105993a0a (patch)
treedfa7c0c7a16e349133c7a3a41a37a80fecb4f794
parent755a2999e2deb3555d6b5611c81f024081ee2d27 (diff)
parent1a359467949a8ba2a828e30539377cf19911bf33 (diff)
downloadqutebrowser-94f576d84cf4eb51c46596eed7ccd87105993a0a.tar.gz
qutebrowser-94f576d84cf4eb51c46596eed7ccd87105993a0a.zip
Merge branch 'prompt-save'
-rw-r--r--doc/help/commands.asciidoc5
-rw-r--r--doc/help/settings.asciidoc2
-rw-r--r--qutebrowser/browser/shared.py5
-rw-r--r--qutebrowser/browser/webengine/webenginetab.py6
-rw-r--r--qutebrowser/browser/webkit/webpage.py7
-rw-r--r--qutebrowser/config/configdata.yml2
-rw-r--r--qutebrowser/mainwindow/prompt.py71
-rw-r--r--qutebrowser/utils/message.py13
-rw-r--r--qutebrowser/utils/usertypes.py5
-rw-r--r--tests/end2end/features/conftest.py8
-rw-r--r--tests/end2end/features/downloads.feature22
-rw-r--r--tests/end2end/features/prompts.feature31
-rw-r--r--tests/end2end/features/test_downloads_bdd.py4
-rw-r--r--tests/end2end/fixtures/quteprocess.py15
14 files changed, 154 insertions, 42 deletions
diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc
index ae9ada9fd..c34cfe602 100644
--- a/doc/help/commands.asciidoc
+++ b/doc/help/commands.asciidoc
@@ -1744,7 +1744,7 @@ How many blocks to move.
[[prompt-accept]]
=== prompt-accept
-Syntax: +:prompt-accept ['value']+
+Syntax: +:prompt-accept [*--save*] ['value']+
Accept the current prompt.
@@ -1752,6 +1752,9 @@ Accept the current prompt.
* +'value'+: If given, uses this value instead of the entered one. For boolean prompts, "yes"/"no" are accepted as value.
+==== optional arguments
+* +*-s*+, +*--save*+: Save the value to the config.
+
[[prompt-item-focus]]
=== prompt-item-focus
Syntax: +:prompt-item-focus 'which'+
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 438a6c2b1..f6115b076 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -703,6 +703,8 @@ Default:
* +pass:[&lt;Alt-Y&gt;]+: +pass:[prompt-yank]+
* +pass:[&lt;Escape&gt;]+: +pass:[leave-mode]+
* +pass:[&lt;Return&gt;]+: +pass:[prompt-accept]+
+* +pass:[N]+: +pass:[prompt-accept --save no]+
+* +pass:[Y]+: +pass:[prompt-accept --save yes]+
* +pass:[n]+: +pass:[prompt-accept no]+
* +pass:[y]+: +pass:[prompt-accept yes]+
diff --git a/qutebrowser/browser/shared.py b/qutebrowser/browser/shared.py
index 194dc5b36..4d75de465 100644
--- a/qutebrowser/browser/shared.py
+++ b/qutebrowser/browser/shared.py
@@ -225,7 +225,7 @@ def feature_permission(url, option, msg, yes_action, no_action, abort_on,
if blocking:
answer = message.ask(abort_on=abort_on, title='Permission request',
- text=text, url=urlstr,
+ text=text, url=urlstr, option=option,
mode=usertypes.PromptMode.yesno)
if answer:
yes_action()
@@ -236,7 +236,8 @@ def feature_permission(url, option, msg, yes_action, no_action, abort_on,
return message.confirm_async(
yes_action=yes_action, no_action=no_action,
cancel_action=no_action, abort_on=abort_on,
- title='Permission request', text=text, url=urlstr)
+ title='Permission request', text=text, url=urlstr,
+ option=option)
elif config_val:
yes_action()
return None
diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py
index 6046b0a02..ac23a5804 100644
--- a/qutebrowser/browser/webengine/webenginetab.py
+++ b/qutebrowser/browser/webengine/webenginetab.py
@@ -827,7 +827,7 @@ class _WebEnginePermissions(QObject):
QWebEnginePage.PermissionDeniedByUser)
question = shared.feature_permission(
- url=url,
+ url=url.adjusted(QUrl.RemovePath),
option=self._options[feature], msg=self._messages[feature],
yes_action=yes_action, no_action=no_action,
abort_on=[self._tab.abort_questions])
@@ -854,7 +854,7 @@ class _WebEnginePermissions(QObject):
def _on_quota_requested(self, request):
size = utils.format_size(request.requestedSize())
shared.feature_permission(
- url=request.origin(),
+ url=request.origin().adjusted(QUrl.RemovePath),
option='content.persistent_storage',
msg='use {} of persistent storage'.format(size),
yes_action=request.accept, no_action=request.reject,
@@ -863,7 +863,7 @@ class _WebEnginePermissions(QObject):
def _on_register_protocol_handler_requested(self, request):
shared.feature_permission(
- url=request.origin(),
+ url=request.origin().adjusted(QUrl.RemovePath),
option='content.register_protocol_handler',
msg='open all {} links'.format(request.scheme()),
yes_action=request.accept, no_action=request.reject,
diff --git a/qutebrowser/browser/webkit/webpage.py b/qutebrowser/browser/webkit/webpage.py
index 1b4b85c65..f591b9754 100644
--- a/qutebrowser/browser/webkit/webpage.py
+++ b/qutebrowser/browser/webkit/webpage.py
@@ -346,8 +346,13 @@ class BrowserPage(QWebPage):
self.setFeaturePermission, frame, feature,
QWebPage.PermissionDeniedByUser)
+ url = frame.url().adjusted(QUrl.RemoveUserInfo |
+ QUrl.RemovePath |
+ QUrl.RemoveQuery |
+ QUrl.RemoveFragment)
+
question = shared.feature_permission(
- url=frame.url(),
+ url=url,
option=options[feature], msg=messages[feature],
yes_action=yes_action, no_action=no_action,
abort_on=[self.shutting_down, self.loadStarted])
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 50b8221a1..2a4800a11 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -2825,6 +2825,8 @@ bindings.default:
<Return>: prompt-accept
y: prompt-accept yes
n: prompt-accept no
+ Y: prompt-accept --save yes
+ N: prompt-accept --save no
<Alt-Y>: prompt-yank
<Alt-Shift-Y>: prompt-yank --sel
<Escape>: leave-mode
diff --git a/qutebrowser/mainwindow/prompt.py b/qutebrowser/mainwindow/prompt.py
index 9fd3da8dd..623e3ecad 100644
--- a/qutebrowser/mainwindow/prompt.py
+++ b/qutebrowser/mainwindow/prompt.py
@@ -32,10 +32,11 @@ from PyQt5.QtWidgets import (QWidget, QGridLayout, QVBoxLayout, QLineEdit,
QSpacerItem)
from qutebrowser.browser import downloads
-from qutebrowser.config import config
+from qutebrowser.config import config, configtypes, configexc
from qutebrowser.utils import usertypes, log, utils, qtutils, objreg, message
from qutebrowser.keyinput import modeman
from qutebrowser.api import cmdutils
+from qutebrowser.utils import urlmatch
prompt_queue = None
@@ -55,7 +56,7 @@ class Error(Exception):
"""Base class for errors in this module."""
-class UnsupportedOperationError(Exception):
+class UnsupportedOperationError(Error):
"""Raised when the prompt class doesn't support the requested operation."""
@@ -377,7 +378,7 @@ class PromptContainer(QWidget):
@cmdutils.register(instance='prompt-container', scope='window',
modes=[usertypes.KeyMode.prompt,
usertypes.KeyMode.yesno])
- def prompt_accept(self, value=None):
+ def prompt_accept(self, value=None, *, save=False):
"""Accept the current prompt.
//
@@ -388,12 +389,15 @@ class PromptContainer(QWidget):
Args:
value: If given, uses this value instead of the entered one.
For boolean prompts, "yes"/"no" are accepted as value.
+ save: Save the value to the config.
"""
question = self._prompt.question
+
try:
- done = self._prompt.accept(value)
+ done = self._prompt.accept(value, save=save)
except Error as e:
raise cmdutils.CommandError(str(e))
+
if done:
message.global_bridge.prompt_done.emit(self._prompt.KEY_MODE)
question.done()
@@ -545,7 +549,12 @@ class _BasePrompt(QWidget):
self._vbox.addLayout(self._key_grid)
- def accept(self, value=None):
+ def _check_save_support(self, save):
+ if save:
+ raise UnsupportedOperationError("Saving answers is only possible "
+ "with yes/no prompts.")
+
+ def accept(self, value=None, save=False):
raise NotImplementedError
def download_open(self, cmdline, pdfjs):
@@ -577,7 +586,8 @@ class LineEditPrompt(_BasePrompt):
self.setFocusProxy(self._lineedit)
self._init_key_label()
- def accept(self, value=None):
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
text = value if value is not None else self._lineedit.text()
self.question.answer = text
return True
@@ -693,7 +703,8 @@ class FilenamePrompt(_BasePrompt):
self._file_model.directoryLoaded.connect(
lambda: self._file_model.sort(0))
- def accept(self, value=None):
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
text = value if value is not None else self._lineedit.text()
text = downloads.transform_path(text)
if text is None:
@@ -763,8 +774,8 @@ class DownloadFilenamePrompt(FilenamePrompt):
super().__init__(question, parent)
self._file_model.setFilter(QDir.AllDirs | QDir.Drives | QDir.NoDot)
- def accept(self, value=None):
- done = super().accept(value)
+ def accept(self, value=None, save=False):
+ done = super().accept(value, save)
answer = self.question.answer
if answer is not None:
self.question.answer = downloads.FileDownloadTarget(answer)
@@ -817,7 +828,8 @@ class AuthenticationPrompt(_BasePrompt):
assert not question.default, question.default
self.setFocusProxy(self._user_lineedit)
- def accept(self, value=None):
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
if value is not None:
if ':' not in value:
raise Error("Value needs to be in the format "
@@ -860,7 +872,14 @@ class YesNoPrompt(_BasePrompt):
self._init_texts(question)
self._init_key_label()
- def accept(self, value=None):
+ def _check_save_support(self, save):
+ if save and self.question.option is None:
+ raise Error("No setting available to save the answer for this "
+ "question.")
+
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
+
if value is None:
if self.question.default is None:
raise Error("No default value was set for this question!")
@@ -871,14 +890,30 @@ class YesNoPrompt(_BasePrompt):
self.question.answer = False
else:
raise Error("Invalid value {} - expected yes/no!".format(value))
+
+ if save:
+ opt = config.instance.get_opt(self.question.option)
+ assert isinstance(opt.typ, configtypes.Bool)
+ pattern = urlmatch.UrlPattern(self.question.url)
+
+ try:
+ config.instance.set_obj(opt.name, self.question.answer,
+ pattern=pattern, save_yaml=True)
+ except configexc.Error as e:
+ raise Error(str(e))
+
return True
def _allowed_commands(self):
- cmds = [
- ('prompt-accept yes', "Yes"),
- ('prompt-accept no', "No"),
- ('prompt-yank', "Yank URL"),
- ]
+ cmds = []
+
+ cmds.append(('prompt-accept yes', "Yes"))
+ if self.question.option is not None:
+ cmds.append(('prompt-accept --save yes', "Always"))
+
+ cmds.append(('prompt-accept no', "No"))
+ if self.question.option is not None:
+ cmds.append(('prompt-accept --save no', "Never"))
if self.question.default is not None:
assert self.question.default in [True, False]
@@ -886,6 +921,7 @@ class YesNoPrompt(_BasePrompt):
cmds.append(('prompt-accept', "Use default ({})".format(default)))
cmds.append(('leave-mode', "Abort"))
+ cmds.append(('prompt-yank', "Yank URL"))
return cmds
@@ -898,7 +934,8 @@ class AlertPrompt(_BasePrompt):
self._init_texts(question)
self._init_key_label()
- def accept(self, value=None):
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
if value is not None:
raise Error("No value is permitted with alert prompts!")
# Simply mark prompt as done without setting self.question.answer
diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py
index b663cbfa4..155547abd 100644
--- a/qutebrowser/utils/message.py
+++ b/qutebrowser/utils/message.py
@@ -83,7 +83,7 @@ def info(message: str, *, replace: bool = False) -> None:
def _build_question(title, text=None, *, mode, default=None, abort_on=(),
- url=None):
+ url=None, option=None):
"""Common function for ask/ask_async."""
if not isinstance(mode, usertypes.PromptMode):
raise TypeError("Mode {} is no PromptMode member!".format(mode))
@@ -93,6 +93,14 @@ def _build_question(title, text=None, *, mode, default=None, abort_on=(),
question.mode = mode
question.default = default
question.url = url
+
+ if option is not None:
+ if mode != usertypes.PromptMode.yesno:
+ raise ValueError("Can only 'option' with PromptMode.yesno")
+ if url is None:
+ raise ValueError("Need 'url' given when 'option' is given")
+ question.option = option
+
for sig in abort_on:
sig.connect(question.abort)
return question
@@ -106,6 +114,8 @@ def ask(*args, **kwargs):
mode: A PromptMode.
default: The default value to display.
text: Additional text to show
+ option: The option for always/never question answers.
+ Only available with PromptMode.yesno.
abort_on: A list of signals which abort the question if emitted.
Return:
@@ -145,6 +155,7 @@ def confirm_async(*, yes_action, no_action=None, cancel_action=None,
cancel_action: Callable to be called when the user cancelled the
question.
default: True/False to set a default value, or None.
+ option: The option for always/never question answers.
text: Additional text to show.
Return:
diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py
index 03bd44869..0bb7badc8 100644
--- a/qutebrowser/utils/usertypes.py
+++ b/qutebrowser/utils/usertypes.py
@@ -309,6 +309,7 @@ class Question(QObject):
title: The question title to show.
text: The prompt text to display to the user.
url: Any URL referenced in prompts.
+ option: Boolean option to be set when answering always/never.
answer: The value the user entered (as password for user_pwd).
is_aborted: Whether the question was aborted.
interrupted: Whether the question was interrupted by another one.
@@ -340,13 +341,15 @@ class Question(QObject):
self.title = None
self.text = None
self.url = None
+ self.option = None
self.answer = None
self.is_aborted = False
self.interrupted = False
def __repr__(self):
return utils.get_repr(self, title=self.title, text=self.text,
- mode=self._mode, default=self.default)
+ mode=self._mode, default=self.default,
+ option=self.option)
@property
def mode(self):
diff --git a/tests/end2end/features/conftest.py b/tests/end2end/features/conftest.py
index 95e9f8022..2774b0961 100644
--- a/tests/end2end/features/conftest.py
+++ b/tests/end2end/features/conftest.py
@@ -676,3 +676,11 @@ def check_not_scrolled(request, quteproc):
def check_option(quteproc, option, value):
actual_value = quteproc.get_setting(option)
assert actual_value == value
+
+
+@bdd.then(bdd.parsers.parse("the per-domain option {option} should be set to "
+ "{value} for {pattern}"))
+def check_option_per_domain(quteproc, option, value, pattern, server):
+ pattern = pattern.replace('(port)', str(server.port))
+ actual_value = quteproc.get_setting(option, pattern=pattern)
+ assert actual_value == value
diff --git a/tests/end2end/features/downloads.feature b/tests/end2end/features/downloads.feature
index 563308e42..e14a1886a 100644
--- a/tests/end2end/features/downloads.feature
+++ b/tests/end2end/features/downloads.feature
@@ -79,7 +79,7 @@ Feature: Downloading things from a website.
And I set downloads.location.prompt to true
And I open data/downloads/issue1243.html
And I hint with args "links download" and follow a
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='qutebrowser-download' mode=<PromptMode.download: 5> text=* title='Save file to:'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='qutebrowser-download' mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log
Then the error "Download error: No handler found for qute://" should be shown
And "NotFoundError while handling qute://* URL" should be logged
@@ -88,7 +88,7 @@ Feature: Downloading things from a website.
And I set downloads.location.prompt to true
And I open data/data_link.html
And I hint with args "links download" and follow a
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='binary blob' mode=<PromptMode.download: 5> text=* title='Save file to:'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='binary blob' mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log
And I run :leave-mode
Then no crash should happen
@@ -178,7 +178,7 @@ Feature: Downloading things from a website.
Scenario: Downloading a file to a reserved path
When I set downloads.location.prompt to true
And I open data/downloads/download.bin without waiting
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> text='Please enter a location for <b>http://localhost:*/data/downloads/download.bin</b>' title='Save file to:'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text='Please enter a location for <b>http://localhost:*/data/downloads/download.bin</b>' title='Save file to:'>, *" in the log
And I run :prompt-accept COM1
And I run :leave-mode
Then the error "Invalid filename" should be shown
@@ -187,7 +187,7 @@ Feature: Downloading things from a website.
Scenario: Downloading a file to a drive-relative working directory
When I set downloads.location.prompt to true
And I open data/downloads/download.bin without waiting
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> text='Please enter a location for <b>http://localhost:*/data/downloads/download.bin</b>' title='Save file to:'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text='Please enter a location for <b>http://localhost:*/data/downloads/download.bin</b>' title='Save file to:'>, *" in the log
And I run :prompt-accept C:foobar
And I run :leave-mode
Then the error "Invalid filename" should be shown
@@ -279,14 +279,14 @@ Feature: Downloading things from a website.
Scenario: :download with a filename and directory which doesn't exist
When I run :download --dest (tmpdir)(dirsep)downloads(dirsep)somedir(dirsep)file http://localhost:(port)/data/downloads/download.bin
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> text='<b>*</b> does not exist. Create it?' title='Create directory?'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> option=None text='<b>*</b> does not exist. Create it?' title='Create directory?'>, *" in the log
And I run :prompt-accept yes
And I wait until the download is finished
Then the downloaded file somedir/file should exist
Scenario: :download with a directory which doesn't exist
When I run :download --dest (tmpdir)(dirsep)downloads(dirsep)somedir(dirsep) http://localhost:(port)/data/downloads/download.bin
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> text='<b>*</b> does not exist. Create it?' title='Create directory?'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> option=None text='<b>*</b> does not exist. Create it?' title='Create directory?'>, *" in the log
And I run :prompt-accept yes
And I wait until the download is finished
Then the downloaded file somedir/download.bin should exist
@@ -311,13 +311,13 @@ Feature: Downloading things from a website.
When I set downloads.location.prompt to true
And I open data/title.html
And I run :download --mhtml
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> text='Please enter a location for <b>http://localhost:*/data/title.html</b>' title='Save file to:'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text='Please enter a location for <b>http://localhost:*/data/title.html</b>' title='Save file to:'>, *" in the log
And I run :prompt-accept
And I wait for "File successfully written." in the log
And I run :download --mhtml
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> text='Please enter a location for <b>http://localhost:*/data/title.html</b>' title='Save file to:'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text='Please enter a location for <b>http://localhost:*/data/title.html</b>' title='Save file to:'>, *" in the log
And I run :prompt-accept
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> text='<b>*</b> already exists. Overwrite?' title='Overwrite existing file?'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> option=None text='<b>*</b> already exists. Overwrite?' title='Overwrite existing file?'>, *" in the log
And I run :prompt-accept yes
And I wait for "File successfully written." in the log
Then the downloaded file Test title.mhtml should exist
@@ -679,9 +679,9 @@ Feature: Downloading things from a website.
Scenario: Answering a question for a cancelled download (#415)
When I set downloads.location.prompt to true
And I run :download http://localhost:(port)/data/downloads/download.bin
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> text=* title='Save file to:'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log
And I run :download http://localhost:(port)/data/downloads/download2.bin
- And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> text=* title='Save file to:'>, *" in the log
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log
And I run :download-cancel with count 2
And I run :prompt-accept
And I wait until the download is finished
diff --git a/tests/end2end/features/prompts.feature b/tests/end2end/features/prompts.feature
index 008b5b906..85698dc05 100644
--- a/tests/end2end/features/prompts.feature
+++ b/tests/end2end/features/prompts.feature
@@ -227,6 +227,15 @@ Feature: Prompts
And I run :prompt-accept no
Then the javascript message "geolocation permission denied" should be logged
+ Scenario: geolocation with ask -> false and save
+ When I set content.geolocation to ask
+ And I open data/prompt/geolocation.html in a new tab
+ And I run :click-element id button
+ And I wait for a prompt
+ And I run :prompt-accept --save no
+ Then the javascript message "geolocation permission denied" should be logged
+ And the per-domain option content.geolocation should be set to false for http://localhost:(port)
+
Scenario: geolocation with ask -> abort
When I set content.geolocation to ask
And I open data/prompt/geolocation.html in a new tab
@@ -264,6 +273,17 @@ Feature: Prompts
Then the javascript message "notification permission denied" should be logged
@qtwebengine_notifications
+ Scenario: notifications with ask -> false and save
+ Given I have a fresh instance
+ When I set content.notifications to ask
+ And I open data/prompt/notifications.html in a new tab
+ And I run :click-element id button
+ And I wait for a prompt
+ And I run :prompt-accept --save no
+ Then the javascript message "notification permission denied" should be logged
+ And the per-domain option content.notifications should be set to false for http://localhost:(port)
+
+ @qtwebengine_notifications
Scenario: notifications with ask -> true
Given I have a fresh instance
When I set content.notifications to ask
@@ -273,6 +293,17 @@ Feature: Prompts
And I run :prompt-accept yes
Then the javascript message "notification permission granted" should be logged
+ @qtwebengine_notifications
+ Scenario: notifications with ask -> true and save
+ Given I have a fresh instance
+ When I set content.notifications to ask
+ And I open data/prompt/notifications.html in a new tab
+ And I run :click-element id button
+ And I wait for a prompt
+ And I run :prompt-accept --save yes
+ Then the javascript message "notification permission granted" should be logged
+ And the per-domain option content.notifications should be set to true for http://localhost:(port)
+
# This actually gives us a denied rather than an aborted
@xfail_norun
Scenario: notifications with ask -> abort
diff --git a/tests/end2end/features/test_downloads_bdd.py b/tests/end2end/features/test_downloads_bdd.py
index 4c4ae3202..230903f5b 100644
--- a/tests/end2end/features/test_downloads_bdd.py
+++ b/tests/end2end/features/test_downloads_bdd.py
@@ -28,8 +28,8 @@ bdd.scenarios('downloads.feature')
PROMPT_MSG = ("Asking question <qutebrowser.utils.usertypes.Question "
- "default={!r} mode=<PromptMode.download: 5> text=* "
- "title='Save file to:'>, *")
+ "default={!r} mode=<PromptMode.download: 5> option=None "
+ "text=* title='Save file to:'>, *")
@bdd.given("I set up a temporary download dir")
diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py
index 9cad17096..c6c6bbcb9 100644
--- a/tests/end2end/fixtures/quteprocess.py
+++ b/tests/end2end/fixtures/quteprocess.py
@@ -681,12 +681,21 @@ class QuteProc(testprocess.Process):
return self.wait_for(category='commands', module='command',
function='run', message='command called: *')
- def get_setting(self, opt):
+ def get_setting(self, opt, pattern=None):
"""Get the value of a qutebrowser setting."""
- self.send_cmd(':set {}?'.format(opt))
+ if pattern is None:
+ cmd = ':set {}?'.format(opt)
+ else:
+ cmd = ':set -u {} {}?'.format(pattern, opt)
+
+ self.send_cmd(cmd)
msg = self.wait_for(loglevel=logging.INFO, category='message',
message='{} = *'.format(opt))
- return msg.message.split(' = ')[1]
+
+ if pattern is None:
+ return msg.message.split(' = ')[1]
+ else:
+ return msg.message.split(' = ')[1].split(' for ')[0]
def set_setting(self, option, value):
# \ and " in a value should be treated literally, so escape them