Browser Testing (Dusk)
The testing/browser package is a Dusk-style end-to-end harness. It drives your app in-process through its http.Handler (the router), keeping a cookie jar so sessions, auth, and CSRF flow exactly as in a real browser. Because Nimbus renders HTML on the server, complete user journeys — visiting pages, following links, filling and submitting forms, asserting on-page text — need no external browser and run at unit-test speed.
A full journey
import "github.com/CodeSyncr/nimbus/testing/browser"
func TestLoginJourney(t *testing.T) {
app := bootstrapTestApp(t) // your app with routes registered
b := browser.New(t, app.Router)
b.Visit("/dashboard").
AssertPathIs("/login"). // redirected: not authenticated
AssertSee("Sign in")
b.Fill("email", "a@b.com").
Fill("password", "secret").
Press("Log in"). // hidden CSRF input carried automatically
AssertPathIs("/dashboard"). // 302 followed; session cookie kept
AssertSee("Welcome back").
AssertTitle("Dashboard")
b.ClickLink("Account settings").
AssertQueryStringHas("tab", "profile").
AssertSeeIn("h1", "Settings")
}
Navigation & interaction
| Method | Does |
|---|---|
| Visit(path) | GET a page, following redirects |
| ClickLink(text) | Follow the first link whose text matches |
| Fill / Type(name, v) | Queue a form field value |
| Check / Uncheck / Select | Checkbox and select helpers |
| Press(buttonText) | Submit the form with that button; carries hidden inputs |
| Submit() | Submit the first form on the page |
Assertions
Every assertion fails the test on mismatch and returns the browser for chaining:
AssertOk() AssertStatus(code)
AssertSee(text) AssertDontSee(text) AssertSeeIn(selector, text)
AssertPathIs(path) AssertPathBeginsWith(prefix)
AssertQueryStringHas(key, value...)
AssertTitle(text) AssertInputValue(name, value) AssertHeader(key, value)
Accessors Status(), Path(), Body(), Text() (tags stripped), and Value(name) let you assert with plain Go when you need something bespoke. Selectors for AssertSeeIn support a tag name, .class, or #id.
Real JavaScript
The in-process browser executes no JavaScript. For flows that genuinely require a rendered DOM (client-side SPA widgets), run your app with httptest.NewServer and drive a headless Chrome with chromedp against its URL. For server-rendered pages and Livewire round-trips (which post back to the server), the in-process browser is faster and needs no browser binary.