Skip to content

Commit 493fdec

Browse files
committed
implement test_module
1 parent 10679cb commit 493fdec

File tree

5 files changed

+59
-44
lines changed

5 files changed

+59
-44
lines changed

re.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ display\((.*?)\)
55
page = await display.show($1)
66

77
driver\.find_element\("id", "(.*?)"\)
8-
await display.wait_for_selector("#$1")
8+
await page.wait_for_selector("#$1")
9+
await page.wait_for_selector("#$1", state="attached")
910

1011
driver_wait\.until\(lambda .*: (\w*)\.get_attribute\("(.*?)"\) == (.*)\)
1112
assert (await $1.evaluate("node => node['$2']")) == $3

requirements/test-env.txt

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ pytest-rerunfailures
77
pytest-timeout
88
responses
99
playwright
10+
pytest-playwright

src/idom/testing.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ def until(
113113
self.until: Callable[[Callable[[_R], bool]], Any] = until
114114
"""Check that the coroutines result meets a condition within the timeout"""
115115

116+
def until_is(self, right: Any, timeout: float = _DEFAULT_TIMEOUT) -> Any:
117+
"""Wait until the result is identical to the given value"""
118+
return self.until(lambda left: left is right, timeout)
119+
116120
def until_equals(self, right: Any, timeout: float = _DEFAULT_TIMEOUT) -> Any:
117121
"""Wait until the result is equal to the given value"""
118122
return self.until(lambda left: left == right, timeout)
@@ -197,13 +201,22 @@ def __init__(
197201
self,
198202
host: str = "127.0.0.1",
199203
port: Optional[int] = None,
204+
app: Any | None = None,
200205
implementation: ServerImplementation[Any] = default_server,
201206
) -> None:
202207
self.server_implementation = implementation
203208
self.host = host
204209
self.port = port or find_available_port(host, allow_reuse_waiting_ports=False)
205210
self.mount, self._root_component = hotswap()
206211

212+
if app is not None:
213+
if implementation is None:
214+
raise ValueError(
215+
"If an application instance its corresponding "
216+
"server implementation must be provided too."
217+
)
218+
self._app = app
219+
207220
@property
208221
def log_records(self) -> List[logging.LogRecord]:
209222
"""A list of captured log records"""
@@ -259,7 +272,7 @@ def list_logged_exceptions(
259272
async def __aenter__(self: _Self) -> _Self:
260273
self._log_handler = _LogRecordCaptor()
261274
logging.getLogger().addHandler(self._log_handler)
262-
app = self.server_implementation.create_development_app()
275+
app = self._app or self.server_implementation.create_development_app()
263276
self.server_implementation.configure(app, self._root_component)
264277

265278
started = asyncio.Event()

tests/conftest.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
from _pytest.config.argparsing import Parser
66
from playwright.async_api import async_playwright
77

8-
from idom.server.utils import all_implementations
98
from idom.testing import DisplayFixture, ServerFixture, clear_idom_web_modules_dir
109
from tests.tooling.loop import open_event_loop
1110

1211

1312
def pytest_addoption(parser: Parser) -> None:
1413
parser.addoption(
15-
"--open-browser",
16-
dest="open_browser",
14+
"--headed",
15+
dest="headed",
1716
action="store_true",
1817
help="Open a browser window when runnging web-based tests",
1918
)
@@ -34,6 +33,7 @@ async def server():
3433
@pytest.fixture(scope="session")
3534
async def page(browser):
3635
pg = await browser.new_page()
36+
pg.set_default_timeout(5000)
3737
try:
3838
yield pg
3939
finally:
@@ -43,9 +43,7 @@ async def page(browser):
4343
@pytest.fixture(scope="session")
4444
async def browser(pytestconfig: Config):
4545
async with async_playwright() as pw:
46-
yield await pw.chromium.launch(
47-
headless=not bool(pytestconfig.option.open_browser)
48-
)
46+
yield await pw.chromium.launch(headless=not bool(pytestconfig.option.headed))
4947

5048

5149
@pytest.fixture(scope="session")

tests/test_web/test_module.py

+38-36
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from pathlib import Path
2+
from sys import implementation
23

34
import pytest
45
from sanic import Sanic
@@ -7,15 +8,21 @@
78
from selenium.webdriver.support.ui import WebDriverWait
89

910
import idom
10-
from idom.server.sanic import PerClientStateServer
11-
from idom.testing import ServerFixture, assert_idom_did_not_log, assert_idom_logged
11+
from idom.server import sanic as sanic_implementation
12+
from idom.testing import (
13+
DisplayFixture,
14+
ServerFixture,
15+
assert_idom_did_not_log,
16+
assert_idom_logged,
17+
poll,
18+
)
1219
from idom.web.module import NAME_SOURCE, WebModule
1320

1421

1522
JS_FIXTURES_DIR = Path(__file__).parent / "js_fixtures"
1623

1724

18-
def test_that_js_module_unmount_is_called(driver, display):
25+
async def test_that_js_module_unmount_is_called(display: DisplayFixture):
1926
SomeComponent = idom.web.export(
2027
idom.web.module_from_file(
2128
"set-flag-when-unmount-is-called",
@@ -33,23 +40,23 @@ def ShowCurrentComponent():
3340
)
3441
return current_component
3542

36-
display(ShowCurrentComponent)
43+
page = await display.show(ShowCurrentComponent)
3744

38-
driver.find_element("id", "some-component")
45+
await page.wait_for_selector("#some-component", state="attached")
3946

4047
set_current_component.current(
4148
idom.html.h1({"id": "some-other-component"}, "some other component")
4249
)
4350

4451
# the new component has been displayed
45-
driver.find_element("id", "some-other-component")
52+
await page.wait_for_selector("#some-other-component", state="attached")
4653

4754
# the unmount callback for the old component was called
48-
driver.find_element("id", "unmount-flag")
55+
await page.wait_for_selector("#unmount-flag", state="attached")
4956

5057

51-
def test_module_from_url(driver):
52-
app = Sanic(__name__)
58+
async def test_module_from_url(browser):
59+
app = Sanic("test_module_from_url")
5360

5461
# instead of directing the URL to a CDN, we just point it to this static file
5562
app.static(
@@ -67,30 +74,25 @@ def test_module_from_url(driver):
6774
def ShowSimpleButton():
6875
return SimpleButton({"id": "my-button"})
6976

70-
with ServerFixture(PerClientStateServer, app=app) as mount_point:
71-
mount_point.mount(ShowSimpleButton)
72-
driver.get(mount_point.url())
73-
driver.find_element("id", "my-button")
77+
async with ServerFixture(app=app, implementation=sanic_implementation) as server:
78+
async with DisplayFixture(server, browser) as display:
79+
page = await display.show(ShowSimpleButton)
80+
await page.wait_for_selector("#my-button")
7481

7582

7683
def test_module_from_template_where_template_does_not_exist():
7784
with pytest.raises(ValueError, match="No template for 'does-not-exist.js'"):
7885
idom.web.module_from_template("does-not-exist", "something.js")
7986

8087

81-
def test_module_from_template(driver, display):
88+
async def test_module_from_template(display: DisplayFixture):
8289
victory = idom.web.module_from_template("react", "[email protected]")
8390
VictoryBar = idom.web.export(victory, "VictoryBar")
84-
display(VictoryBar)
85-
wait = WebDriverWait(driver, 10)
86-
wait.until(
87-
expected_conditions.visibility_of_element_located(
88-
(By.CLASS_NAME, "VictoryContainer")
89-
)
90-
)
91+
page = await display.show(VictoryBar)
92+
await page.wait_for_selector(".VictoryContainer")
9193

9294

93-
def test_module_from_file(driver, driver_wait, display):
95+
async def test_module_from_file(display: DisplayFixture):
9496
SimpleButton = idom.web.export(
9597
idom.web.module_from_file(
9698
"simple-button", JS_FIXTURES_DIR / "simple-button.js"
@@ -106,11 +108,11 @@ def ShowSimpleButton():
106108
{"id": "my-button", "onClick": lambda event: is_clicked.set_current(True)}
107109
)
108110

109-
display(ShowSimpleButton)
111+
page = await display.show(ShowSimpleButton)
110112

111-
button = driver.find_element("id", "my-button")
112-
button.click()
113-
driver_wait.until(lambda d: is_clicked.current)
113+
button = await page.wait_for_selector("#my-button")
114+
await button.click()
115+
poll(lambda: is_clicked.current).until_is(True)
114116

115117

116118
def test_module_from_file_source_conflict(tmp_path):
@@ -188,44 +190,44 @@ def test_module_missing_exports():
188190
idom.web.export(module, ["x", "y"])
189191

190192

191-
def test_module_exports_multiple_components(driver, display):
193+
async def test_module_exports_multiple_components(display: DisplayFixture):
192194
Header1, Header2 = idom.web.export(
193195
idom.web.module_from_file(
194196
"exports-two-components", JS_FIXTURES_DIR / "exports-two-components.js"
195197
),
196198
["Header1", "Header2"],
197199
)
198200

199-
display(lambda: Header1({"id": "my-h1"}, "My Header 1"))
201+
page = await display.show(lambda: Header1({"id": "my-h1"}, "My Header 1"))
200202

201-
driver.find_element("id", "my-h1")
203+
await page.wait_for_selector("#my-h1", state="attached")
202204

203-
display(lambda: Header2({"id": "my-h2"}, "My Header 2"))
205+
page = await display.show(lambda: Header2({"id": "my-h2"}, "My Header 2"))
204206

205-
driver.find_element("id", "my-h2")
207+
await page.wait_for_selector("#my-h2", state="attached")
206208

207209

208-
def test_imported_components_can_render_children(driver, display):
210+
async def test_imported_components_can_render_children(display: DisplayFixture):
209211
module = idom.web.module_from_file(
210212
"component-can-have-child", JS_FIXTURES_DIR / "component-can-have-child.js"
211213
)
212214
Parent, Child = idom.web.export(module, ["Parent", "Child"])
213215

214-
display(
216+
page = await display.show(
215217
lambda: Parent(
216218
Child({"index": 1}),
217219
Child({"index": 2}),
218220
Child({"index": 3}),
219221
)
220222
)
221223

222-
parent = driver.find_element("id", "the-parent")
223-
children = parent.find_elements("tag name", "li")
224+
parent = await page.wait_for_selector("#the-parent", state="attached")
225+
children = await parent.query_selector_all("li")
224226

225227
assert len(children) == 3
226228

227229
for index, child in enumerate(children):
228-
assert child.get_attribute("id") == f"child-{index + 1}"
230+
assert (await child.get_attribute("id")) == f"child-{index + 1}"
229231

230232

231233
def test_module_from_string():

0 commit comments

Comments
 (0)