From d62ebdb926f9dc1fe9d23a29992f7a323ab2b328 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 27 Apr 2017 21:01:10 +0200 Subject: [PATCH] Make most of search BDD tests work with QtWebEngine --- qutebrowser/browser/webengine/webenginetab.py | 29 +++++++++----- qutebrowser/browser/webkit/webkittab.py | 25 +++++++++--- tests/end2end/features/search.feature | 38 +++++++++++++++++++ tests/end2end/features/test_search_bdd.py | 13 ++++--- 4 files changed, 84 insertions(+), 21 deletions(-) diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 821b73a1a..cedd59b1e 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -40,7 +40,7 @@ from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory, webenginedownloads) from qutebrowser.misc import miscwidgets from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils, - objreg, jinja) + objreg, jinja, debug) _qute_scheme_handler = None @@ -128,12 +128,21 @@ class WebEngineSearch(browsertab.AbstractSearch): super().__init__(parent) self._flags = QWebEnginePage.FindFlags(0) - def _find(self, text, flags, cb=None): - """Call findText on the widget with optional callback.""" - if cb is None: - self._widget.findText(text, flags) - else: - self._widget.findText(text, flags, cb) + def _find(self, text, flags, callback, caller): + """Call findText on the widget.""" + def wrapped_callback(found): + """Wrap the callback to do debug logging.""" + found_text = 'found' if found else "didn't find" + if flags: + flag_text = 'with flags {}'.format(debug.qflags_key( + QWebEnginePage, flags, klass=QWebEnginePage.FindFlag)) + else: + flag_text = '' + log.webview.debug(' '.join([caller, found_text, text, flag_text]) + .strip()) + if callback is not None: + callback(found) + self._widget.findText(text, flags, wrapped_callback) def search(self, text, *, ignore_case=False, reverse=False, result_cb=None): @@ -148,7 +157,7 @@ class WebEngineSearch(browsertab.AbstractSearch): self.text = text self._flags = flags - self._find(text, flags, result_cb) + self._find(text, flags, result_cb, 'search') def clear(self): self._widget.findText('') @@ -160,10 +169,10 @@ class WebEngineSearch(browsertab.AbstractSearch): flags &= ~QWebEnginePage.FindBackward else: flags |= QWebEnginePage.FindBackward - self._find(self.text, flags, result_cb) + self._find(self.text, flags, result_cb, 'prev_result') def next_result(self, *, result_cb=None): - self._find(self.text, self._flags, result_cb) + self._find(self.text, self._flags, result_cb, 'next_result') class WebEngineCaret(browsertab.AbstractCaret): diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index ef427c3be..0a844ddb0 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -36,7 +36,7 @@ from qutebrowser.browser import browsertab from qutebrowser.browser.network import proxy from qutebrowser.browser.webkit import webview, tabhistory, webkitelem from qutebrowser.browser.webkit.network import webkitqutescheme -from qutebrowser.utils import qtutils, objreg, usertypes, utils, log +from qutebrowser.utils import qtutils, objreg, usertypes, utils, log, debug def init(): @@ -104,7 +104,7 @@ class WebKitSearch(browsertab.AbstractSearch): super().__init__(parent) self._flags = QWebPage.FindFlags(0) - def _call_cb(self, callback, found): + def _call_cb(self, callback, found, text, flags, caller): """Call the given callback if it's non-None. Delays the call via a QTimer so the website is re-rendered in between. @@ -112,7 +112,22 @@ class WebKitSearch(browsertab.AbstractSearch): Args: callback: What to call found: If the text was found + text: The text searched for + flags: The flags searched with + caller: Name of the caller. """ + found_text = 'found' if found else "didn't find" + # Removing FindWrapsAroundDocument to get the same logging as with + # QtWebEngine + debug_flags = debug.qflags_key( + QWebPage, flags & ~QWebPage.FindWrapsAroundDocument, + klass=QWebPage.FindFlag) + if debug_flags != '0x0000': + flag_text = 'with flags {}'.format(debug_flags) + else: + flag_text = '' + log.webview.debug(' '.join([caller, found_text, text, flag_text]) + .strip()) if callback is not None: QTimer.singleShot(0, functools.partial(callback, found)) @@ -137,11 +152,11 @@ class WebKitSearch(browsertab.AbstractSearch): self._widget.findText(text, flags | QWebPage.HighlightAllOccurrences) self.text = text self._flags = flags - self._call_cb(result_cb, found) + self._call_cb(result_cb, found, text, flags, 'search') def next_result(self, *, result_cb=None): found = self._widget.findText(self.text, self._flags) - self._call_cb(result_cb, found) + self._call_cb(result_cb, found, self.text, self._flags, 'next_result') def prev_result(self, *, result_cb=None): # The int() here makes sure we get a copy of the flags. @@ -151,7 +166,7 @@ class WebKitSearch(browsertab.AbstractSearch): else: flags |= QWebPage.FindBackward found = self._widget.findText(self.text, flags) - self._call_cb(result_cb, found) + self._call_cb(result_cb, found, self.text, flags, 'prev_result') class WebKitCaret(browsertab.AbstractCaret): diff --git a/tests/end2end/features/search.feature b/tests/end2end/features/search.feature index aeea2e4e8..285b3cbf8 100644 --- a/tests/end2end/features/search.feature +++ b/tests/end2end/features/search.feature @@ -11,37 +11,45 @@ Feature: Searching on a page Scenario: Searching text When I run :search foo + And I wait for "search found foo" in the log Then "foo" should be found Scenario: Searching twice When I run :search foo + And I wait for "search found foo" in the log And I run :search bar + And I wait for "search found bar" in the log Then "Bar" should be found Scenario: Searching with --reverse When I set general -> ignore-case to true And I run :search -r foo + And I wait for "search found foo with flags FindBackward" in the log Then "Foo" should be found Scenario: Searching without matches When I run :search doesnotmatch + And I wait for "search didn't find doesnotmatch" in the log Then the warning "Text 'doesnotmatch' not found on page!" should be shown @xfail_norun Scenario: Searching with / and spaces at the end (issue 874) When I run :set-cmd-text -s /space And I run :command-accept + And I wait for "search found space " in the log Then "space " should be found Scenario: Searching with / and slash in search term (issue 507) When I run :set-cmd-text -s //slash And I run :command-accept + And I wait for "search found /slash" in the log Then "/slash" should be found # This doesn't work because this is QtWebKit behavior. @xfail_norun Scenario: Searching text with umlauts When I run :search blub + And I wait for "search didn't find blub" in the log Then the warning "Text 'blub' not found on page!" should be shown ## ignore-case @@ -49,21 +57,25 @@ Feature: Searching on a page Scenario: Searching text with ignore-case = true When I set general -> ignore-case to true And I run :search bar + And I wait for "search found bar" in the log Then "Bar" should be found Scenario: Searching text with ignore-case = false When I set general -> ignore-case to false And I run :search bar + And I wait for "search found bar with flags FindCaseSensitively" in the log Then "bar" should be found Scenario: Searching text with ignore-case = smart (lower-case) When I set general -> ignore-case to smart And I run :search bar + And I wait for "search found bar" in the log Then "Bar" should be found Scenario: Searching text with ignore-case = smart (upper-case) When I set general -> ignore-case to smart And I run :search Foo + And I wait for "search found Foo with flags FindCaseSensitively" in the log Then "Foo" should be found # even though foo was first ## :search-next @@ -71,19 +83,25 @@ Feature: Searching on a page Scenario: Jumping to next match When I set general -> ignore-case to true And I run :search foo + And I wait for "search found foo" in the log And I run :search-next + And I wait for "next_result found foo" in the log Then "Foo" should be found Scenario: Jumping to next match with count When I set general -> ignore-case to true And I run :search baz + And I wait for "search found baz" in the log And I run :search-next with count 2 + And I wait for "next_result found baz" in the log Then "BAZ" should be found Scenario: Jumping to next match with --reverse When I set general -> ignore-case to true And I run :search --reverse foo + And I wait for "search found foo with flags FindBackward" in the log And I run :search-next + And I wait for "next_result found foo with flags FindBackward" in the log Then "foo" should be found Scenario: Jumping to next match without search @@ -95,16 +113,20 @@ Feature: Searching on a page Scenario: Repeating search in a second tab (issue #940) When I open data/search.html in a new tab And I run :search foo + And I wait for "search found foo" in the log And I run :tab-prev And I run :search-next + And I wait for "search found foo" in the log Then "foo" should be found # https://github.com/qutebrowser/qutebrowser/issues/2438 Scenario: Jumping to next match after clearing When I set general -> ignore-case to true And I run :search foo + And I wait for "search found foo" in the log And I run :search And I run :search-next + And I wait for "next_result found foo" in the log Then "foo" should be found ## :search-prev @@ -112,23 +134,33 @@ Feature: Searching on a page Scenario: Jumping to previous match When I set general -> ignore-case to true And I run :search foo + And I wait for "search found foo" in the log And I run :search-next + And I wait for "next_result found foo" in the log And I run :search-prev + And I wait for "prev_result found foo with flags FindBackward" in the log Then "foo" should be found Scenario: Jumping to previous match with count When I set general -> ignore-case to true And I run :search baz + And I wait for "search found baz" in the log And I run :search-next + And I wait for "next_result found baz" in the log And I run :search-next + And I wait for "next_result found baz" in the log And I run :search-prev with count 2 + And I wait for "prev_result found baz with flags FindBackward" in the log Then "baz" should be found Scenario: Jumping to previous match with --reverse When I set general -> ignore-case to true And I run :search --reverse foo + And I wait for "search found foo with flags FindBackward" in the log And I run :search-next + And I wait for "next_result found foo with flags FindBackward" in the log And I run :search-prev + And I wait for "prev_result found foo" in the log Then "Foo" should be found Scenario: Jumping to previous match without search @@ -141,14 +173,20 @@ Feature: Searching on a page Scenario: Wrapping around page When I run :search foo + And I wait for "search found foo" in the log And I run :search-next + And I wait for "next_result found foo" in the log And I run :search-next + And I wait for "next_result found foo" in the log Then "foo" should be found Scenario: Wrapping around page with --reverse When I run :search --reverse foo + And I wait for "search found foo with flags FindBackward" in the log And I run :search-next + And I wait for "next_result found foo with flags FindBackward" in the log And I run :search-next + And I wait for "next_result found foo with flags FindBackward" in the log Then "Foo" should be found # TODO: wrapping message with scrolling diff --git a/tests/end2end/features/test_search_bdd.py b/tests/end2end/features/test_search_bdd.py index d9866fe03..caf592ce6 100644 --- a/tests/end2end/features/test_search_bdd.py +++ b/tests/end2end/features/test_search_bdd.py @@ -19,7 +19,6 @@ import json -import pytest import pytest_bdd as bdd # pylint: disable=unused-import @@ -28,14 +27,16 @@ from end2end.features.test_yankpaste_bdd import init_fake_clipboard @bdd.then(bdd.parsers.parse('"{text}" should be found')) def check_found_text(request, quteproc, text): + if request.config.webengine: + # WORKAROUND + # This probably should work with Qt 5.9: + # https://codereview.qt-project.org/#/c/192920/ + # https://codereview.qt-project.org/#/c/192921/ + # https://bugreports.qt.io/browse/QTBUG-53134 + return quteproc.send_cmd(':yank selection') quteproc.wait_for(message='Setting fake clipboard: {}'.format( json.dumps(text))) -# After cancelling the search, the text (sometimes?) shows up as selected. -# However, we can't get it via ':yank selection' it seems? -pytestmark = pytest.mark.qtwebengine_skip("Searched text is not selected...") - - bdd.scenarios('search.feature')