@pyscript/core 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -2
- package/dist/core.js +3 -3
- package/dist/core.js.map +1 -1
- package/docs/README.md +3 -12
- package/package.json +3 -3
- package/src/config.js +32 -24
- package/src/core.js +1 -1
- package/src/stdlib/pyscript/__init__.py +34 -0
- package/src/stdlib/pyscript/display.py +154 -0
- package/src/stdlib/pyscript/event_handling.py +45 -0
- package/src/stdlib/pyscript/magic_js.py +32 -0
- package/src/stdlib/pyscript/util.py +22 -0
- package/src/stdlib/pyscript.js +9 -5
- package/src/stdlib/pyweb/pydom.py +314 -0
- package/tests/integration/__init__.py +0 -0
- package/tests/integration/conftest.py +184 -0
- package/tests/integration/support.py +1038 -0
- package/tests/integration/test_00_support.py +495 -0
- package/tests/integration/test_01_basic.py +353 -0
- package/tests/integration/test_02_display.py +452 -0
- package/tests/integration/test_03_element.py +303 -0
- package/tests/integration/test_assets/line_plot.png +0 -0
- package/tests/integration/test_assets/tripcolor.png +0 -0
- package/tests/integration/test_async.py +197 -0
- package/tests/integration/test_event_handling.py +193 -0
- package/tests/integration/test_importmap.py +66 -0
- package/tests/integration/test_interpreter.py +98 -0
- package/tests/integration/test_plugins.py +419 -0
- package/tests/integration/test_py_config.py +294 -0
- package/tests/integration/test_py_repl.py +663 -0
- package/tests/integration/test_py_terminal.py +270 -0
- package/tests/integration/test_runtime_attributes.py +64 -0
- package/tests/integration/test_script_type.py +121 -0
- package/tests/integration/test_shadow_root.py +33 -0
- package/tests/integration/test_splashscreen.py +124 -0
- package/tests/integration/test_stdio_handling.py +370 -0
- package/tests/integration/test_style.py +47 -0
- package/tests/integration/test_warnings_and_banners.py +32 -0
- package/tests/integration/test_zz_examples.py +419 -0
- package/tests/integration/test_zzz_docs_snippets.py +305 -0
- package/types/stdlib/pyscript.d.ts +8 -4
@@ -0,0 +1,270 @@
|
|
1
|
+
import time
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
from playwright.sync_api import expect
|
5
|
+
|
6
|
+
from .support import PyScriptTest, skip_worker
|
7
|
+
|
8
|
+
pytest.skip(
|
9
|
+
reason="FIX LATER: pyscript NEXT doesn't support the Terminal yet",
|
10
|
+
allow_module_level=True,
|
11
|
+
)
|
12
|
+
|
13
|
+
|
14
|
+
class TestPyTerminal(PyScriptTest):
|
15
|
+
def test_py_terminal(self):
|
16
|
+
"""
|
17
|
+
1. <py-terminal> should redirect stdout and stderr to the DOM
|
18
|
+
|
19
|
+
2. they also go to the console as usual
|
20
|
+
"""
|
21
|
+
self.pyscript_run(
|
22
|
+
"""
|
23
|
+
<py-terminal></py-terminal>
|
24
|
+
|
25
|
+
<py-script>
|
26
|
+
import sys
|
27
|
+
print('hello world')
|
28
|
+
print('this goes to stderr', file=sys.stderr)
|
29
|
+
print('this goes to stdout')
|
30
|
+
</py-script>
|
31
|
+
"""
|
32
|
+
)
|
33
|
+
term = self.page.locator("py-terminal")
|
34
|
+
term_lines = term.inner_text().splitlines()
|
35
|
+
assert term_lines == [
|
36
|
+
"hello world",
|
37
|
+
"this goes to stderr",
|
38
|
+
"this goes to stdout",
|
39
|
+
]
|
40
|
+
assert self.console.log.lines[-3:] == [
|
41
|
+
"hello world",
|
42
|
+
"this goes to stderr",
|
43
|
+
"this goes to stdout",
|
44
|
+
]
|
45
|
+
|
46
|
+
@skip_worker("FIXME: js.document")
|
47
|
+
def test_two_terminals(self):
|
48
|
+
"""
|
49
|
+
Multiple <py-terminal>s can cohexist.
|
50
|
+
A <py-terminal> receives only output from the moment it is added to
|
51
|
+
the DOM.
|
52
|
+
"""
|
53
|
+
self.pyscript_run(
|
54
|
+
"""
|
55
|
+
<py-terminal id="term1"></py-terminal>
|
56
|
+
|
57
|
+
<py-script>
|
58
|
+
import js
|
59
|
+
print('one')
|
60
|
+
term2 = js.document.createElement('py-terminal')
|
61
|
+
term2.id = 'term2'
|
62
|
+
js.document.body.append(term2)
|
63
|
+
|
64
|
+
print('two')
|
65
|
+
print('three')
|
66
|
+
</py-script>
|
67
|
+
"""
|
68
|
+
)
|
69
|
+
term1 = self.page.locator("#term1")
|
70
|
+
term2 = self.page.locator("#term2")
|
71
|
+
term1_lines = term1.inner_text().splitlines()
|
72
|
+
term2_lines = term2.inner_text().splitlines()
|
73
|
+
assert term1_lines == ["one", "two", "three"]
|
74
|
+
assert term2_lines == ["two", "three"]
|
75
|
+
|
76
|
+
def test_auto_attribute(self):
|
77
|
+
self.pyscript_run(
|
78
|
+
"""
|
79
|
+
<py-terminal auto></py-terminal>
|
80
|
+
|
81
|
+
<button id="my-button" py-click="print('hello world')">Click me</button>
|
82
|
+
"""
|
83
|
+
)
|
84
|
+
term = self.page.locator("py-terminal")
|
85
|
+
expect(term).to_be_hidden()
|
86
|
+
self.page.locator("button").click()
|
87
|
+
expect(term).to_be_visible()
|
88
|
+
assert term.inner_text() == "hello world\n"
|
89
|
+
|
90
|
+
def test_config_auto(self):
|
91
|
+
"""
|
92
|
+
config.terminal == "auto" is the default: a <py-terminal auto> is
|
93
|
+
automatically added to the page
|
94
|
+
"""
|
95
|
+
self.pyscript_run(
|
96
|
+
"""
|
97
|
+
<button id="my-button" py-click="print('hello world')">Click me</button>
|
98
|
+
"""
|
99
|
+
)
|
100
|
+
term = self.page.locator("py-terminal")
|
101
|
+
expect(term).to_be_hidden()
|
102
|
+
assert "No <py-terminal> found, adding one" in self.console.info.text
|
103
|
+
#
|
104
|
+
self.page.locator("button").click()
|
105
|
+
expect(term).to_be_visible()
|
106
|
+
assert term.inner_text() == "hello world\n"
|
107
|
+
|
108
|
+
def test_config_true(self):
|
109
|
+
"""
|
110
|
+
If we set config.terminal == true, a <py-terminal> is automatically added
|
111
|
+
"""
|
112
|
+
self.pyscript_run(
|
113
|
+
"""
|
114
|
+
<py-config>
|
115
|
+
terminal = true
|
116
|
+
</py-config>
|
117
|
+
|
118
|
+
<py-script>
|
119
|
+
print('hello world')
|
120
|
+
</py-script>
|
121
|
+
"""
|
122
|
+
)
|
123
|
+
term = self.page.locator("py-terminal")
|
124
|
+
expect(term).to_be_visible()
|
125
|
+
assert term.inner_text() == "hello world\n"
|
126
|
+
|
127
|
+
def test_config_false(self):
|
128
|
+
"""
|
129
|
+
If we set config.terminal == false, no <py-terminal> is added
|
130
|
+
"""
|
131
|
+
self.pyscript_run(
|
132
|
+
"""
|
133
|
+
<py-config>
|
134
|
+
terminal = false
|
135
|
+
</py-config>
|
136
|
+
"""
|
137
|
+
)
|
138
|
+
term = self.page.locator("py-terminal")
|
139
|
+
assert term.count() == 0
|
140
|
+
|
141
|
+
def test_config_docked(self):
|
142
|
+
"""
|
143
|
+
config.docked == "docked" is also the default: a <py-terminal auto docked> is
|
144
|
+
automatically added to the page
|
145
|
+
"""
|
146
|
+
self.pyscript_run(
|
147
|
+
"""
|
148
|
+
<button id="my-button" py-click="print('hello world')">Click me</button>
|
149
|
+
"""
|
150
|
+
)
|
151
|
+
term = self.page.locator("py-terminal")
|
152
|
+
self.page.locator("button").click()
|
153
|
+
expect(term).to_be_visible()
|
154
|
+
assert term.get_attribute("docked") == ""
|
155
|
+
|
156
|
+
def test_xterm_function(self):
|
157
|
+
"""Test a few basic behaviors of the xtermjs terminal.
|
158
|
+
|
159
|
+
This test isn't meant to capture all of the behaviors of an xtermjs terminal;
|
160
|
+
rather, it confirms with a few basic formatting sequences that (1) the xtermjs
|
161
|
+
terminal is functioning/loaded correctly and (2) that output toward that terminal
|
162
|
+
isn't being escaped in a way that prevents it reacting to escape seqeunces. The
|
163
|
+
main goal is preventing regressions.
|
164
|
+
"""
|
165
|
+
self.pyscript_run(
|
166
|
+
"""
|
167
|
+
<py-config>
|
168
|
+
xterm = true
|
169
|
+
</py-config>
|
170
|
+
<py-script>
|
171
|
+
print("\x1b[33mYellow\x1b[0m")
|
172
|
+
print("\x1b[4mUnderline\x1b[24m")
|
173
|
+
print("\x1b[1mBold\x1b[22m")
|
174
|
+
print("\x1b[3mItalic\x1b[23m")
|
175
|
+
print("done")
|
176
|
+
</py-script>
|
177
|
+
"""
|
178
|
+
)
|
179
|
+
|
180
|
+
# Wait for "done" to actually appear in the xterm; may be delayed,
|
181
|
+
# since xtermjs processes its input buffer in chunks
|
182
|
+
last_line = self.page.get_by_text("done")
|
183
|
+
last_line.wait_for()
|
184
|
+
|
185
|
+
# Yes, this is not ideal. However, per http://xtermjs.org/docs/guides/hooks/
|
186
|
+
# "It is not possible to conclude, whether or when a certain chunk of data
|
187
|
+
# will finally appear on the screen," which is what we'd really like to know.
|
188
|
+
# By waiting for the "done" test to appear above, we get close, however it is
|
189
|
+
# possible for the text to appear and not be 'processed' (i.e.) formatted. This
|
190
|
+
# small delay should avoid that.
|
191
|
+
time.sleep(1)
|
192
|
+
|
193
|
+
rows = self.page.locator(".xterm-rows")
|
194
|
+
|
195
|
+
# The following use locator.evaluate() and getComputedStyle to get
|
196
|
+
# the computed CSS values; this tests that the lines are rendering
|
197
|
+
# properly in a better way than just testing whether they
|
198
|
+
# get the right css classes from xtermjs
|
199
|
+
|
200
|
+
# First line should be yellow
|
201
|
+
first_line = rows.locator("div").nth(0)
|
202
|
+
first_char = first_line.locator("span").nth(0)
|
203
|
+
color = first_char.evaluate(
|
204
|
+
"(element) => getComputedStyle(element).getPropertyValue('color')"
|
205
|
+
)
|
206
|
+
assert color == "rgb(196, 160, 0)"
|
207
|
+
|
208
|
+
# Second line should be underlined
|
209
|
+
second_line = rows.locator("div").nth(1)
|
210
|
+
first_char = second_line.locator("span").nth(0)
|
211
|
+
text_decoration = first_char.evaluate(
|
212
|
+
"(element) => getComputedStyle(element).getPropertyValue('text-decoration')"
|
213
|
+
)
|
214
|
+
assert "underline" in text_decoration
|
215
|
+
|
216
|
+
# We'll make sure the 'bold' font weight is more than the
|
217
|
+
# default font weight without specifying a specific value
|
218
|
+
baseline_font_weight = first_char.evaluate(
|
219
|
+
"(element) => getComputedStyle(element).getPropertyValue('font-weight')"
|
220
|
+
)
|
221
|
+
|
222
|
+
# Third line should be bold
|
223
|
+
third_line = rows.locator("div").nth(2)
|
224
|
+
first_char = third_line.locator("span").nth(0)
|
225
|
+
font_weight = first_char.evaluate(
|
226
|
+
"(element) => getComputedStyle(element).getPropertyValue('font-weight')"
|
227
|
+
)
|
228
|
+
assert int(font_weight) > int(baseline_font_weight)
|
229
|
+
|
230
|
+
# Fourth line should be italic
|
231
|
+
fourth_line = rows.locator("div").nth(3)
|
232
|
+
first_char = fourth_line.locator("span").nth(0)
|
233
|
+
font_style = first_char.evaluate(
|
234
|
+
"(element) => getComputedStyle(element).getPropertyValue('font-style')"
|
235
|
+
)
|
236
|
+
assert font_style == "italic"
|
237
|
+
|
238
|
+
def test_xterm_multiple(self):
|
239
|
+
"""Test whether multiple x-terms on the page all function"""
|
240
|
+
self.pyscript_run(
|
241
|
+
"""
|
242
|
+
<py-config>
|
243
|
+
xterm = true
|
244
|
+
</py-config>
|
245
|
+
<py-script>
|
246
|
+
print("\x1b[33mYellow\x1b[0m")
|
247
|
+
print("done")
|
248
|
+
</py-script>
|
249
|
+
<py-terminal id="a"></py-terminal>
|
250
|
+
<py-terminal id="b" data-testid="b"></py-terminal>
|
251
|
+
"""
|
252
|
+
)
|
253
|
+
|
254
|
+
# Wait for "done" to actually appear in the xterm; may be delayed,
|
255
|
+
# since xtermjs processes its input buffer in chunks
|
256
|
+
last_line = self.page.get_by_test_id("b").get_by_text("done")
|
257
|
+
last_line.wait_for()
|
258
|
+
|
259
|
+
# Yes, this is not ideal. See note in `test_xterm_function`
|
260
|
+
time.sleep(1)
|
261
|
+
|
262
|
+
rows = self.page.locator("#a .xterm-rows")
|
263
|
+
|
264
|
+
# First line should be yellow
|
265
|
+
first_line = rows.locator("div").nth(0)
|
266
|
+
first_char = first_line.locator("span").nth(0)
|
267
|
+
color = first_char.evaluate(
|
268
|
+
"(element) => getComputedStyle(element).getPropertyValue('color')"
|
269
|
+
)
|
270
|
+
assert color == "rgb(196, 160, 0)"
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from .support import PyScriptTest
|
4
|
+
|
5
|
+
|
6
|
+
class TestPyScriptRuntimeAttributes(PyScriptTest):
|
7
|
+
@pytest.mark.skip("FIXME: Element interface is gone. Replace with PyDom")
|
8
|
+
def test_injected_html_with_py_event(self):
|
9
|
+
self.pyscript_run(
|
10
|
+
r"""
|
11
|
+
<div id="py-button-container"></div>
|
12
|
+
<py-script>
|
13
|
+
import js
|
14
|
+
|
15
|
+
py_button = Element("py-button-container")
|
16
|
+
py_button.element.innerHTML = '<button py-click="print_hello()"></button>'
|
17
|
+
|
18
|
+
def print_hello():
|
19
|
+
js.console.log("hello pyscript")
|
20
|
+
</py-script>
|
21
|
+
"""
|
22
|
+
)
|
23
|
+
self.page.locator("button").click()
|
24
|
+
assert self.console.log.lines == ["hello pyscript"]
|
25
|
+
|
26
|
+
@pytest.mark.skip("FIXME: Element interface is gone. Replace with PyDom")
|
27
|
+
def test_added_py_event(self):
|
28
|
+
self.pyscript_run(
|
29
|
+
r"""
|
30
|
+
<button id="py-button"></button>
|
31
|
+
<py-script>
|
32
|
+
import js
|
33
|
+
|
34
|
+
py_button = Element("py-button")
|
35
|
+
py_button.element.setAttribute("py-click", "print_hello()")
|
36
|
+
|
37
|
+
def print_hello():
|
38
|
+
js.console.log("hello pyscript")
|
39
|
+
</py-script>
|
40
|
+
"""
|
41
|
+
)
|
42
|
+
self.page.locator("button").click()
|
43
|
+
assert self.console.log.lines == ["hello pyscript"]
|
44
|
+
|
45
|
+
@pytest.mark.skip("FIXME: Element interface is gone. Replace with PyDom")
|
46
|
+
def test_added_then_removed_py_event(self):
|
47
|
+
self.pyscript_run(
|
48
|
+
r"""
|
49
|
+
<button id="py-button">live content</button>
|
50
|
+
<py-script>
|
51
|
+
import js
|
52
|
+
|
53
|
+
py_button = Element("py-button")
|
54
|
+
py_button.element.setAttribute("py-click", "print_hello()")
|
55
|
+
|
56
|
+
def print_hello():
|
57
|
+
js.console.log("hello pyscript")
|
58
|
+
py_button.element.removeAttribute("py-click")
|
59
|
+
</py-script>
|
60
|
+
"""
|
61
|
+
)
|
62
|
+
self.page.locator("button").click()
|
63
|
+
self.page.locator("button").click()
|
64
|
+
assert self.console.log.lines == ["hello pyscript"]
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from .support import PyScriptTest
|
4
|
+
|
5
|
+
|
6
|
+
class TestScriptTypePyScript(PyScriptTest):
|
7
|
+
def test_display_line_break(self):
|
8
|
+
self.pyscript_run(
|
9
|
+
r"""
|
10
|
+
<script type="py">
|
11
|
+
from pyscript import display
|
12
|
+
display('hello\nworld')
|
13
|
+
</script>
|
14
|
+
"""
|
15
|
+
)
|
16
|
+
text_content = self.page.locator("script-py").text_content()
|
17
|
+
assert "hello\nworld" == text_content
|
18
|
+
|
19
|
+
def test_amp(self):
|
20
|
+
self.pyscript_run(
|
21
|
+
r"""
|
22
|
+
<script type="py">
|
23
|
+
from pyscript import display
|
24
|
+
display('a & b')
|
25
|
+
</script>
|
26
|
+
"""
|
27
|
+
)
|
28
|
+
text_content = self.page.locator("script-py").text_content()
|
29
|
+
assert "a & b" == text_content
|
30
|
+
|
31
|
+
def test_quot(self):
|
32
|
+
self.pyscript_run(
|
33
|
+
r"""
|
34
|
+
<script type="py">
|
35
|
+
from pyscript import display
|
36
|
+
display('a " b')
|
37
|
+
</script>
|
38
|
+
"""
|
39
|
+
)
|
40
|
+
text_content = self.page.locator("script-py").text_content()
|
41
|
+
assert "a " b" == text_content
|
42
|
+
|
43
|
+
def test_lt_gt(self):
|
44
|
+
self.pyscript_run(
|
45
|
+
r"""
|
46
|
+
<script type="py">
|
47
|
+
from pyscript import display
|
48
|
+
display('< < > >')
|
49
|
+
</script>
|
50
|
+
"""
|
51
|
+
)
|
52
|
+
text_content = self.page.locator("script-py").text_content()
|
53
|
+
assert "< < > >" == text_content
|
54
|
+
|
55
|
+
def test_dynamically_add_script_type_py_tag(self):
|
56
|
+
self.pyscript_run(
|
57
|
+
"""
|
58
|
+
<script>
|
59
|
+
function addPyScriptTag() {
|
60
|
+
let tag = document.createElement('script');
|
61
|
+
tag.type = 'py';
|
62
|
+
tag.textContent = "print('hello world')";
|
63
|
+
document.body.appendChild(tag);
|
64
|
+
}
|
65
|
+
addPyScriptTag();
|
66
|
+
</script>
|
67
|
+
"""
|
68
|
+
)
|
69
|
+
# please note the test here was on timeout
|
70
|
+
# incapable of finding a <button> after the script
|
71
|
+
self.page.locator("script-py")
|
72
|
+
|
73
|
+
assert self.console.log.lines[-1] == "hello world"
|
74
|
+
|
75
|
+
def test_script_type_py_src_attribute(self):
|
76
|
+
self.writefile("foo.py", "print('hello from foo')")
|
77
|
+
self.pyscript_run(
|
78
|
+
"""
|
79
|
+
<script type="py" src="foo.py"></script>
|
80
|
+
"""
|
81
|
+
)
|
82
|
+
assert self.console.log.lines[-1] == "hello from foo"
|
83
|
+
|
84
|
+
@pytest.mark.skip("FIXME: test failure is unrelated")
|
85
|
+
def test_script_type_py_worker_attribute(self):
|
86
|
+
self.writefile("foo.py", "print('hello from foo')")
|
87
|
+
self.pyscript_run(
|
88
|
+
"""
|
89
|
+
<script type="py" worker="foo.py"></script>
|
90
|
+
"""
|
91
|
+
)
|
92
|
+
assert self.console.log.lines[-1] == "hello from foo"
|
93
|
+
|
94
|
+
@pytest.mark.skip("FIXME: output attribute is not implemented")
|
95
|
+
def test_script_type_py_output_attribute(self):
|
96
|
+
self.pyscript_run(
|
97
|
+
"""
|
98
|
+
<div id="first"></div>
|
99
|
+
<script type="py" output="first">
|
100
|
+
print("<p>Hello</p>")
|
101
|
+
</script>
|
102
|
+
"""
|
103
|
+
)
|
104
|
+
text = self.page.locator("#first").text_content()
|
105
|
+
assert "<p>Hello</p>" in text
|
106
|
+
|
107
|
+
@pytest.mark.skip("FIXME: stderr attribute is not implemented")
|
108
|
+
def test_script_type_py_stderr_attribute(self):
|
109
|
+
self.pyscript_run(
|
110
|
+
"""
|
111
|
+
<div id="stdout-div"></div>
|
112
|
+
<div id="stderr-div"></div>
|
113
|
+
<py-script output="stdout-div" stderr="stderr-div">
|
114
|
+
import sys
|
115
|
+
print("one.", file=sys.stderr)
|
116
|
+
print("two.")
|
117
|
+
</py-script>
|
118
|
+
"""
|
119
|
+
)
|
120
|
+
assert self.page.locator("#stdout-div").text_content() == "one.two."
|
121
|
+
assert self.page.locator("#stderr-div").text_content() == "one."
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from .support import PyScriptTest
|
4
|
+
|
5
|
+
|
6
|
+
class TestShadowRoot(PyScriptTest):
|
7
|
+
# @skip_worker("FIXME: js.document")
|
8
|
+
@pytest.mark.skip("FIXME: Element interface is gone. Replace with PyDom")
|
9
|
+
def test_reachable_shadow_root(self):
|
10
|
+
self.pyscript_run(
|
11
|
+
r"""
|
12
|
+
<script>
|
13
|
+
// reason to wait for py-script is that it's the entry point for
|
14
|
+
// all patches and the MutationObserver, otherwise being this a synchronous
|
15
|
+
// script the constructor gets instantly invoked at the node before
|
16
|
+
// py-script gets a chance to initialize itself.
|
17
|
+
customElements.whenDefined('py-script').then(() => {
|
18
|
+
customElements.define('s-r', class extends HTMLElement {
|
19
|
+
constructor() {
|
20
|
+
super().attachShadow({mode: 'closed'}).innerHTML =
|
21
|
+
'<div id="shadowed">OK</div>';
|
22
|
+
}
|
23
|
+
});
|
24
|
+
});
|
25
|
+
</script>
|
26
|
+
<s-r></s-r>
|
27
|
+
<py-script>
|
28
|
+
import js
|
29
|
+
js.console.log(Element("shadowed").innerHtml)
|
30
|
+
</py-script>
|
31
|
+
"""
|
32
|
+
)
|
33
|
+
assert self.console.log.lines[-1] == "OK"
|
@@ -0,0 +1,124 @@
|
|
1
|
+
import pytest
|
2
|
+
from playwright.sync_api import expect
|
3
|
+
|
4
|
+
from .support import PyScriptTest, skip_worker
|
5
|
+
|
6
|
+
pytest.skip(
|
7
|
+
reason="DECIDE: Should we remove the splashscreen?", allow_module_level=True
|
8
|
+
)
|
9
|
+
|
10
|
+
|
11
|
+
class TestSplashscreen(PyScriptTest):
|
12
|
+
def test_autoshow_and_autoclose(self):
|
13
|
+
"""
|
14
|
+
By default, we show the splashscreen and we close it when the loading is
|
15
|
+
complete.
|
16
|
+
|
17
|
+
XXX: this test is a bit fragile: now it works reliably because the
|
18
|
+
startup is so slow that when we do expect(div).to_be_visible(), the
|
19
|
+
splashscreen is still there. But in theory, if the startup become very
|
20
|
+
fast, it could happen that by the time we arrive in python lang, it
|
21
|
+
has already been removed.
|
22
|
+
"""
|
23
|
+
self.pyscript_run(
|
24
|
+
"""
|
25
|
+
<py-script>
|
26
|
+
print('hello pyscript')
|
27
|
+
</py-script>
|
28
|
+
""",
|
29
|
+
wait_for_pyscript=False,
|
30
|
+
)
|
31
|
+
div = self.page.locator("py-splashscreen > div")
|
32
|
+
expect(div).to_be_visible()
|
33
|
+
expect(div).to_contain_text("Python startup...")
|
34
|
+
assert "Python startup..." in self.console.info.text
|
35
|
+
#
|
36
|
+
# now we wait for the startup to complete
|
37
|
+
self.wait_for_pyscript()
|
38
|
+
#
|
39
|
+
# and now the splashscreen should have been removed
|
40
|
+
expect(div).to_be_hidden()
|
41
|
+
assert self.page.locator("py-locator").count() == 0
|
42
|
+
|
43
|
+
assert "hello pyscript" in self.console.log.lines
|
44
|
+
|
45
|
+
def test_autoclose_false(self):
|
46
|
+
self.pyscript_run(
|
47
|
+
"""
|
48
|
+
<py-config>
|
49
|
+
[splashscreen]
|
50
|
+
autoclose = false
|
51
|
+
</py-config>
|
52
|
+
<py-script>
|
53
|
+
print('hello pyscript')
|
54
|
+
</py-script>
|
55
|
+
""",
|
56
|
+
)
|
57
|
+
div = self.page.locator("py-splashscreen > div")
|
58
|
+
expect(div).to_be_visible()
|
59
|
+
expect(div).to_contain_text("Python startup...")
|
60
|
+
expect(div).to_contain_text("Startup complete")
|
61
|
+
assert "hello pyscript" in self.console.log.lines
|
62
|
+
|
63
|
+
def test_autoclose_loader_deprecated(self):
|
64
|
+
self.pyscript_run(
|
65
|
+
"""
|
66
|
+
<py-config>
|
67
|
+
autoclose_loader = false
|
68
|
+
</py-config>
|
69
|
+
<py-script>
|
70
|
+
print('hello pyscript')
|
71
|
+
</py-script>
|
72
|
+
""",
|
73
|
+
)
|
74
|
+
warning = self.page.locator(".py-warning")
|
75
|
+
inner_text = warning.inner_html()
|
76
|
+
assert "The setting autoclose_loader is deprecated" in inner_text
|
77
|
+
|
78
|
+
div = self.page.locator("py-splashscreen > div")
|
79
|
+
expect(div).to_be_visible()
|
80
|
+
expect(div).to_contain_text("Python startup...")
|
81
|
+
expect(div).to_contain_text("Startup complete")
|
82
|
+
assert "hello pyscript" in self.console.log.lines
|
83
|
+
|
84
|
+
def test_splashscreen_disabled_option(self):
|
85
|
+
self.pyscript_run(
|
86
|
+
"""
|
87
|
+
<py-config>
|
88
|
+
[splashscreen]
|
89
|
+
enabled = false
|
90
|
+
</py-config>
|
91
|
+
|
92
|
+
<py-script>
|
93
|
+
def test():
|
94
|
+
print("Hello pyscript!")
|
95
|
+
test()
|
96
|
+
</py-script>
|
97
|
+
""",
|
98
|
+
)
|
99
|
+
assert self.page.locator("py-splashscreen").count() == 0
|
100
|
+
assert self.console.log.lines[-1] == "Hello pyscript!"
|
101
|
+
py_terminal = self.page.wait_for_selector("py-terminal")
|
102
|
+
assert py_terminal.inner_text() == "Hello pyscript!\n"
|
103
|
+
|
104
|
+
@skip_worker("FIXME: js.document")
|
105
|
+
def test_splashscreen_custom_message(self):
|
106
|
+
self.pyscript_run(
|
107
|
+
"""
|
108
|
+
<py-config>
|
109
|
+
[splashscreen]
|
110
|
+
autoclose = false
|
111
|
+
</py-config>
|
112
|
+
|
113
|
+
<py-script>
|
114
|
+
from js import document
|
115
|
+
|
116
|
+
splashscreen = document.querySelector("py-splashscreen")
|
117
|
+
splashscreen.log("Hello, world!")
|
118
|
+
</py-script>
|
119
|
+
""",
|
120
|
+
)
|
121
|
+
|
122
|
+
splashscreen = self.page.locator("py-splashscreen")
|
123
|
+
assert splashscreen.count() == 1
|
124
|
+
assert "Hello, world!" in splashscreen.inner_text()
|