You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
wheels.wheelstest.BrowserTest wires this.browser (the BrowserClient) only inside browserDescribe() blocks. Plain describe() blocks inherited from wheels.WheelsTest look like they should work (since BrowserTest extends WheelsTest) but cause runtime failures.
Repro
A spec like this — the form shown in most internal samples and what a newcomer would write by analogy with TestBox BDD examples — fails:
```cfml
component extends="wheels.wheelstest.BrowserTest" {
function run() {
describe("my flow", () => {
it("does the thing", () => {
this.browser.visitUrl("data:text/html,
Hi
").assertSee("Hi");
});
});
}
}
```
Error: `function [visitUrl] does not exist in the String` (because `this.browser` is a String — its uninitialized default — inside a non-browserDescribe block).
Anyone writing their first BrowserTest hits this on iteration 1. The error message doesn't point at the cause (says `this.browser` is a String, not "you need browserDescribe").
Suggested fixes (any of)
Doc fix: prominently note the `browserDescribe()` requirement in the docstring at the top of `vendor/wheels/wheelstest/BrowserTest.cfc` (the existing sample uses `describe()`, which compounds the issue).
Better error message: when `this.browser` is a String at the moment a BrowserClient method is called, throw with a hint: "BrowserTest specs must use `browserDescribe()` blocks, not `describe()`. The framework wires `this.browser` only inside `browserDescribe()`."
Make it transparent: auto-wire `this.browser` for any `describe()` block inside a BrowserTest subclass.
Repo / version
CLI: `wheels 4.0.1`
Wheels Core: `4.0.0-SNAPSHOT+1779`
File: `vendor/wheels/wheelstest/BrowserTest.cfc`
Where found
Surfaced while dogfooding the BrowserTest infrastructure in Titan (DataPAI portal Phase 0).
🤖 Found while executing a Claude-Code-driven implementation plan
testing — see .ai/wheels/testing/browser-testing.md for canonical patterns. The defect lives in vendor/wheels/wheelstest/BrowserTest.cfc, which only wires this.browser inside browserDescribe() callbacks (see lines 38–41, 145–181) and leaves it as the empty-string default elsewhere, producing a misleading function [visitUrl] does not exist in the String error inside plain describe() blocks.
Fix sketch
Primary target: vendor/wheels/wheelstest/BrowserTest.cfc. The minimum-viable fix is option 2 from the report — when a spec uses describe() instead of browserDescribe(), detect that this.browser is still the uninitialized empty string and throw a clear "use browserDescribe() here" error (a guard in the existing browser-setup path, or a check-before-use in BrowserClient-bound methods). The docstring at the top of the file and the sample in .ai/wheels/testing/browser-testing.md should be updated in the same change to call out the requirement prominently. Auto-wiring this.browser for plain describe() blocks (option 3) is a larger design decision and not the right scope for the bug-fix path.
Confidence: medium
The reproduction and target file are unambiguous, but the report deliberately presents three different fix shapes (doc-only / better error / transparent auto-wire) and choosing between them is a judgment call rather than a mechanical change.
Picked the better error message path from the triage (option 2 in the report). Option 3 (auto-wire this.browser for plain describe() blocks) would have been a larger design decision and out of scope for the bug-fix path.
A human review is required before merge. Reviewer A and Reviewer B will weigh in shortly. Doc updates (MDX guides, .ai/wheels/, CLAUDE.md) are handled separately by bot-update-docs.yml.
Activity
wheels-bot commentedon May 21, 2026
Wheels Bot — Triage
Classified as bug.
Suspected layer
testing— see.ai/wheels/testing/browser-testing.mdfor canonical patterns. The defect lives invendor/wheels/wheelstest/BrowserTest.cfc, which only wiresthis.browserinsidebrowserDescribe()callbacks (see lines 38–41, 145–181) and leaves it as the empty-string default elsewhere, producing a misleadingfunction [visitUrl] does not exist in the Stringerror inside plaindescribe()blocks.Fix sketch
Primary target:
vendor/wheels/wheelstest/BrowserTest.cfc. The minimum-viable fix is option 2 from the report — when a spec usesdescribe()instead ofbrowserDescribe(), detect thatthis.browseris still the uninitialized empty string and throw a clear "usebrowserDescribe()here" error (a guard in the existing browser-setup path, or a check-before-use inBrowserClient-bound methods). The docstring at the top of the file and the sample in.ai/wheels/testing/browser-testing.mdshould be updated in the same change to call out the requirement prominently. Auto-wiringthis.browserfor plaindescribe()blocks (option 3) is a larger design decision and not the right scope for the bug-fix path.Confidence:
mediumThe reproduction and target file are unambiguous, but the report deliberately presents three different fix shapes (doc-only / better error / transparent auto-wire) and choosing between them is a judgment call rather than a mechanical change.
<!-- wheels-bot:triage:2778 -->
<!-- wheels-bot:triage-class:bug -->
<!-- wheels-bot:triage-confidence:medium -->
wheels-bot commentedon May 21, 2026
Wheels Bot — Fix proposed
Draft PR: #2782
Spec:
vendor/wheels/tests/specs/wheelstest/BrowserTestNotWiredSpec.cfc— failing → passingImplementation:
vendor/wheels/wheelstest/UnwiredBrowserGuard.cfc(new sentinel) +vendor/wheels/wheelstest/BrowserTest.cfc(install guard atthis.browserbefore/afterbrowserDescribe()wiring; tighten$captureFailureArtifactsguard check)Picked the better error message path from the triage (option 2 in the report). Option 3 (auto-wire
this.browserfor plaindescribe()blocks) would have been a larger design decision and out of scope for the bug-fix path.A human review is required before merge. Reviewer A and Reviewer B will weigh in shortly. Doc updates (MDX guides,
.ai/wheels/,CLAUDE.md) are handled separately bybot-update-docs.yml.fix(test): BrowserTest reports unwired this.browser with browserDescr…
Release 4.0.2 (#2819)