bdd: Allow to skip a test from JS.

This is a bit tricky since the test will actually run, but be marked as
skipped. The problem is we can't raise a pytest.skip.Exception during a test,
or it'll show up as an exception in a virtual Qt method.

Still this is better than nothing.
This commit is contained in:
Florian Bruhin 2016-01-14 18:50:36 +01:00
parent 14ff684e99
commit 9c87eaf371
3 changed files with 39 additions and 2 deletions

View File

@ -297,8 +297,7 @@ def ensure_not_logged(quteproc, pattern):
'logged'))
def javascript_message_logged(quteproc, message):
"""Make sure the given message was logged via javascript."""
quteproc.wait_for(category='js', function='javaScriptConsoleMessage',
message='[*] {}'.format(message))
quteproc.wait_for_js(message)
@bdd.then(bdd.parsers.parse('the javascript message "{message}" should not be '

View File

@ -225,6 +225,11 @@ class QuteProc(testprocess.Process):
self._httpbin.port if port is None else port,
path if path != '/' else '')
def wait_for_js(self, message):
"""Wait for the given javascript console message."""
self.wait_for(category='js', function='javaScriptConsoleMessage',
message='[*] {}'.format(message))
def _is_error_logline(self, msg):
"""Check if the given LogLine is some kind of error message."""
is_js_error = (msg.category == 'js' and
@ -233,16 +238,32 @@ class QuteProc(testprocess.Process):
value=msg.message))
return msg.loglevel > logging.INFO or is_js_error
def _is_js_skip_logline(self, msg):
"""Check if a JS snippet wanted to skip a test."""
return (msg.category == 'js' and
msg.function == 'javaScriptConsoleMessage' and
testutils.pattern_match(pattern='[*] [SKIP] *',
value=msg.message))
def after_test(self):
bad_msgs = [msg for msg in self._data
if self._is_error_logline(msg) and not msg.expected]
skip_msgs = [msg for msg in self._data
if self._is_js_skip_logline(msg)]
super().after_test()
if bad_msgs:
text = 'Logged unexpected errors:\n\n' + '\n'.join(
str(e) for e in bad_msgs)
# We'd like to use pytrace=False here but don't as a WORKAROUND
# for https://github.com/pytest-dev/pytest/issues/1316
pytest.fail(text)
elif skip_msgs:
texts = []
for msg in skip_msgs:
texts.append(msg.message.partition(' [SKIP] ')[2])
pytest.skip(', '.join(texts))
def send_cmd(self, command, count=None):
"""Send a command to the running qutebrowser instance."""

View File

@ -43,6 +43,23 @@ def test_quteproc_error_message(qtbot, quteproc, cmd):
quteproc.after_test()
@pytest.mark.parametrize('texts, expected', [
(["[SKIP] test"], "test"),
(["[SKIP] foo", "[SKIP] bar"], "foo, bar"),
])
def test_quteproc_skip_via_js(qtbot, quteproc, texts, expected):
for text in texts:
quteproc.send_cmd(':jseval console.log("{}");'.format(text))
quteproc.wait_for_js(text)
# Usually we wouldn't call this from inside a test, but here we force the
# error to occur during the test rather than at teardown time.
with pytest.raises(pytest.skip.Exception) as excinfo:
quteproc.after_test()
assert str(excinfo.value) == expected
def test_qt_log_ignore(qtbot, quteproc):
"""Make sure the test passes when logging a qt_log_ignore message."""
with qtbot.waitSignal(quteproc.got_error):