By onsi
Write fast, stable browser tests in Go using Biloba with Ginkgo/Gomega. Set up a Ginkgo suite with Biloba, use the dual immediate/matcher API and XPath DSL for element selection, debug failures with DOM outlines and screenshots, and explore unfamiliar pages to draft starter specs.
One-line reference for every Biloba method and matcher, grouped by area — lifecycle, navigation, cookies/storage, tabs, DOM existence/visibility/contents/properties/forms, clicking and interactions, keyboard, uploads, element JS, dialogs, downloads, arbitrary JS, network stubbing/observing, and screenshots/outline/window. Use to look up the exact method or matcher name and shape. Methods marked (dual) act immediately when fully applied and return a pollable matcher when under-applied.
See why a Biloba spec failed — the on-failure artifacts (DOM outline + screenshots), how Biloba auto-adapts to humans vs CI vs AI agents, the env vars and config knobs that surface them (BILOBA_SCREENSHOTS_DIR, BILOBA_INLINE_SCREENSHOTS, BILOBA_INTERACTIVE, BilobaConfig*), and using b.Outline()/b.A11yOutline() to understand why a selector didn't match. Use when a browser spec is failing and you need visibility, or to configure failure output for CI/agents.
Orient to a page or app you haven't seen, then draft a starter Biloba spec. Use when writing browser tests against an unfamiliar URL or fixture — it drives the page once to dump its DOM outline, accessibility tree, and a screenshot so you can SEE it, then proposes a spec with sensible readiness anchors and interactions. Covers the orient-then-author loop and cleanup. Also invokable as /biloba:explore-unfamiliar-page <url-or-fixture>.
The Biloba mental model for writing browser tests in your own Ginkgo/Gomega suite — the three principles and the consequences they have for how you write specs (pragmatic simulation, never-polls, drop-to-chromedp). Use this first when you start working with Biloba in a project, or to decide whether Biloba fits a testing task. Routes to the other biloba:* skills.
Wire Biloba into your project's Ginkgo suite — go get, the bootstrap file (SynchronizedBeforeSuite + Prepare), installing chrome-headless-shell, choosing high-fidelity vs the fast headless shell, the three bootstrap variations (shared vs per-process browser, reusable vs fresh tab), window size, and running the suite. Use when setting up Biloba in a repo or changing the suite-level Chrome lifecycle.
Own this plugin?
Verify ownership to unlock analytics, metadata editing, and a verified badge. GitHub access is read-only (username + org membership).
Sign in to claimOwn this plugin?
Verify ownership to unlock analytics, metadata editing, and a verified badge. GitHub access is read-only (username + org membership).
Sign in to claimBased on adoption, maintenance, documentation, and repository signals. Not a security audit or endorsement.

