Navigations
Introduction
CSTesting can navigate to URLs and work with navigations caused by page interactions (e.g. clicking a link or submitting a form). This page describes basic navigation, when the page is considered loaded, and how to wait for a specific URL after an action.
Basic navigation
The main way to open a URL is await browser.GotoAsync(url) (ICSTestingBrowser in C:\CSTesting-DotNet):
await browser.GotoAsync("https://example.com");
Playwright waits for the default load state after navigation. For an extra wait until the load event, call await browser.WaitForLoadAsync() after GotoAsync.
await browser.GotoAsync("https://example.com");
await browser.WaitForLoadAsync();
Current URL: await browser.GetUrlAsync(). The CSTesting .NET API does not expose Back, Forward, or Reload on ICSTestingBrowser; use EvaluateAsync if you need history.back() for a special case.
When is the page loaded?
Modern pages often do more after the load event: they fetch data lazily, fill in the UI, or load extra scripts and styles. There is no single definition of "fully loaded"; it depends on the page and framework.
Playwright-backed actions auto-wait for elements to be actionable before ClickAsync, TypeAsync, etc.
Example – navigate and click:
await browser.GotoAsync("https://example.com");
await browser.Locator("//*[contains(.,'Example Domain')]").First().ClickAsync();
If you prefer to wait for the document first, call await browser.WaitForLoadAsync() after GotoAsync:
await browser.GotoAsync("https://example.com");
await browser.WaitForLoadAsync();
await browser.Locator("h1").ClickAsync();
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
Clicking a link or submitting a form can trigger a navigation to a new URL. Use await browser.WaitForURLAsync(urlOrPattern, timeoutMs) after the action that triggers the navigation (Playwright URL match / glob semantics).
await browser.Locator("//*[contains(.,'Click me')]").First().ClickAsync();
await browser.WaitForURLAsync("**/login", 10_000);
var title = await browser.EvaluateAsync<string>("document.title");
Assert.That(title, Does.Contain("Login"));
Examples:
await browser.WaitForURLAsync("https://example.com/dashboard", 5_000);
await browser.WaitForURLAsync("**/dashboard", 5_000);
await browser.WaitForURLAsync("**/users/*/profile", 5_000);
If the URL doesn't match in time, WaitForURLAsync throws. Omit timeoutMs to use the default (30 seconds in the API).
Navigation and loading (overview)
Conceptually, showing a new document involves:
- Navigation – The URL changes (e.g. by
GotoAsyncor by clicking a link). The browser resolves the URL and may follow redirects. - Loading – The response is received, the document is parsed, scripts run, and the load event fires when the document and its main resources are loaded.
You can:
- Use
GotoAsync(url)to navigate. - Use
WaitForLoadAsync()after navigation when you need the full load event. - Use
WaitForURLAsync(urlOrPattern, timeoutMs)after an action that changes the URL. - Use
GetUrlAsync()to read the current URL.
There is no waitForNetworkIdle helper in the CSTesting .NET surface; rely on WaitForSelectorAsync / element state or Playwright-specific code if you need stricter network idle behavior.
Summary
| Topic | CSTesting |
|---|---|
| Open URL | await browser.GotoAsync(url) |
| Wait for load event | await browser.WaitForLoadAsync() |
| Back / forward / refresh | Not on ICSTestingBrowser; use EvaluateAsync for history if needed |
| Current URL | await browser.GetUrlAsync() |
| Wait for URL after action | await browser.WaitForURLAsync(urlOrPattern, timeoutMs) |
| When to interact | Playwright auto-waits on actions; add WaitForSelectorAsync / WaitForURLAsync when needed |
| Hydration issues | Disable controls until the app is hydrated; use slow network to reproduce. |