forked from reactive-python/reactpy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_client.py
More file actions
125 lines (90 loc) · 3.96 KB
/
test_client.py
File metadata and controls
125 lines (90 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import asyncio
from pathlib import Path
import reactpy
from reactpy.testing import BackendFixture, DisplayFixture, poll
from tests.tooling.common import DEFAULT_TYPE_DELAY
from tests.tooling.hooks import use_counter
from . import pytestmark # noqa: F401
JS_DIR = Path(__file__).parent / "js"
async def test_automatic_reconnect(display: DisplayFixture, server: BackendFixture):
@reactpy.component
def SomeComponent():
count, incr_count = use_counter(0)
return reactpy.html(
reactpy.html.p({"data-count": count, "id": "count"}, "count", count),
reactpy.html.button(
{"onClick": lambda e: incr_count(), "id": "incr"}, "incr"
),
)
async def get_count():
# need to refetch element because may unmount on reconnect
count = await display.page.wait_for_selector("#count")
return await count.get_attribute("data-count")
await display.show(SomeComponent)
await poll(get_count).until_equals("0")
incr = await display.page.wait_for_selector("#incr")
await incr.click()
await poll(get_count).until_equals("1")
incr = await display.page.wait_for_selector("#incr")
await incr.click()
await poll(get_count).until_equals("2")
incr = await display.page.wait_for_selector("#incr")
await incr.click()
await server.restart()
await poll(get_count).until_equals("0")
incr = await display.page.wait_for_selector("#incr")
await incr.click()
await poll(get_count).until_equals("1")
incr = await display.page.wait_for_selector("#incr")
await incr.click()
await poll(get_count).until_equals("2")
incr = await display.page.wait_for_selector("#incr")
await incr.click()
async def test_style_can_be_changed(display: DisplayFixture):
"""This test was introduced to verify the client does not mutate the model
A bug was introduced where the client-side model was mutated and React was relying
on the model to have been copied in order to determine if something had changed.
See for more info: https://github.com/reactive-python/reactpy/issues/480
"""
@reactpy.component
def ButtonWithChangingColor():
color_toggle, set_color_toggle = reactpy.hooks.use_state(True)
color = "red" if color_toggle else "blue"
return reactpy.html.button(
{
"id": "my-button",
"onClick": lambda event: set_color_toggle(not color_toggle),
"style": {"backgroundColor": color, "color": "white"},
},
f"color: {color}",
)
await display.show(ButtonWithChangingColor)
button = await display.page.wait_for_selector("#my-button")
await poll(_get_style, button).until(
lambda style: style["background-color"] == "red"
)
for color in ["blue", "red"] * 2:
await button.click()
await poll(_get_style, button).until(
lambda style, c=color: style["background-color"] == c
)
async def _get_style(element):
items = (await element.get_attribute("style")).split(";")
pairs = [item.split(":", 1) for item in map(str.strip, items) if item]
return {key.strip(): value.strip() for key, value in pairs}
async def test_slow_server_response_on_input_change(display: DisplayFixture):
"""A delay server-side could cause input values to be overwritten.
For more info see: https://github.com/reactive-python/reactpy/issues/684
"""
delay = 0.2
@reactpy.component
def SomeComponent():
_value, set_value = reactpy.hooks.use_state("")
async def handle_change(event):
await asyncio.sleep(delay)
set_value(event["target"]["value"])
return reactpy.html.input({"onChange": handle_change, "id": "test-input"})
await display.show(SomeComponent)
inp = await display.page.wait_for_selector("#test-input")
await inp.type("hello", delay=DEFAULT_TYPE_DELAY)
assert (await inp.evaluate("node => node.value")) == "hello"