8000 [EPIC] Fix all the remaining worker tests · Issue #1762 · pyscript/pyscript · GitHub
[go: up one dir, main page]

Skip to content

[EPIC] Fix all the remaining worker tests #1762

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
antocuni opened this issue Sep 27, 2023 · 1 comment
Closed

[EPIC] Fix all the remaining worker tests #1762

antocuni opened this issue Sep 27, 2023 · 1 comment

Comments

@antocuni
Copy link
Contributor
antocuni commented Sep 27, 2023

This is the sister issue of #1761.
We currently have 14 tests marked as @skip_worker

The goal of this issue is to give a rough explanation, try to group them into categories and serve as a starting point for further discussion, and to decide which ones we want to absolutely fix before the final release, and which ones can wait.

I expect that some of them will be uncontroversial, others will require more discussion, so depending on the case we might want to open separate sub-issues for them.


Missing error messages

These are all cases in which we display a nice error banner when we run in the main thread, but not when running in a worker:

@skip_worker("NEXT: exceptions should be displayed in the DOM")
def test_python_exception(self):
self.pyscript_run(
"""
<script type="py">
print('hello pyscript')
raise Exception('this is an error')
</script>
"""
)
assert "hello pyscript" in self.console.log.lines
self.check_py_errors("Exception: this is an error")
#
# check that we sent the traceback to the console
tb_lines = self.console.error.lines[-1].splitlines()
assert tb_lines[0] == "PythonError: Traceback (most recent call last):"
#
# check that we show the traceback in the page. Note that here we
# display the "raw" python traceback, without the "[pyexec] Python
# exception:" line (which is useful in the console, but not for the
# user)
banner = self.page.locator(".py-error")
tb_lines = banner.inner_text().splitlines()
assert tb_lines[0] == "Traceback (most recent call last):"
assert tb_lines[-1] == "Exception: this is an error"

@skip_worker("NEXT: banner not shown")
def test_py_script_src_not_found(self):
self.pyscript_run(
"""
<script type="py" src="foo.py"></script>
""",
check_js_errors=False,
)
assert "Failed to load resource" in self.console.error.lines[0]
# TODO: we need to be sure errors make sense from both main and worker worlds
expected_msg = "(PY0404): Fetching from URL foo.py failed with error 404"
assert any((expected_msg in line) for line in self.console.error.lines)
assert self.assert_banner_message(expected_msg)

@skip_worker("NEXT: error banner not shown")
def test_when_decorator_invalid_selector(self):
"""When the selector parameter of @when is invalid, it should show an error"""
self.pyscript_run(
"""
<button id="foo_id">foo_button</button>
<script type="py">
from pyscript import when
@when("click", selector="#.bad")
def foo(evt):
...
</script>
"""
)
self.page.locator("text=foo_button").click()
msg = "Failed to execute 'querySelectorAll' on 'Document': '#.bad' is not a valid selector."
error = self.page.wait_for_selector(".py-error")
banner_text = error.inner_text()
if msg not in banner_text:
raise AssertionError(
f"Expected message '{msg}' does not "
f"match banner text '{banner_text}'"
)
assert msg in self.console.error.lines[-1]
self.check_py_errors(msg)