"Automated browser testing is slow and flaky" - every developer, ever
Biloba builds on top of chromedp to bring stable, performant, automated browser testing to Ginkgo. It embraces three principles:
It's blazing fast and designed to work well with AI toolchains like Claude Code. It's under active development and use as I build out a new feature-rich single-page app with Claude.
Take a look at the documentation to learn more and get started!
Here's a quick taste of what Biloba specs look like:
func login(tab *Biloba, user string, password string) {
GinkgoHelper()
tab.Navigate("/login")
Eventually("#user").Should(tab.SetValue("sally"))
tab.SetValue("#password", "yllas")
tab.Click("#log-in")
Eventually(".chat-page").Should(tab.Exist())
}
Describe("a simple chat app", func() {
var tab *Biloba
BeforeEach(func() {
login(b, "sally", "yllas")
tab = b.NewTab()
login(tab, "jane", "enaj")
})
It("shows all logged in users as present", func() {
userXPath := b.XPath("div").WithID("user-list").Descendant()
// b should show both users
Eventually(userXPath.WithText("Sally")).Should(b.HaveClass("online"))
Eventually(userXPath.WithText("Jane")).Should(b.HaveClass("online"))
// tab should show both users
Eventually(userXPath.WithText("Sally")).Should(tab.HaveClass("online"))
Eventually(userXPath.WithText("Jane")).Should(tab.HaveClass("online"))
})
It("shows Jane when Sally is typing", func() {
lastEntryXPath := tab.XPath("#conversation").Descendant().WithClass("entry").Last()
b.SetValue("#input", "Hey Jane, how are you?")
Eventually(lastEntryXPath).Should(SatisfyAll(
tab.HaveInnerText("Jane is typing..."),
tab.HaveClass("typing"),
))
b.SetValue("#input", "")
Eventually(lastEntryXPath).ShouldNot(SatisfyAny(
tab.HaveInnerText("Jane is typing..."),
tab.HaveClass("typing"),
))
})
It("shows Jane new messages from Sally, and sally new messages from Jane", func() {
lastEntryXPath := tab.XPath("#conversation").Descendant().WithClass("entry").Last()
b.SetValue("#input", "Hey Jane, how are you?")
b.Click("#send")
Eventually(lastEntryXPath).Should(tab.HaveInnerText("Hey Jane, how are you?"))
tab.SetValue("#input", "I'm splendid, Sally!")
tab.Click("#send")
Eventually(lastEntryXPath).Should(b.HaveInnerText("I'm splendid, Sally!"))
})
It("tracks when users aren't online", func() {
userXPath := b.XPath("div").WithID("user-list").Descendant()
Eventually(userXPath.WithText("Jane")).Should(b.HaveClass("online"))
tab.Close()
Eventually(userXPath.WithText("Jane")).Should(b.HaveClass("offline"))
})
})
Run these in series with ginkgo. And in parallel with ginkgo -p for fast, stable, isolated browser tests.
Biloba is quite feature complete and in active development. However, a 1.0 release milestone has not been reached yet, so the public API contract may shift as the project evolves.
Biloba automatically captures and emits screenshots and any JavaScript console output when tests fail. It even hooks into Ginkgo's progress emitter infrastructure so ^T/SIGNIFO on a mac (SIGUSR2 on linux) will spit out a screenshot.
Screenshots are great for humans but won't show up in most CI systems and don't help AI agents. Biloba autodetects when it's being run in CI or by an agent and spits out DOM outlines and puts screenshot files on disk instead automatically.
Biloba ships a set of Claude Code skills as a plugin, with this repo doubling as the marketplace. From inside Claude Code:
/plugin marketplace add onsi/biloba
/plugin install biloba@biloba
(or non-interactively: claude plugin marketplace add onsi/biloba then claude plugin install biloba@biloba)
Ginkgo Tree Graphics Designed By 可行 From LovePik.com
npx claudepluginhub onsi/biloba --plugin bilobaWrite, run, and debug Ginkgo/Gomega test suites in Go. Skills for the tree-construction mental model, spec authoring and cleanup, tables and generated specs, the full decorator reference, filtering, parallelism, ordered/flaky specs, timeouts and async, the CLI and CI configuration, reporting, and JSON-first failure diagnosis.
Write expressive, correct Gomega assertions in Go. Skills for the Expect/Ω model, synchronous and asynchronous (Eventually/Consistently) assertions, the full matcher catalog, composing and authoring custom matchers, and the gstruct, ghttp, gexec, gbytes, gleak, and gmeasure sub-libraries.
Write, run, and debug Ginkgo/Gomega test suites in Go. Skills for the tree-construction mental model, spec authoring and cleanup, tables and generated specs, the full decorator reference, filtering, parallelism, ordered/flaky specs, timeouts and async, the CLI and CI configuration, reporting, and JSON-first failure diagnosis.
End-to-end test automation with Playwright, Cypress, and Selenium for browser-based testing
Simplified CLI-integrated plugin for E2E testing with essential slash commands plus dynamic API CLI workflows (`qa-use api`). Provides AI-first feature verification, browser automation, and test management. All CLI operations documented in SKILL.md and accessible via `qa-use docs` for harness compatibility.
Playwright E2E test debugging and interactive browser exploration. Runs tests with action capture (DOM snapshots, network, console, screenshots), diagnoses failures, and provides browser tools for navigating, clicking, and inspecting pages through ARIA snapshots.
Browser automation and E2E testing with Playwright. Auto-detects dev servers, writes clean test scripts. Test pages, fill forms, take screenshots, check responsive design, validate UX, test login flows, check links, automate any browser task. Use for cross-browser testing, visual regression, API testing, component testing in TypeScript/JavaScript and Python projects.
Browser automation plugin for agent-driven web app testing, inspection, and debugging.