Navigations

Introduction

CSTesting for Python (C:\CSTesting-Python) uses Playwright. Navigation APIs are async and live on BrowserApi in cstesting/browser.py.

Basic navigation

Open a URL with await browser.goto(url) (not gotoUrl).

await browser.goto("https://example.com")

After navigation, optionally wait for the load event with await browser.wait_for_load() (maps to Playwright wait_for_load_state("load")).

await browser.goto("https://example.com")
await browser.wait_for_load()

Current URL: current = await browser.url() (async method).

Back / forward / reload are not wrapped on BrowserApi in the current Python package; use await browser.evaluate("history.back()") or extend the wrapper if you need them.

When is the page loaded?

Playwright actions auto-wait for elements to be actionable. You usually only need wait_for_load when you explicitly want document load before the next step.

Example – navigate and click:

await browser.goto("https://example.com")
await browser.locator("h1").first().click()

With wait_for_load:

await browser.goto("https://example.com")
await browser.wait_for_load()
await browser.locator("h1").first().click()

Hydration

Sometimes you'll see a case where an action seems to do nothing—for example you click a button and nothing happens, or you type into an input and the text disappears. A common cause is poor hydration (e.g. in SPAs).

With hydration, the server first sends a static version of the page; then the dynamic part loads and the page becomes "live." If CSTesting interacts as soon as the button is visible but before the app has attached its listeners, the click may have no effect or the input may be reset when the framework takes over.

To check for this, you can slow down the network (e.g. Chrome DevTools → Network → "Slow 3G"), reload the page, and try interacting as soon as the element appears. If clicks are ignored or text is cleared, the fix is on the app side: disable interactive controls until after hydration, when the page is fully functional.

Waiting for navigation

After a click or submit that changes the URL, use await browser.wait_for_url(pattern, options). Pass a string (glob with *) or a compiled re.Pattern. Timeout is in the options dict in milliseconds (default 30000).

from cstesting import expect

await browser.locator("a.login").first().click()
await browser.wait_for_url("**/login", {"timeout": 10000})
title = await browser.evaluate("document.title")
expect(title).to_contain("Login")

More examples:

await browser.wait_for_url("https://example.com/dashboard", {"timeout": 5000})
await browser.wait_for_url("**/users/*/profile", {"timeout": 5000})
  • await browser.goto(url) — navigate.
  • await browser.wait_for_load() — after goto, wait for load state.
  • await browser.wait_for_url(...) — after an action, wait until URL matches.
  • await browser.url() — read current URL.
  • await browser.wait_for_selector(sel, {"timeout": 5000}) — wait for an element.

Summary

TopicPython (BrowserApi)
Open URLawait browser.goto(url)
Wait for document loadawait browser.wait_for_load()
Current URLawait browser.url()
Wait for URL after actionawait browser.wait_for_url(pattern, {"timeout": ms})
When to interactPlaywright auto-waits on actions; add wait_for_load / wait_for_url when needed.
HydrationSame guidance as other stacks—ensure UI is ready before acting.