|  | 
| 2 | 2 | from typing import Any | 
| 3 | 3 | 
 | 
| 4 | 4 | from playwright.async_api._generated import Browser, Page | 
| 5 |  | -from reactpy import Ref, component, html, use_location | 
|  | 5 | +from reactpy import Ref, component, html, use_location, use_state | 
| 6 | 6 | from reactpy.testing import DisplayFixture | 
| 7 | 7 | 
 | 
| 8 |  | -from reactpy_router import browser_router, link, route, use_params, use_search_params | 
|  | 8 | +from reactpy_router import browser_router, link, navigate, route, use_params, use_search_params | 
| 9 | 9 | 
 | 
| 10 | 10 | GITHUB_ACTIONS = os.getenv("GITHUB_ACTIONS", "").lower() == "true" | 
| 11 | 11 | CLICK_DELAY = 350 if GITHUB_ACTIONS else 25  # Delay in miliseconds. | 
| @@ -295,3 +295,56 @@ def sample(): | 
| 295 | 295 |     browser_context = browser.contexts[0] | 
| 296 | 296 |     new_page: Page = await browser_context.wait_for_event("page") | 
| 297 | 297 |     await new_page.wait_for_selector("#a") | 
|  | 298 | + | 
|  | 299 | + | 
|  | 300 | +async def test_navigate_component(display: DisplayFixture): | 
|  | 301 | +    @component | 
|  | 302 | +    def navigate_btn(): | 
|  | 303 | +        nav_url, set_nav_url = use_state("") | 
|  | 304 | + | 
|  | 305 | +        return html.button( | 
|  | 306 | +            {"onClick": lambda _: set_nav_url("/a")}, | 
|  | 307 | +            navigate(nav_url) if nav_url else "Click to navigate", | 
|  | 308 | +        ) | 
|  | 309 | + | 
|  | 310 | +    @component | 
|  | 311 | +    def sample(): | 
|  | 312 | +        return browser_router( | 
|  | 313 | +            route("/", navigate_btn()), | 
|  | 314 | +            route("/a", html.h1({"id": "a"}, "A")), | 
|  | 315 | +        ) | 
|  | 316 | + | 
|  | 317 | +    await display.show(sample) | 
|  | 318 | +    _button = await display.page.wait_for_selector("button") | 
|  | 319 | +    await _button.click(delay=CLICK_DELAY) | 
|  | 320 | +    await display.page.wait_for_selector("#a") | 
|  | 321 | +    await display.page.go_back() | 
|  | 322 | +    await display.page.wait_for_selector("button") | 
|  | 323 | + | 
|  | 324 | + | 
|  | 325 | +async def test_navigate_component_replace(display: DisplayFixture): | 
|  | 326 | +    @component | 
|  | 327 | +    def navigate_btn(to: str, replace: bool = False): | 
|  | 328 | +        nav_url, set_nav_url = use_state("") | 
|  | 329 | + | 
|  | 330 | +        return html.button( | 
|  | 331 | +            {"onClick": lambda _: set_nav_url(to), "id": f"nav-{to.replace('/', '')}"}, | 
|  | 332 | +            navigate(nav_url, replace) if nav_url else f"Navigate to {to}", | 
|  | 333 | +        ) | 
|  | 334 | + | 
|  | 335 | +    @component | 
|  | 336 | +    def sample(): | 
|  | 337 | +        return browser_router( | 
|  | 338 | +            route("/", navigate_btn("/a")), | 
|  | 339 | +            route("/a", navigate_btn("/b", replace=True)), | 
|  | 340 | +            route("/b", html.h1({"id": "b"}, "B")), | 
|  | 341 | +        ) | 
|  | 342 | + | 
|  | 343 | +    await display.show(sample) | 
|  | 344 | +    _button = await display.page.wait_for_selector("#nav-a") | 
|  | 345 | +    await _button.click(delay=CLICK_DELAY) | 
|  | 346 | +    _button = await display.page.wait_for_selector("#nav-b") | 
|  | 347 | +    await _button.click(delay=CLICK_DELAY) | 
|  | 348 | +    await display.page.wait_for_selector("#b") | 
|  | 349 | +    await display.page.go_back() | 
|  | 350 | +    await display.page.wait_for_selector("#nav-a") | 
0 commit comments