forked from reactive-python/reactpy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_standalone.py
163 lines (116 loc) · 4.83 KB
/
test_standalone.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
from collections.abc import MutableMapping
import pytest
from requests import request
import reactpy
from reactpy import html
from reactpy.asgi.standalone import ReactPy
from reactpy.testing import BackendFixture, DisplayFixture, poll
from reactpy.testing.common import REACTPY_TESTS_DEFAULT_TIMEOUT
from reactpy.types import Connection, Location
@pytest.fixture()
async def display(page):
async with BackendFixture() as server:
async with DisplayFixture(backend=server, driver=page) 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",
"onClick": 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.path + loc.query_string)
await poll_location.until_equals(loc)
async def test_carrier(display: DisplayFixture):
hook_val = reactpy.Ref()
@reactpy.component
def ShowRoute():
hook_val.current = reactpy.hooks.use_connection().carrier
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
async def test_customized_head(page):
custom_title = "Custom Title for ReactPy"
@reactpy.component
def sample():
return html.h1(f"^ Page title is customized to: '{custom_title}'")
app = ReactPy(sample, html_head=html.head(html.title(custom_title)))
async with BackendFixture(app) as server:
async with DisplayFixture(backend=server, driver=page) as new_display:
await new_display.show(sample)
assert (await new_display.page.title()) == custom_title
async def test_head_request(page):
@reactpy.component
def sample():
return html.h1("Hello World")
app = ReactPy(sample)
async with BackendFixture(app) as server:
async with DisplayFixture(backend=server, driver=page) as new_display:
await new_display.show(sample)
url = f"http://{server.host}:{server.port}"
response = request(
"HEAD", url, timeout=REACTPY_TESTS_DEFAULT_TIMEOUT.current
)
assert response.status_code == 200
assert response.headers["content-type"] == "text/html; charset=utf-8"
assert response.headers["cache-control"] == "max-age=60, public"
assert response.headers["access-control-allow-origin"] == "*"
assert response.content == b""