@@ -10,15 +10,20 @@ import { createRequire } from 'module'
1010const __filename = fileURLToPath ( import . meta. url )
1111const __dirname = dirname ( __filename )
1212
13+ import escapeRe from 'escape-string-regexp'
1314import Helper from '@codeceptjs/helper'
14- import Runner from './runner .js'
15+ import MochaFactory from './mocha/factory .js'
1516import container from './container.js'
1617import Config from './config.js'
18+ import event from './event.js'
19+ import recorder from './recorder.js'
20+ import output from './output.js'
1721import runHook from './hooks.js'
1822import ActorFactory from './actor.js'
1923import { emptyFolder } from './utils.js'
2024import { initCodeceptGlobals } from './globals.js'
2125import store from './store.js'
26+ import { validateTypeScriptSetup , getTSNodeESMWarning } from './utils/loaderCheck.js'
2227
2328import storeListener from './listener/store.js'
2429import stepsListener from './listener/steps.js'
@@ -100,7 +105,6 @@ class Codecept {
100105 await this . requireModules ( this . requiringModules )
101106 // initializing listeners
102107 await container . create ( this . config , this . opts )
103- this . runner = new Runner ( this )
104108 await this . runHooks ( )
105109 }
106110
@@ -263,7 +267,26 @@ class Codecept {
263267 * @returns {Array<{title: string, file: string, tags: string[], tests: Array<{title: string, uid: string, tags: string[], fullTitle: string}>}> }
264268 */
265269 getSuites ( pattern ) {
266- return this . runner . getSuites ( pattern )
270+ if ( this . testFiles . length === 0 ) this . loadTests ( pattern )
271+
272+ const tempMocha = MochaFactory . create ( this . config . mocha || { } , this . opts || { } )
273+ tempMocha . files = this . testFiles
274+ tempMocha . loadFiles ( )
275+
276+ const suites = [ ]
277+ for ( const suite of tempMocha . suite . suites ) {
278+ suites . push ( {
279+ ...suite . simplify ( ) ,
280+ file : suite . file || '' ,
281+ tests : suite . tests . map ( test => ( {
282+ ...test . simplify ( ) ,
283+ fullTitle : test . fullTitle ( ) ,
284+ } ) ) ,
285+ } )
286+ }
287+
288+ tempMocha . unloadFiles ( )
289+ return suites
267290 }
268291
269292 /**
@@ -274,7 +297,7 @@ class Codecept {
274297 * @returns {Promise<void> }
275298 */
276299 async runSuite ( suite ) {
277- return this . runner . runSuite ( suite )
300+ return this . run ( suite . file )
278301 }
279302
280303 /**
@@ -285,7 +308,7 @@ class Codecept {
285308 * @returns {Promise<void> }
286309 */
287310 async runTest ( test ) {
288- return this . runner . runTest ( test )
311+ return this . _execute ( { grep : `^ ${ escapeRe ( test . fullTitle ) } $` } )
289312 }
290313
291314 /**
@@ -295,7 +318,69 @@ class Codecept {
295318 * @returns {Promise<void> }
296319 */
297320 async run ( test ) {
298- return this . runner . run ( test )
321+ let files = this . testFiles
322+
323+ if ( test ) {
324+ if ( ! fsPath . isAbsolute ( test ) ) {
325+ test = fsPath . join ( store . codeceptDir , test )
326+ }
327+ const testBasename = fsPath . basename ( test , '.js' )
328+ const testFeatureBasename = fsPath . basename ( test , '.feature' )
329+ files = files . filter ( t => {
330+ return fsPath . basename ( t , '.js' ) === testBasename || fsPath . basename ( t , '.feature' ) === testFeatureBasename || t === test
331+ } )
332+ }
333+
334+ return this . _execute ( { files } )
335+ }
336+
337+ async _execute ( { files, grep } = { } ) {
338+ await container . started ( )
339+
340+ const tsValidation = validateTypeScriptSetup ( this . testFiles , this . requiringModules || [ ] )
341+ if ( tsValidation . hasError ) {
342+ output . error ( tsValidation . message )
343+ process . exit ( 1 )
344+ }
345+
346+ const tsWarning = getTSNodeESMWarning ( this . requiringModules || [ ] )
347+ if ( tsWarning ) {
348+ output . print ( output . colors . yellow ( tsWarning ) )
349+ }
350+
351+ try {
352+ const { loadTranslations } = await import ( './mocha/gherkin.js' )
353+ await loadTranslations ( )
354+ } catch ( e ) {
355+ // Ignore if gherkin module not available
356+ }
357+
358+ return new Promise ( ( resolve , reject ) => {
359+ const mocha = container . mocha ( )
360+ mocha . files = files || this . testFiles
361+
362+ if ( grep ) {
363+ mocha . grep ( grep )
364+ }
365+
366+ const done = async ( failures ) => {
367+ event . emit ( event . all . result , container . result ( ) )
368+ event . emit ( event . all . after , this )
369+ await recorder . promise ( )
370+ if ( failures ) {
371+ process . exitCode = 1
372+ }
373+ resolve ( )
374+ }
375+
376+ try {
377+ event . emit ( event . all . before , this )
378+ mocha . run ( async ( failures ) => await done ( failures ) )
379+ } catch ( e ) {
380+ output . error ( e . stack )
381+ reject ( e )
382+ }
383+ } )
299384 }
300385
301386 /**
0 commit comments