mirror of
https://github.com/pyscript/pyscript.git
synced 2026-02-13 07:01:00 -05:00
committed by
GitHub
parent
c8ec29a3d8
commit
aef028be6e
@@ -1,27 +1,35 @@
|
||||
// PyScript py-terminal plugin
|
||||
import { TYPES, hooks } from "../core.js";
|
||||
import { notify } from "./error.js";
|
||||
|
||||
const SELECTOR = [...TYPES.keys()]
|
||||
.map((type) => `script[type="${type}"][terminal],${type}-script[terminal]`)
|
||||
.join(",");
|
||||
|
||||
// show the error on main and
|
||||
// stops the module from keep executing
|
||||
const notifyAndThrow = (message) => {
|
||||
notify(message);
|
||||
throw new Error(message);
|
||||
};
|
||||
|
||||
const pyTerminal = async () => {
|
||||
const terminals = document.querySelectorAll(SELECTOR);
|
||||
|
||||
// no results will look further for runtime nodes
|
||||
if (!terminals.length) return;
|
||||
|
||||
// we currently support only one terminal as in "classic"
|
||||
if (terminals.length > 1)
|
||||
console.warn("Unable to satisfy multiple terminals");
|
||||
|
||||
// if we arrived this far, let's drop the MutationObserver
|
||||
// as we only support one terminal per page (right now).
|
||||
mo.disconnect();
|
||||
|
||||
// we currently support only one terminal as in "classic"
|
||||
if (terminals.length > 1) notifyAndThrow("You can use at most 1 terminal.");
|
||||
|
||||
const [element] = terminals;
|
||||
// hopefully to be removed in the near future!
|
||||
if (element.matches('script[type="mpy"],mpy-script'))
|
||||
throw new Error("Unsupported terminal");
|
||||
notifyAndThrow("Unsupported terminal.");
|
||||
|
||||
// import styles lazily
|
||||
document.head.append(
|
||||
|
||||
@@ -118,6 +118,20 @@ def only_main(fn):
|
||||
return decorated
|
||||
|
||||
|
||||
def only_worker(fn):
|
||||
"""
|
||||
Decorator to mark a test which make sense only in the worker thread
|
||||
"""
|
||||
|
||||
@functools.wraps(fn)
|
||||
def decorated(self, *args):
|
||||
if self.execution_thread != "worker":
|
||||
return
|
||||
return fn(self, *args)
|
||||
|
||||
return decorated
|
||||
|
||||
|
||||
def filter_inner_text(text, exclude=None):
|
||||
return "\n".join(filter_page_content(text.splitlines(), exclude=exclude))
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ class TestBasic(PyScriptTest):
|
||||
'"Cross-Origin-Opener-Policy":"same-origin"}. '
|
||||
"The problem may be that one or both of these are missing."
|
||||
)
|
||||
alert_banner = self.page.wait_for_selector(".alert-banner")
|
||||
alert_banner = self.page.wait_for_selector(".py-error")
|
||||
assert expected_alert_banner_msg in alert_banner.inner_text()
|
||||
|
||||
def test_print(self):
|
||||
|
||||
@@ -1,12 +1,45 @@
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from playwright.sync_api import expect
|
||||
|
||||
from .support import PyScriptTest, skip_worker
|
||||
from .support import PageErrors, PyScriptTest, only_worker, skip_worker
|
||||
|
||||
|
||||
class TestPyTerminal(PyScriptTest):
|
||||
@skip_worker("FIXME: the auto worker dance removes terminal")
|
||||
def test_multiple_terminals(self):
|
||||
"""
|
||||
Multiple terminals are not currently supported
|
||||
"""
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<script type="py" terminal></script>
|
||||
<script type="py" terminal></script>
|
||||
""",
|
||||
wait_for_pyscript=False,
|
||||
check_js_errors=False,
|
||||
)
|
||||
assert self.assert_banner_message("You can use at most 1 terminal")
|
||||
|
||||
with pytest.raises(PageErrors, match="You can use at most 1 terminal"):
|
||||
self.check_js_errors()
|
||||
|
||||
@only_worker
|
||||
def test_py_terminal_input(self):
|
||||
"""
|
||||
Only worker py-terminal accepts an input
|
||||
"""
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<script type="py" terminal></script>
|
||||
""",
|
||||
wait_for_pyscript=False,
|
||||
)
|
||||
self.page.get_by_text(">>> ", exact=True).wait_for()
|
||||
self.page.keyboard.type("'the answer is ' + str(6 * 7)")
|
||||
self.page.keyboard.press("Enter")
|
||||
self.page.get_by_text("the answer is 42").wait_for()
|
||||
|
||||
def test_py_terminal(self):
|
||||
"""
|
||||
1. <py-terminal> should redirect stdout and stderr to the DOM
|
||||
@@ -21,8 +54,10 @@ class TestPyTerminal(PyScriptTest):
|
||||
print('this goes to stderr', file=sys.stderr)
|
||||
print('this goes to stdout')
|
||||
</script>
|
||||
"""
|
||||
""",
|
||||
wait_for_pyscript=False,
|
||||
)
|
||||
self.page.get_by_text("hello world").wait_for()
|
||||
term = self.page.locator("py-terminal")
|
||||
term_lines = term.inner_text().splitlines()
|
||||
assert term_lines[0:3] == [
|
||||
@@ -31,7 +66,9 @@ class TestPyTerminal(PyScriptTest):
|
||||
"this goes to stdout",
|
||||
]
|
||||
|
||||
@skip_worker("FIXME: the auto worker dance removes terminal")
|
||||
@skip_worker(
|
||||
"Workers don't have events + two different workers don't share the same I/O"
|
||||
)
|
||||
def test_button_action(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
@@ -50,7 +87,6 @@ class TestPyTerminal(PyScriptTest):
|
||||
last_line.wait_for()
|
||||
assert term.inner_text().rstrip() == "hello world"
|
||||
|
||||
@skip_worker("FIXME: the auto worker dance removes terminal")
|
||||
def test_xterm_function(self):
|
||||
"""Test a few basic behaviors of the xtermjs terminal.
|
||||
|
||||
@@ -69,7 +105,8 @@ class TestPyTerminal(PyScriptTest):
|
||||
print("\x1b[3mItalic\x1b[23m")
|
||||
print("done")
|
||||
</script>
|
||||
"""
|
||||
""",
|
||||
wait_for_pyscript=False,
|
||||
)
|
||||
|
||||
# Wait for "done" to actually appear in the xterm; may be delayed,
|
||||
|
||||
Reference in New Issue
Block a user