| name | explore-unfamiliar-page |
| description | 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>. |
Orienting to an unfamiliar page, then drafting a spec
Drive the page once to see it (DOM outline + a11y tree + screenshot), then write the spec against what you actually saw. Assumes Biloba is wired in (biloba:setup); the draft follows biloba:write-tests.
1. Drive the page once
Write a throwaway spec (zz_scratch_test.go) — you delete it in step 3.
package <suite>_test
import (
"fmt"
. "github.com/onsi/ginkgo/v2"
)
var _ = Describe("scratch", func() {
It("dumps the page", func() {
b.Navigate("<TARGET_URL>")
fmt.Println("=== DOM OUTLINE ===")
fmt.Println(b.Outline())
fmt.Println("=== A11Y OUTLINE ===")
fmt.Println(b.A11yOutline())
fmt.Println("SCREENSHOT:", b.CaptureScreenshotToFile("./tmp/scratch.png"))
})
})
ginkgo --no-color --focus="scratch"
Then Read the printed PNG path so you actually see the rendered page (what's visible, what's below the fold), and cross-reference the two outlines:
b.Outline() — raw DOM; your primary map for an app you own. Hunt for stable, intentional hooks (#id, [data-testid]) and target them with CSS — the default, fastest pathway. Avoid styling classes (.btn-primary) that get renamed in redesigns.
b.A11yOutline() — role + accessible name. Use it when there's no good hook, or when you want to assert the user-perceivable thing so the spec doubles as an a11y guard: b.ByRole("button").WithName("Save"), b.ByText(...), b.ByLabel("Email"), b.ByTestID(...). XPath is the rare fallback for axis/ordinal structure (biloba:xpath).
You get the same outline for free on a failure under CI or an AI agent (biloba:debug-failures) — once you're iterating in step 2, read it from the failure report instead of re-running the scratch spec.
2. Author the real spec
var _ = Describe("<feature>", func() {
BeforeEach(func() {
b.Navigate("<TARGET_URL>")
Eventually("<readiness anchor>").Should(b.Exist())
})
It("<does the obvious thing>", func() {
b.SetValue(b.ByLabel("Search"), "biloba")
b.Click(b.ByRole("button").WithName("Search"))
Eventually(".result").Should(b.HaveCount(BeNumerically(">", 0)))
})
})
A good draft:
3. Clean up
rm zz_scratch_test.go
rm -rf ./tmp/scratch.png
ginkgo -r -p
Report the new spec to the user and call out every // TODO and guess you left, so they know what to verify.