Added single-file discovery without a config or a runtime Mocha suite object.
Reflection.scanFile(filePath)returns{ suites, tests }for a file — everyFeature(...)andScenario(...)with its parent suite, byte range, and line. Reuses the same walkerProjectReflectionuses internally.Reflection.forSuite({ file })now auto-detects the suite title when the file has exactly oneFeature(...). ThrowsAmbiguousLocateErrorif multiple exist,NotFoundErrorif none.forSuitealso accepts a bare path string (Reflection.forSuite('./auth.js')) as a shorthand.
Added hook reflection to SuiteReflection for Before, After, BeforeSuite, and AfterSuite.
sur.hooks— list of{ kind, line, range }entries scoped to the current suite.sur.findHook(kind)— filter by kind.sur.addHook(kind, code, { position })— append after existing hooks (or right afterFeature(...)if none); scoped to the current suite.sur.removeHook(kind, { index })— delete a hook; throwsAmbiguousLocateErrorwhen multiple match and no index is given.sur.replaceHook(kind, code, { index })— replace a hook body with the same disambiguation semantics.
Added ProjectReflection — a project-level discovery layer that reads a CodeceptJS config and enumerates suites, tests, steps, and page objects without running anything.
Reflection.project(configPath | opts)/ProjectReflection.load(pathOrOpts).listTestFiles(),listSuites(),listTests(),listTestsBySuite(),listSteps(testRef),listPageObjects({ includeActor }).getSuite(title, file?)/getTest(title, file?)/getPageObject(name)— hand off to the specialized reflectors.- Static "dry-run" step listing via AST walk — no CodeceptJS boot required.
- Config loader supports
export const config = {...},export default {...},module.exports = {...}, and.json. - New runtime dep:
globfor test-file discovery.
Added PageObjectReflection for source-level introspection and editing of CodeceptJS Page Objects.
Reflection.forPageObject(filePath, { name })returns aPageObjectReflection.- Supports both class-based (
class LoginPage { ... } export default LoginPage) and plain-object (module.exports = { ... },export default { ... }) Page Objects, in JS and TS. .kind,.className,.dependencies,.members,.methods,.properties,.findMember(name)..read()returns the full container text;.readMember(name)returns an individual member..addMember(code),.replaceMember(name, code),.removeMember(name)— class fields and methods, plain-object properties and method shorthands. All return anEdit..addDependency(name)/.removeDependency(name)— maintain theconst { ... } = inject()destructuring at the top of the file.- Trailing commas and surrounding whitespace are managed automatically on add/remove.
Added programmatic suite editing and dependency introspection.
SuiteReflection.tests— list of Scenarios belonging to the suite, in source order.SuiteReflection.dependencies— aggregated destructured param names across all scenarios in the suite.SuiteReflection.addTest(code, { position })— insert a new Scenario at the end (or start) of the suite.SuiteReflection.removeTest(title)— delete a Scenario by title, scoped to this suite.TestReflection.dependencies— destructured param names of a single scenario's callback.Editnow supports zero-width inserts viamagic-string.appendLeftwhenstart === end, and plain deletion via empty-string replacement.
Initial release.
Reflection.forStep(step, { test, extraFrameworkPatterns })returns aStepReflection.Reflection.forTest(test)returns aTestReflection.Reflection.forSuite(suite)returns aSuiteReflection.Reflection.batch(filePath)returns aBatchfor composing multi-edit atomic writes.- AST-based source parsing via
acorn(JS/MJS/CJS) and optionaltypescriptpeer (TS/TSX). .read(),.readFunction(),.readTest(),.replace()for steps..read(),.readDataBlock(),.replace()for tests (withData(...).Scenario(...)handling)..read(),.replace()for suites. Gherkin.featurefiles throwUnsupportedSourceError.Editwith.preview(),.diff(),.apply({ ignoreStale }). Stale-file detection via sha1 snapshot.Batchwith overlap detection viamagic-string.- Atomic writes (tmp + rename, with Windows
EBUSYfallback). - CRLF/LF EOL normalization, UTF-8 BOM preservation.
.temp.mjs → .tssource path resolution via injected or lazystore.tsFileMapping.