Skip to content

Commit 106aaed

Browse files
committed
revert #886 + add test + misc
1 parent 508e671 commit 106aaed

File tree

4 files changed

+48
-25
lines changed

4 files changed

+48
-25
lines changed

src/client/packages/idom-client-react/src/mount.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ function mountLayoutWithReconnectingWebSocket(
3838
socket.onopen = (event) => {
3939
console.info(`IDOM WebSocket connected.`);
4040

41+
if (mountState.everMounted) {
42+
ReactDOM.unmountComponentAtNode(element);
43+
}
4144
_resetOpenMountState(mountState);
4245

4346
mountLayout(element, {

src/idom/testing/common.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ async def until(
5656
condition: Callable[[_R], bool],
5757
timeout: float = IDOM_TESTING_DEFAULT_TIMEOUT.current,
5858
delay: float = _DEFAULT_POLL_DELAY,
59+
description: str = "condition to be true",
5960
) -> None:
6061
"""Check that the coroutines result meets a condition within the timeout"""
6162
started_at = time.time()
@@ -66,7 +67,7 @@ async def until(
6667
break
6768
elif (time.time() - started_at) > timeout: # pragma: no cover
6869
raise TimeoutError(
69-
f"Condition not met within {timeout} "
70+
f"Expected {description} after {timeout} "
7071
f"seconds - last value was {result!r}"
7172
)
7273

@@ -77,7 +78,12 @@ async def until_is(
7778
delay: float = _DEFAULT_POLL_DELAY,
7879
) -> None:
7980
"""Wait until the result is identical to the given value"""
80-
return await self.until(lambda left: left is right, timeout, delay)
81+
return await self.until(
82+
lambda left: left is right,
83+
timeout,
84+
delay,
85+
f"value to be identical to {right!r}",
86+
)
8187

8288
async def until_equals(
8389
self,
@@ -86,7 +92,12 @@ async def until_equals(
8692
delay: float = _DEFAULT_POLL_DELAY,
8793
) -> None:
8894
"""Wait until the result is equal to the given value"""
89-
return await self.until(lambda left: left == right, timeout, delay)
95+
return await self.until(
96+
lambda left: left == right,
97+
timeout,
98+
delay,
99+
f"value to equal {right!r}",
100+
)
90101

91102

92103
class HookCatcher:

tests/test_client.py

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
import idom
88
from idom.backend.utils import find_available_port
9-
from idom.testing import BackendFixture, DisplayFixture
9+
from idom.testing import BackendFixture, DisplayFixture, poll
1010
from tests.tooling.common import DEFAULT_TYPE_DELAY
11+
from tests.tooling.hooks import use_counter
1112

1213

1314
JS_DIR = Path(__file__).parent / "js"
@@ -21,45 +22,53 @@ async def test_automatic_reconnect(browser: Browser):
2122
page.set_default_timeout(10000)
2223

2324
@idom.component
24-
def OldComponent():
25-
return idom.html.p("old", id="old-component")
25+
def SomeComponent():
26+
count, incr_count = use_counter(0)
27+
return idom.html._(
28+
idom.html.p("count", count, data_count=count, id="count"),
29+
idom.html.button("incr", on_click=lambda e: incr_count(), id="incr"),
30+
)
2631

2732
async with AsyncExitStack() as exit_stack:
2833
server = await exit_stack.enter_async_context(BackendFixture(port=port))
2934
display = await exit_stack.enter_async_context(
3035
DisplayFixture(server, driver=page)
3136
)
3237

33-
await display.show(OldComponent)
38+
await display.show(SomeComponent)
3439

35-
# ensure the element is displayed before stopping the server
36-
await page.wait_for_selector("#old-component")
37-
38-
# the server is disconnected but the last view state is still shown
39-
await page.wait_for_selector("#old-component")
40+
count = await page.wait_for_selector("#count")
41+
incr = await page.wait_for_selector("#incr")
4042

41-
set_state = idom.Ref(None)
43+
for i in range(3):
44+
assert (await count.get_attribute("data-count")) == str(i)
45+
await incr.click()
4246

43-
@idom.component
44-
def NewComponent():
45-
state, set_state.current = idom.hooks.use_state(0)
46-
return idom.html.p(f"new-{state}", id=f"new-component-{state}")
47+
# the server is disconnected but the last view state is still shown
48+
await page.wait_for_selector("#count")
4749

4850
async with AsyncExitStack() as exit_stack:
4951
server = await exit_stack.enter_async_context(BackendFixture(port=port))
5052
display = await exit_stack.enter_async_context(
5153
DisplayFixture(server, driver=page)
5254
)
5355

54-
await display.show(NewComponent)
56+
# use mount instead of show to avoid a page refesh
57+
display.backend.mount(SomeComponent)
58+
59+
async def get_count():
60+
# need to refetch element because may unmount on reconnect
61+
count = await page.wait_for_selector("#count")
62+
return await count.get_attribute("data-count")
63+
64+
for i in range(3):
65+
# it may take a moment for the websocket to reconnect so need to poll
66+
await poll(get_count).until_equals(str(i))
5567

56-
# Note the lack of a page refresh before looking up this new component. The
57-
# client should attempt to reconnect and display the new view automatically.
58-
await page.wait_for_selector("#new-component-0")
68+
# need to refetch element because may unmount on reconnect
69+
incr = await page.wait_for_selector("#incr")
5970

60-
# check that we can resume normal operation
61-
set_state.current(1)
62-
await page.wait_for_selector("#new-component-1")
71+
await incr.click()
6372

6473

6574
async def test_style_can_be_changed(display: DisplayFixture):

tests/tooling/hooks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ def use_toggle(init=False):
1212

1313
def use_counter(initial_value):
1414
state, set_state = use_state(initial_value)
15-
return state, lambda: set_state(state + 1)
15+
return state, lambda: set_state(lambda old: old + 1)

0 commit comments

Comments
 (0)