problems related to display()

  • when we are inside a worker, display() doesn't take into account the target attribute of its surrounding tag:

    @skip_worker("NEXT: display(target=...) does not work")
    def test_tag_target_attribute(self):
    self.pyscript_run(
    """
    <script type="py" target="hello">
    from pyscript import display
    display('hello')
    display("goodbye world", target="goodbye")
    display('world')
    </script>
    <div id="hello"></div>
    <div id="goodbye"></div>
    """
    )
    hello = self.page.locator("#hello")
    assert hello.inner_text() == "hello\nworld"
    goodbye = self.page.locator("#goodbye")
    assert goodbye.inner_text() == "goodbye world"

  • these are for a different case: display(..., target=x) works fine is x points to e.g. a div, but not if it points to a <script type="py"> tag. Note that this works in the main thread, not in the worker:

    @skip_worker("NEXT: display target does not work properly")
    def test_target_script_py(self):
    self.pyscript_run(
    """
    <div>ONE</div>
    <script type="py" id="two">
    # just a placeholder
    </script>
    <div>THREE</div>
    <script type="py">
    from pyscript import display
    display('TWO', target="two")
    </script>
    """
    )
    text = self.page.inner_text("body")
    assert text == "ONE\nTWO\nTHREE"

    @skip_worker("NEXT: display target does not work properly")
    def test_consecutive_display_target(self):
    self.pyscript_run(
    """
    <script type="py" id="first">
    from pyscript import display
    display('hello 1')
    </script>
    <p>hello in between 1 and 2</p>
    <script type="py" id="second">
    from pyscript import display
    display('hello 2', target="second")
    </script>
    <script type="py" id="third">
    from pyscript import display
    display('hello 3')
    </script>
    """
    )
    inner_text = self.page.inner_text("body")
    lines = inner_text.splitlines()
    lines = [line for line in filter_page_content(lines)] # remove empty lines
    assert lines == ["hello 1", "hello in between 1 and 2", "hello 2", "hello 3"]

    @skip_worker("NEXT: display target does not work properly")
    def test_explicit_target_pyscript_tag(self):
    self.pyscript_run(
    """
    <script type="py">
    from pyscript import display
    def display_hello():
    display('hello', target='second-pyscript-tag')
    </script>
    <script type="py" id="second-pyscript-tag">
    display_hello()
    </script>
    """
    )
    text = self.page.locator("script-py").nth(1).inner_text()
    assert text == "hello"

  • this is another case of display(..., target=...) not working:

    @skip_worker("NEXT: display target does not work properly")
    def test_image_renders_correctly(self):
    """
    This is just a sanity check to make sure that images are rendered
    in a reasonable way.
    """
    self.pyscript_run(
    """
    <py-config>
    packages = ["pillow"]
    </py-config>
    <div id="img-target" />
    <script type="py">
    from pyscript import display
    from PIL import Image
    img = Image.new("RGB", (4, 4), color=(0, 0, 0))
    display(img, target='img-target', append=False)
    </script>
    """,
    )
    img_src = self.page.locator("img").get_attribute("src")
    assert img_src.startswith('data:image/png;charset=utf-8;base64')


misc

  • matplotlib-pyodide seems to have problems inside workers, we need to investigate:

    @skip_worker("NEXT: matplotlib-pyodide backend does not work")
    def test_image_display(self):
    self.pyscript_run(
    """
    <py-config> packages = ["matplotlib"] </py-config>
    <script type="py">
    from pyscript import display
    import matplotlib.pyplot as plt
    xpoints = [3, 6, 9]
    ypoints = [1, 2, 3]
    plt.plot(xpoints, ypoints)
    display(plt)
    </script>
    """,
    timeout=30 * 1000,
    )
    wait_for_render(self.page, "*", "<img src=['\"]data:image")
    test = self.page.wait_for_selector("img")
    img_src = test.get_attribute("src").replace(
    "data:image/png;charset=utf-8;base64,", ""
    )
    img_data = np.asarray(Image.open(io.BytesIO(base64.b64decode(img_src))))
    with Image.open(
    os.path.join(os.path.dirname(__file__), "test_assets", "line_plot.png"),
    ) as image:
    ref_data = np.asarray(image)
    deviation = np.mean(np.abs(img_data - ref_data))
    assert deviation == 0.0
    self.assert_no_banners()

  • this is a sub issue, worth its own discussion:
    Should workers support py-* events? #1763

  • test_escaping_of_angle_brackets has a very weird behavior:
    Fix escaping of <py-script> #1764

@WebReflection
Copy link
Contributor

This comes from times we had a different core, so I think this should be closed, as current integration tests have different reasons about the why, while other tests via workers got implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
0