fix(test): isolate the web runner in a separate application scope (#3374) - #3383
Merged
Merged
Conversation
) Bind test-runner, TestClient, and browser requests to <this.name>_wheelsTest so the live application.wheels is never swapped. Keep the #3373 named lock as a fallback for apps without the Application.cfc include. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Peter Amiri <peter@alurium.com>
Rename the $testClient local so Lucee no longer throws "client scope is not enabled" on every TestClient call. Resolve Application.cfc paths via the /config mapping instead of walking GetDirectoryFromPath on a directory. Map `internal` in tools/test-local.sh. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Peter Amiri <peter@alurium.com>
Isolated-app boot mounts browser-fixture controllers on
controllerPath. A later lookup of controller("wheels") then
falls through to that last-path Controller.cfc stub, which
has no mixins. Disable the fixture remount during the swap,
clear controller/file caches, and point interface specs at
Test.cfc.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Peter Amiri <peter@alurium.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The web test runner no longer mutates the live
application.wheelswhenApplication.cfcincludes the shipped snippet. Test-runner URLs, TestClient, and browser specs bind a separate CFML application name (_wheelsTest) so concurrent normal requests keep production config.This is the #3374 successor to #3025 / #3373. A request-scoped overlay remains infeasible (blockers B1–B9). Isolation is a second application context inside the same servlet — verified against those blockers rather than guessed.
Related Issue
Closes #3374
Type of Change
Approach (verified against B1–B9)
Changing
this.nameinApplication.cfc's constructor is the only CFML mechanism that yields a separateapplicationscope (own model/dialect caches, own routes, own datasource wiring). That sidesteps:automaticValidationsstay baked per isolated app; noStructClear(models)of the live cache/wheels/core/tests,/wheels/app/tests) orX-Wheels-Test-ContextorWHEELS_TEST_CONTEXTcookie. Header (not URL prefix) is required for Playwright: in-page navigations and form posts would drop a prefix/query marker;extraHTTPHeaderspersists across the context.$get()overlay / tenant datasource reuse was re-checked and rejected: the tenant override swaps only the datasource name after dialect SQL is generated, and cannot re-bake adapters (B1).What shipped
vendor/wheels/events/testcontext.cfm— constructor include (no CFCnewhere: mappings are not guaranteed duringApplication.cfcconstruction)vendor/wheels/events/TestContext.cfc— runtime twin (same suffix / header / cookie); unit-testablewheels new+ exampleApplication.cfcinclude the snippet afterconfig/app.cfmWheelsTest.$testClient()sends the header + cookie by default;$testClient(testContext=false)hits the live app. Local is namedhttpClient(notclient) so Lucee does not throw "client scope is not enabled" (anti-pattern 11)BrowserTestsets PlaywrightextraHTTPHeaders+ isolation cookieParallelRunnerpartition GETs send the header (path already matches)set(loadBrowserTestFixtures=false)and clears controller / object-file caches so isolated-app boot does not leavecontroller("wheels")resolving to the browser-fixtureController.cfcstubcontroller("Test")(a real test-asset CFC) instead of the no-filewheelsfallbackvendor/wheels/tests/specs/internal/TestRunnerIsolationSpec.cfc.ai/CLAUDE.mdupdatestools/test-local.sh internal/interfacesmap to the matchingwheels.tests.specs.*directoriesLeftovers (not papered over)
Application.cfcinclude to opt in. Without it, behavior is unchanged (fix(test): serialize web test-runner config swap under a named lock (#3025) #3373 lock + live-scope swap)._wheelsTest_sqlite) were deferred: browser requests have no?db=and would bind a different app than the runner.$wheelsRunner(wheels.Test) still swaps if invoked;wheels testuses HTTP/wheels/core|app/testsand is isolated.onApplicationStartof the second name).Feature Completeness Checklist
/wheels/infosees a different application name)fixtures-and-test-data.mdx,running-tests-locally.mdx.ai/wheels/testing/browser-testing.mdchangelog.d/test-runner-app-isolation.fixed.mdTest Plan
Local Lucee 7 + SQLite via
tools/test-local.sh:internal— 92 passed (isolation + swap-lock + TestClient)interfaces— 57 passedAlso verified over HTTP:
/wheels/info?format=jsonreturnswheels-dev; the same URL withX-Wheels-Test-Context: 1orWHEELS_TEST_CONTEXT=1returnswheels-dev_wheelsTest.