Skip to content

Commit

Permalink
test: make test more robust by non using globals and guessing the con…
Browse files Browse the repository at this point in the history
…text

We relied on a global variable to wait for the component to be called,
but this seems to not be very robust. Instead, we pass a unique ID
via a query parameter to not re-use the Event object, and store the
context that we actually use, instead of relying on the last used
context found.
  • Loading branch information
maartenbreddels committed Oct 6, 2023
1 parent f660bf9 commit 7b0d651
Showing 1 changed file with 26 additions and 16 deletions.
42 changes: 26 additions & 16 deletions solara/test/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import textwrap
import threading
import typing
import urllib.parse
import uuid
from io import BytesIO
from pathlib import Path
from typing import Any, Callable, Dict, Generator, List, Union
Expand All @@ -19,6 +21,7 @@
from IPython.display import display

import solara.server.app
import solara.server.kernel_context
import solara.server.server
import solara.server.settings
from solara.server import reload
Expand Down Expand Up @@ -155,37 +158,43 @@ def run(app: Union[solara.server.app.AppScript, str]):
used_app.close()


run_event = threading.Event()
run_calls = 0
run_events: Dict[str, threading.Event] = {}
used_contexts: Dict[str, solara.server.kernel_context.VirtualKernelContext] = {}


@solara.component
def SyncWrapper():
global run_calls
import reacton.ipywidgets as w
router = solara.use_router()
values = urllib.parse.parse_qs(router.search, keep_blank_values=True)
id = values.get("id", [None])[0] # type: ignore
if id is None:
solara.Error("No id found in url")
else:

import reacton.ipywidgets as w

run_calls += 1
run_event.set()
return w.VBox(children=[w.HTML(value="Test in solara"), w.VBox()])
used_contexts[id] = solara.server.kernel_context.get_current_context()
run_events[id].set()

return w.VBox(children=[w.HTML(value="Test in solara"), w.VBox()])


@contextlib.contextmanager
def _solara_test(solara_server, solara_app, page_session: "playwright.sync_api.Page"):
global run_calls
with solara_app("solara.test.pytest_plugin:SyncWrapper"):
assert len(solara.server.kernel_context.contexts) == 0
page_session.goto(solara_server.base_url)
id = str(uuid.uuid4())
run_events[id] = run_event = threading.Event()
page_session.goto(solara_server.base_url + f"?id={id}")
try:
run_event.wait()
assert run_calls == 1
keys = list(solara.server.kernel_context.contexts)
assert len(keys) == 1, "expected only one context, got %s" % keys
context = solara.server.kernel_context.contexts[keys[-1]]
assert run_event.wait(10)
context = used_contexts[id]
with context:
test_output_warmup = widgets.Output()
test_output = widgets.Output()
try:
page_session.locator("text=Test in solara").wait_for()
assert context.container
context.container.children[0].children[1].children[1].children = [test_output_warmup] # type: ignore
with test_output_warmup:
warmup()
Expand All @@ -202,8 +211,9 @@ def _solara_test(solara_server, solara_app, page_session: "playwright.sync_api.P
test_output.close()
test_output_warmup.close()
finally:
run_calls = 0
run_event.clear()
del run_events[id]
if id in used_contexts:
del used_contexts[id]


@pytest.fixture()
Expand Down

0 comments on commit 7b0d651

Please sign in to comment.