diff --git a/tests/browser/test_webelem.py b/tests/browser/test_webelem.py index d88bbc6aa..72ab7274f 100644 --- a/tests/browser/test_webelem.py +++ b/tests/browser/test_webelem.py @@ -25,10 +25,12 @@ from unittest import mock import collections.abc import operator import itertools +import binascii +import os.path import hypothesis import hypothesis.strategies -from PyQt5.QtCore import QRect, QPoint +from PyQt5.QtCore import PYQT_VERSION, QRect, QPoint from PyQt5.QtWebKit import QWebElement import pytest @@ -525,21 +527,63 @@ class TestJavascriptEscape: """Test javascript escaping with some expected outcomes.""" assert webelem.javascript_escape(before) == after - def _test_escape(self, text, webframe): + def _test_escape(self, text, qtbot, webframe): """Helper function for test_real_escape*.""" + try: + self._test_escape_simple(text, webframe) + except AssertionError: + # Try another method if the simple method failed. + # + # See _test_escape_hexlified documentation on why this is + # necessary. + self._test_escape_hexlified(text, qtbot, webframe) + + def _test_escape_hexlified(self, text, qtbot, webframe): + """Test conversion by hexlifying in javascript. + + Since the conversion of QStrings to Python strings is broken in some + older PyQt versions in some corner cases, we load a HTML file which + generates an MD5 of the escaped text and use that for comparisons. + """ escaped = webelem.javascript_escape(text) - webframe.evaluateJavaScript('window.foo = "{}";'.format(escaped)) - assert webframe.evaluateJavaScript('window.foo') == text + path = os.path.join(os.path.dirname(__file__), + 'test_webelem_jsescape.html') + with open(path, encoding='utf-8') as f: + html_source = f.read().replace('%INPUT%', escaped) + + with qtbot.waitSignal(webframe.loadFinished, raising=True): + webframe.setHtml(html_source) + + result = webframe.evaluateJavaScript('window.qute_test_result') + assert result is not None + assert '|' in result + result_md5, result_text = result.split('|', maxsplit=1) + text_md5 = binascii.hexlify(text.encode('utf-8')).decode('ascii') + assert result_md5 == text_md5, result_text + + def _test_escape_simple(self, text, webframe): + """Test conversion by using evaluateJavaScript.""" + escaped = webelem.javascript_escape(text) + result = webframe.evaluateJavaScript('"{}";'.format(escaped)) + assert result == text @pytest.mark.parametrize('text', TESTS) - def test_real_escape(self, webframe, text): + def test_real_escape(self, webframe, qtbot, text): """Test javascript escaping with a real QWebPage.""" - self._test_escape(text, webframe) + self._test_escape(text, qtbot, webframe) @hypothesis.given(hypothesis.strategies.text()) - def test_real_escape_hypothesis(self, webframe, text): + def test_real_escape_hypothesis(self, webframe, qtbot, text): """Test javascript escaping with a real QWebPage and hypothesis.""" - self._test_escape(text, webframe) + # We can't simply use self._test_escape because of this: + # https://github.com/pytest-dev/pytest-qt/issues/69 + + # self._test_escape(text, qtbot, webframe) + try: + self._test_escape_simple(text, webframe) + except AssertionError: + if PYQT_VERSION >= 0x050300: + self._test_escape_hexlified(text, qtbot, webframe) class TestGetChildFrames: diff --git a/tests/browser/test_webelem_jsescape.html b/tests/browser/test_webelem_jsescape.html new file mode 100644 index 000000000..937499258 --- /dev/null +++ b/tests/browser/test_webelem_jsescape.html @@ -0,0 +1,68 @@ + + + +
+ + + +set_text() not called...
+