-
-
Notifications
You must be signed in to change notification settings - Fork 324
/
Copy pathtest_all.py
166 lines (121 loc) · 4.89 KB
/
test_all.py
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
from collections.abc import MutableMapping
import pytest
import reactpy
from reactpy import html
from reactpy.backend import default as default_implementation
from reactpy.backend._common import PATH_PREFIX
from reactpy.backend.types import BackendType, Connection, Location
from reactpy.backend.utils import all_implementations
from reactpy.testing import BackendFixture, DisplayFixture, poll
@pytest.fixture(
params=[*list(all_implementations()), default_implementation],
ids=lambda imp: imp.__name__,
)
async def display(page, request):
imp: BackendType = request.param
# we do this to check that route priorities for each backend are correct
if imp is default_implementation:
url_prefix = ""
opts = None
else:
url_prefix = str(PATH_PREFIX)
opts = imp.Options(url_prefix=url_prefix)
async with BackendFixture(implementation=imp, options=opts) as server:
async with DisplayFixture(
backend=server,
driver=page,
url_prefix=url_prefix,
) as display:
yield display
async def test_display_simple_hello_world(display: DisplayFixture):
@reactpy.component
def Hello():
return reactpy.html.p({"id": "hello"}, ["Hello World"])
await display.show(Hello)
await display.page.wait_for_selector("#hello")
# test that we can reconnect successfully
await display.page.reload()
await display.page.wait_for_selector("#hello")
async def test_display_simple_click_counter(display: DisplayFixture):
@reactpy.component
def Counter():
count, set_count = reactpy.hooks.use_state(0)
return reactpy.html.button(
{
"id": "counter",
"on_click": lambda event: set_count(lambda old_count: old_count + 1),
},
f"Count: {count}",
)
await display.show(Counter)
counter = await display.page.wait_for_selector("#counter")
for i in range(5):
await poll(counter.text_content).until_equals(f"Count: {i}")
await counter.click()
async def test_use_connection(display: DisplayFixture):
conn = reactpy.Ref()
@reactpy.component
def ShowScope():
conn.current = reactpy.use_connection()
return html.pre({"id": "scope"}, str(conn.current))
await display.show(ShowScope)
await display.page.wait_for_selector("#scope")
assert isinstance(conn.current, Connection)
async def test_use_scope(display: DisplayFixture):
scope = reactpy.Ref()
@reactpy.component
def ShowScope():
scope.current = reactpy.use_scope()
return html.pre({"id": "scope"}, str(scope.current))
await display.show(ShowScope)
await display.page.wait_for_selector("#scope")
assert isinstance(scope.current, MutableMapping)
async def test_use_location(display: DisplayFixture):
location = reactpy.Ref()
@poll
async def poll_location():
"""This needs to be async to allow the server to respond"""
return getattr(location, "current", None)
@reactpy.component
def ShowRoute():
location.current = reactpy.use_location()
return html.pre(str(location.current))
await display.show(ShowRoute)
await poll_location.until_equals(Location("/", ""))
for loc in [
Location("/something", ""),
Location("/something/file.txt", ""),
Location("/another/something", ""),
Location("/another/something/file.txt", ""),
Location("/another/something/file.txt", "?key=value"),
Location("/another/something/file.txt", "?key1=value1&key2=value2"),
]:
await display.goto(loc.pathname + loc.search)
await poll_location.until_equals(loc)
@pytest.mark.parametrize("hook_name", ["use_request", "use_websocket"])
async def test_use_request(display: DisplayFixture, hook_name):
hook = getattr(display.backend.implementation, hook_name, None)
if hook is None:
pytest.skip(f"{display.backend.implementation} has no '{hook_name}' hook")
hook_val = reactpy.Ref()
@reactpy.component
def ShowRoute():
hook_val.current = hook()
return html.pre({"id": "hook"}, str(hook_val.current))
await display.show(ShowRoute)
await display.page.wait_for_selector("#hook")
# we can't easily narrow this check
assert hook_val.current is not None
@pytest.mark.parametrize("imp", all_implementations())
async def test_customized_head(imp: BackendType, page):
custom_title = f"Custom Title for {imp.__name__}"
@reactpy.component
def sample():
return html.h1(f"^ Page title is customized to: '{custom_title}'")
async with BackendFixture(
implementation=imp,
options=imp.Options(head=html.title(custom_title)),
) as server:
async with DisplayFixture(backend=server, driver=page) as display:
await display.show(sample)
assert (await display.page.title()) == custom_title