@@ -398,6 +398,57 @@ function isFailedTestReplayEnabled () {
398398 return config . isTestDynamicInstrumentationEnabled && config . isDiEnabled
399399}
400400
401+ /**
402+ * @typedef {object } MochaSuite
403+ * @property {MochaSuite[] } suites
404+ * @property {import('mocha').Test[] } tests
405+ * @property {MochaSuite[] } _onlySuites
406+ * @property {import('mocha').Test[] } _onlyTests
407+ */
408+
409+ /**
410+ * Mirrors Mocha 5's private exclusivity check.
411+ *
412+ * @param {MochaSuite } suite
413+ * @returns {boolean }
414+ */
415+ function hasOnly ( suite ) {
416+ if ( suite . _onlyTests . length || suite . _onlySuites . length ) return true
417+
418+ for ( const childSuite of suite . suites ) {
419+ if ( hasOnly ( childSuite ) ) return true
420+ }
421+ return false
422+ }
423+
424+ /**
425+ * Mirrors Mocha 5's private exclusivity filter.
426+ *
427+ * @param {MochaSuite } suite
428+ * @returns {boolean }
429+ */
430+ function filterOnly ( suite ) {
431+ if ( suite . _onlyTests . length ) {
432+ suite . tests = suite . _onlyTests
433+ suite . suites = [ ]
434+ } else {
435+ suite . tests = [ ]
436+
437+ for ( const onlySuite of suite . _onlySuites ) {
438+ if ( hasOnly ( onlySuite ) ) filterOnly ( onlySuite )
439+ }
440+
441+ const filteredSuites = [ ]
442+ for ( const childSuite of suite . suites ) {
443+ if ( suite . _onlySuites . includes ( childSuite ) || filterOnly ( childSuite ) ) {
444+ filteredSuites . push ( childSuite )
445+ }
446+ }
447+ suite . suites = filteredSuites
448+ }
449+ return suite . tests . length > 0 || suite . suites . length > 0
450+ }
451+
401452function getExecutionConfiguration ( runner , isParallel , frameworkVersion , onFinishRequest , localSuites ) {
402453 const ctx = {
403454 isParallel,
@@ -431,8 +482,10 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
431482
432483 // We remove the suites that we skip through ITR
433484 // Mocha normally applies exclusivity after this asynchronous configuration step.
434- if ( runner . suite . hasOnly ( ) ) {
435- runner . suite . filterOnly ( )
485+ if ( typeof runner . suite . hasOnly === 'function' ) {
486+ if ( runner . suite . hasOnly ( ) ) runner . suite . filterOnly ( )
487+ } else if ( hasOnly ( runner . suite ) ) {
488+ filterOnly ( runner . suite )
436489 }
437490 const numTestsToRun = runner . grepTotal ( runner . suite )
438491 const filteredSuites = getFilteredSuites ( runner . suite . suites )
0 commit comments