@@ -63,12 +63,21 @@ class Container {
6363 // create support objects
6464 container . support = { }
6565 container . helpers = await createHelpers ( config . helpers || { } )
66- container . translation = loadTranslation ( config . translation || null , config . vocabularies || [ ] )
66+ container . translation = await loadTranslation ( config . translation || null , config . vocabularies || [ ] )
6767 container . proxySupport = await createSupportObjects ( config . include || { } )
6868 container . plugins = await createPlugins ( config . plugins || { } , opts )
6969 container . result = new Result ( )
7070
71- await createActor ( config . include ?. I )
71+ // Create actor - pass custom I object only if no I is provided in includes
72+ // If I is provided in includes, it should remain as a pure support object
73+ const customIProvided = config . include && config . include . I
74+ const actorConfig = customIProvided ? { } : config . include ?. I
75+ container . actor = await createActor ( actorConfig )
76+
77+ // Only set I to actor if no custom I was loaded as a support object
78+ if ( ! customIProvided ) {
79+ container . support . I = container . actor
80+ }
7281
7382 if ( opts && opts . ai ) ai . enable ( config . ai ) // enable AI Assistant
7483 if ( config . gherkin ) await loadGherkinSteps ( config . gherkin . steps || [ ] )
@@ -173,8 +182,9 @@ class Container {
173182 */
174183 static clear ( newHelpers = { } , newSupport = { } , newPlugins = { } ) {
175184 container . helpers = newHelpers
176- container . translation = loadTranslation ( )
177- container . proxySupport = createSupportObjects ( newSupport )
185+ container . translation = Translation . createEmpty ( ) // Use empty translation to avoid async issues
186+ // Handle simple objects synchronously for backward compatibility
187+ container . proxySupport = createSupportObjectsSync ( newSupport )
178188 container . plugins = newPlugins
179189 container . sharedKeys = new Set ( ) // Clear shared keys
180190 asyncHelperPromise = Promise . resolve ( )
@@ -306,9 +316,20 @@ async function requireHelperFromModule(helperName, config, HelperClass) {
306316 HelperClass = mod . default || mod
307317 } catch ( err ) {
308318 if ( err . code === 'ERR_MODULE_NOT_FOUND' ) {
309- throw new Error ( `Helper module '${ moduleName } ' was not found. Make sure you have installed the package correctly.` )
319+ // Try adding .js extension for custom helpers (ESM compatibility)
320+ if ( ! moduleName . endsWith ( '.js' ) && ! moduleName . endsWith ( '.mjs' ) && ! moduleName . endsWith ( '.ts' ) ) {
321+ try {
322+ const mod = await import ( moduleName + '.js' ) ;
323+ HelperClass = mod . default || mod
324+ } catch ( retryErr ) {
325+ throw new Error ( `Helper module '${ moduleName } ' was not found. Make sure you have installed the package correctly.` )
326+ }
327+ } else {
328+ throw new Error ( `Helper module '${ moduleName } ' was not found. Make sure you have installed the package correctly.` )
329+ }
330+ } else {
331+ throw err
310332 }
311- throw err
312333 }
313334 }
314335 return HelperClass
@@ -328,8 +349,8 @@ async function createSupportObjects(config) {
328349 const supportObjects = { } ;
329350 for ( const name in config ) {
330351 if ( name === 'I' ) {
331- // Handle I (actor) separately
332- supportObjects [ name ] = await createActor ( config . I ) ;
352+ // Load I as a support object, not as an actor
353+ supportObjects [ name ] = await loadSupportObject ( config . I ) ;
333354 continue ;
334355 }
335356
@@ -482,7 +503,7 @@ async function loadSupportObject(modulePath, supportObjectName) {
482503 * Method collect own property and prototype
483504 */
484505
485- function loadTranslation ( locale , vocabularies ) {
506+ async function loadTranslation ( locale , vocabularies ) {
486507 if ( ! locale ) {
487508 return Translation . createEmpty ( )
488509 }
@@ -495,12 +516,15 @@ function loadTranslation(locale, vocabularies) {
495516 } else if ( fileExists ( path . join ( global . codecept_dir , locale ) ) ) {
496517 // get from a provided file instead
497518 translation = Translation . createDefault ( )
498- translation . loadVocabulary ( locale )
519+ await translation . loadVocabulary ( locale )
499520 } else {
500521 translation = Translation . createDefault ( )
501522 }
502523
503- vocabularies . forEach ( v => translation . loadVocabulary ( v ) )
524+ // Load vocabularies asynchronously
525+ for ( const v of vocabularies ) {
526+ await translation . loadVocabulary ( v )
527+ }
504528
505529 return translation
506530}
@@ -535,3 +559,18 @@ function normalizeAndJoin(basePath, subPath) {
535559 // Join the paths using POSIX-style
536560 return path . posix . join ( normalizedBase , normalizedSub )
537561}
562+
563+ function createSupportObjectsSync ( config ) {
564+ // Synchronous version for simple objects (used by clear method)
565+ const supportObjects = { } ;
566+ for ( const name in config ) {
567+ if ( typeof config [ name ] === 'object' ) {
568+ supportObjects [ name ] = config [ name ] ;
569+ }
570+ }
571+ // Store objects in container for access
572+ for ( const name in supportObjects ) {
573+ container . support [ name ] = supportObjects [ name ] ;
574+ }
575+ return supportObjects ;
576+ }
0 commit comments