mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-23 12:12:59 -05:00
Introduce/improve check_js_errors and improve test_no_implicit_target (#874)
Until now, we didn't have a nice way to check that we expect a specific JS error in the web page. This PR improves check_js_errors() so that now you can pass a list of error messages that you expect. It is tricky because we need to handle (and test!) all various combinations of cases: - errors expected and found / expected but not found - unexpected errors found / not found Moreover, JS exceptions now are logged in the special category console.js_error, which means that the printed text is also available using e.g. self.console.js_error.text or self.console.all.text. However, this should never be required and it's preferred to use self.check_js_errors to check for exceptions. This fixes #795 . Finally, use the new logic to improve test_no_implicit_target.
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
from playwright import sync_api
|
||||
|
||||
from .support import JsError, JsMultipleErrors, PyScriptTest
|
||||
from .support import JsErrors, JsErrorsDidNotRaise, PyScriptTest
|
||||
|
||||
|
||||
class TestSupport(PyScriptTest):
|
||||
@@ -75,7 +76,7 @@ class TestSupport(PyScriptTest):
|
||||
assert self.console.log.lines == ["my log 1", "my log 2"]
|
||||
assert self.console.debug.lines == ["my debug"]
|
||||
|
||||
def test_check_errors(self):
|
||||
def test_check_js_errors_simple(self):
|
||||
doc = """
|
||||
<html>
|
||||
<body>
|
||||
@@ -85,18 +86,68 @@ class TestSupport(PyScriptTest):
|
||||
"""
|
||||
self.writefile("mytest.html", doc)
|
||||
self.goto("mytest.html")
|
||||
with pytest.raises(JsError) as exc:
|
||||
self.check_errors()
|
||||
with pytest.raises(JsErrors) as exc:
|
||||
self.check_js_errors()
|
||||
# check that the exception message contains the error message and the
|
||||
# stack trace
|
||||
msg = str(exc.value)
|
||||
assert "Error: this is an error" in msg
|
||||
assert f"at {self.http_server}/mytest.html" in msg
|
||||
expected = textwrap.dedent(
|
||||
f"""
|
||||
JS errors found: 1
|
||||
Error: this is an error
|
||||
at {self.http_server}/mytest.html:.*
|
||||
"""
|
||||
).strip()
|
||||
assert re.search(expected, msg)
|
||||
#
|
||||
# after a call to check_errors, the errors are cleared
|
||||
self.check_errors()
|
||||
# after a call to check_js_errors, the errors are cleared
|
||||
self.check_js_errors()
|
||||
#
|
||||
# JS exceptions are also available in self.console.js_error
|
||||
assert self.console.js_error.lines[0].startswith("Error: this is an error")
|
||||
|
||||
def test_check_errors_multiple(self):
|
||||
def test_check_js_errors_expected(self):
|
||||
doc = """
|
||||
<html>
|
||||
<body>
|
||||
<script>throw new Error('this is an error');</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
self.writefile("mytest.html", doc)
|
||||
self.goto("mytest.html")
|
||||
self.check_js_errors("this is an error")
|
||||
|
||||
def test_check_js_errors_expected_but_didnt_raise(self):
|
||||
doc = """
|
||||
<html>
|
||||
<body>
|
||||
<script>throw new Error('this is an error 2');</script>
|
||||
<script>throw new Error('this is an error 4');</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
self.writefile("mytest.html", doc)
|
||||
self.goto("mytest.html")
|
||||
with pytest.raises(JsErrorsDidNotRaise) as exc:
|
||||
self.check_js_errors(
|
||||
"this is an error 1",
|
||||
"this is an error 2",
|
||||
"this is an error 3",
|
||||
"this is an error 4",
|
||||
)
|
||||
#
|
||||
msg = str(exc.value)
|
||||
expected = textwrap.dedent(
|
||||
"""
|
||||
The following JS errors were expected but could not be found:
|
||||
- this is an error 1
|
||||
- this is an error 3
|
||||
"""
|
||||
).strip()
|
||||
assert re.search(expected, msg)
|
||||
|
||||
def test_check_js_errors_multiple(self):
|
||||
doc = """
|
||||
<html>
|
||||
<body>
|
||||
@@ -107,15 +158,82 @@ class TestSupport(PyScriptTest):
|
||||
"""
|
||||
self.writefile("mytest.html", doc)
|
||||
self.goto("mytest.html")
|
||||
with pytest.raises(JsMultipleErrors) as exc:
|
||||
self.check_errors()
|
||||
assert "error 1" in str(exc.value)
|
||||
assert "error 2" in str(exc.value)
|
||||
with pytest.raises(JsErrors) as exc:
|
||||
self.check_js_errors()
|
||||
#
|
||||
msg = str(exc.value)
|
||||
expected = textwrap.dedent(
|
||||
"""
|
||||
JS errors found: 2
|
||||
Error: error 1
|
||||
at http://fake_server/mytest.html:.*
|
||||
Error: error 2
|
||||
at http://fake_server/mytest.html:.*
|
||||
"""
|
||||
).strip()
|
||||
assert re.search(expected, msg)
|
||||
#
|
||||
# check that errors are cleared
|
||||
self.check_errors()
|
||||
self.check_js_errors()
|
||||
|
||||
def test_clear_errors(self):
|
||||
def test_check_js_errors_some_expected_but_others_not(self):
|
||||
doc = """
|
||||
<html>
|
||||
<body>
|
||||
<script>throw new Error('expected 1');</script>
|
||||
<script>throw new Error('NOT expected 2');</script>
|
||||
<script>throw new Error('expected 3');</script>
|
||||
<script>throw new Error('NOT expected 4');</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
self.writefile("mytest.html", doc)
|
||||
self.goto("mytest.html")
|
||||
with pytest.raises(JsErrors) as exc:
|
||||
self.check_js_errors("expected 1", "expected 3")
|
||||
#
|
||||
msg = str(exc.value)
|
||||
expected = textwrap.dedent(
|
||||
"""
|
||||
JS errors found: 2
|
||||
Error: NOT expected 2
|
||||
at http://fake_server/mytest.html:.*
|
||||
Error: NOT expected 4
|
||||
at http://fake_server/mytest.html:.*
|
||||
"""
|
||||
).strip()
|
||||
assert re.search(expected, msg)
|
||||
|
||||
def test_check_js_errors_expected_not_found_but_other_errors(self):
|
||||
doc = """
|
||||
<html>
|
||||
<body>
|
||||
<script>throw new Error('error 1');</script>
|
||||
<script>throw new Error('error 2');</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
self.writefile("mytest.html", doc)
|
||||
self.goto("mytest.html")
|
||||
with pytest.raises(JsErrorsDidNotRaise) as exc:
|
||||
self.check_js_errors("this is not going to be found")
|
||||
#
|
||||
msg = str(exc.value)
|
||||
expected = textwrap.dedent(
|
||||
"""
|
||||
The following JS errors were expected but could not be found:
|
||||
- this is not going to be found
|
||||
---
|
||||
The following JS errors were raised but not expected:
|
||||
Error: error 1
|
||||
at http://fake_server/mytest.html:.*
|
||||
Error: error 2
|
||||
at http://fake_server/mytest.html:.*
|
||||
"""
|
||||
).strip()
|
||||
assert re.search(expected, msg)
|
||||
|
||||
def test_clear_js_errors(self):
|
||||
doc = """
|
||||
<html>
|
||||
<body>
|
||||
@@ -125,10 +243,10 @@ class TestSupport(PyScriptTest):
|
||||
"""
|
||||
self.writefile("mytest.html", doc)
|
||||
self.goto("mytest.html")
|
||||
self.clear_errors()
|
||||
# self.check_errors does not raise, because the errors have been
|
||||
self.clear_js_errors()
|
||||
# self.check_js_errors does not raise, because the errors have been
|
||||
# cleared
|
||||
self.check_errors()
|
||||
self.check_js_errors()
|
||||
|
||||
def test_wait_for_console(self):
|
||||
"""
|
||||
@@ -177,19 +295,19 @@ class TestSupport(PyScriptTest):
|
||||
self.writefile("mytest.html", doc)
|
||||
# "Page loaded!" will never appear, of course.
|
||||
self.goto("mytest.html")
|
||||
with pytest.raises(JsError) as exc:
|
||||
with pytest.raises(JsErrors) as exc:
|
||||
self.wait_for_console("Page loaded!", timeout=200)
|
||||
assert "this is an error" in str(exc.value)
|
||||
assert isinstance(exc.value.__context__, sync_api.TimeoutError)
|
||||
#
|
||||
# if we use check_errors=False, the error are ignored, but we get the
|
||||
# if we use check_js_errors=False, the error are ignored, but we get the
|
||||
# Timeout anyway
|
||||
self.goto("mytest.html")
|
||||
with pytest.raises(sync_api.TimeoutError):
|
||||
self.wait_for_console("Page loaded!", timeout=200, check_errors=False)
|
||||
# we still got a JsError, so we need to manually clear it, else the
|
||||
self.wait_for_console("Page loaded!", timeout=200, check_js_errors=False)
|
||||
# we still got a JsErrors, so we need to manually clear it, else the
|
||||
# test fails at teardown
|
||||
self.clear_errors()
|
||||
self.clear_js_errors()
|
||||
|
||||
def test_wait_for_console_exception_2(self):
|
||||
"""
|
||||
@@ -210,13 +328,13 @@ class TestSupport(PyScriptTest):
|
||||
"""
|
||||
self.writefile("mytest.html", doc)
|
||||
self.goto("mytest.html")
|
||||
with pytest.raises(JsError) as exc:
|
||||
with pytest.raises(JsErrors) as exc:
|
||||
self.wait_for_console("Page loaded!", timeout=200)
|
||||
assert "this is an error" in str(exc.value)
|
||||
#
|
||||
# with check_errors=False, the Error is ignored and the
|
||||
# with check_js_errors=False, the Error is ignored and the
|
||||
# wait_for_console succeeds
|
||||
self.goto("mytest.html")
|
||||
self.wait_for_console("Page loaded!", timeout=200, check_errors=False)
|
||||
self.wait_for_console("Page loaded!", timeout=200, check_js_errors=False)
|
||||
# clear the errors, else the test fails at teardown
|
||||
self.clear_errors()
|
||||
self.clear_js_errors()
|
||||
|
||||
Reference in New Issue
Block a user