@@ -113,8 +113,10 @@ function deepCloneSuite (suite, filterTest, tags = []) {
113113 if ( filterTest ( entry ) ) {
114114 const copiedTest = entry . _clone ( )
115115 tags . forEach ( tag => {
116- if ( tag ) {
117- copiedTest [ tag ] = true
116+ const resolvedTag = typeof tag === 'function' ? tag ( entry ) : tag
117+
118+ if ( resolvedTag ) {
119+ copiedTest [ resolvedTag ] = true
118120 }
119121 } )
120122 copy . _addTest ( copiedTest )
@@ -764,6 +766,30 @@ addHook({
764766 return suiteUtilsPackage
765767} )
766768
769+ /**
770+ * We could repeat the logic of `applyRepeatEachIndex` here, but it'd be more risky
771+ * as playwright could change it at any time.
772+ *
773+ * `applyRepeatEachIndex` goes through all the tests in a suite and applies the "repeat" logic
774+ * for a single repeat index.
775+ *
776+ * This means that the clone logic is cumbersome:
777+ * - we grab the unique file suites that have new tests
778+ * - we store its project suite
779+ * - we clone each of these file suites for each repeat index
780+ * - we execute `applyRepeatEachIndex` for each of these cloned file suites
781+ * - we add the cloned file suites to the project suite
782+ */
783+ function applyRetriesToTests ( fileSuitesWithTestsToRetry , filterTest , tagsToApply ) {
784+ for ( const [ fileSuite , projectSuite ] of fileSuitesWithTestsToRetry . entries ( ) ) {
785+ for ( let repeatEachIndex = 1 ; repeatEachIndex <= earlyFlakeDetectionNumRetries ; repeatEachIndex ++ ) {
786+ const copyFileSuite = deepCloneSuite ( fileSuite , filterTest , tagsToApply )
787+ applyRepeatEachIndex ( projectSuite . _fullProject , copyFileSuite , repeatEachIndex + 1 )
788+ projectSuite . _addSuite ( copyFileSuite )
789+ }
790+ }
791+ }
792+
767793addHook ( {
768794 name : 'playwright' ,
769795 file : 'lib/runner/loadUtils.js' ,
@@ -819,31 +845,36 @@ addHook({
819845 }
820846
821847 if ( isImpactedTestsEnabled ) {
822- await Promise . all ( allTests . map ( async ( test ) => {
823- const { isModified } = await getChannelPromise ( isModifiedCh , {
848+ const impactedTests = allTests . filter ( test => {
849+ let isImpacted = false
850+ isModifiedCh . publish ( {
824851 filePath : test . _requireFile ,
825- modifiedFiles
852+ modifiedFiles,
853+ onDone : ( isModified ) => { isImpacted = isModified }
826854 } )
827- if ( isModified ) {
828- test . _ddIsModified = true
829- }
830- if ( isEarlyFlakeDetectionEnabled && test . expectedStatus !== 'skipped' ) {
831- const isNew = isKnownTestsEnabled && isNewTest ( test )
832- const fileSuite = getSuiteType ( test , 'file' )
833- const projectSuite = getSuiteType ( test , 'project' )
834- // If something change in the file, all tests in the file are impacted
835- const isModifiedTest = ( ) => isModified
836- for ( let repeatEachIndex = 1 ; repeatEachIndex <= earlyFlakeDetectionNumRetries ; repeatEachIndex ++ ) {
837- const copyFileSuite = deepCloneSuite ( fileSuite , isModifiedTest , [
838- isNew && '_ddIsNew' ,
839- '_ddIsModified' ,
840- '_ddIsEfdRetry'
841- ] )
842- applyRepeatEachIndex ( projectSuite . _fullProject , copyFileSuite , repeatEachIndex + 1 )
843- projectSuite . _addSuite ( copyFileSuite )
855+ return isImpacted
856+ } )
857+
858+ const fileSuitesWithImpactedTestsToProjects = new Map ( )
859+ impactedTests . forEach ( impactedTest => {
860+ impactedTest . _ddIsModified = true
861+ if ( isEarlyFlakeDetectionEnabled && impactedTest . expectedStatus !== 'skipped' ) {
862+ const fileSuite = getSuiteType ( impactedTest , 'file' )
863+ if ( ! fileSuitesWithImpactedTestsToProjects . has ( fileSuite ) ) {
864+ fileSuitesWithImpactedTestsToProjects . set ( fileSuite , getSuiteType ( impactedTest , 'project' ) )
844865 }
845866 }
846- } ) )
867+ } )
868+ // If something change in the file, all tests in the file are impacted, hence the () => true filter
869+ applyRetriesToTests (
870+ fileSuitesWithImpactedTestsToProjects ,
871+ ( ) => true ,
872+ [
873+ '_ddIsModified' ,
874+ '_ddIsEfdRetry' ,
875+ ( test ) => ( isKnownTestsEnabled && isNewTest ( test ) ? '_ddIsNew' : null )
876+ ]
877+ )
847878 }
848879
849880 if ( isKnownTestsEnabled ) {
@@ -860,21 +891,6 @@ addHook({
860891 isKnownTestsEnabled = false
861892 isEarlyFlakeDetectionFaulty = true
862893 } else {
863- /**
864- * We could repeat the logic of `applyRepeatEachIndex` here, but it'd be more risky
865- * as playwright could change it at any time.
866- *
867- * `applyRepeatEachIndex` goes through all the tests in a suite and applies the "repeat" logic
868- * for a single repeat index.
869- *
870- * This means that the clone logic is cumbersome:
871- * - we grab the unique file suites that have new tests
872- * - we store its project suite
873- * - we clone each of these file suites for each repeat index
874- * - we execute `applyRepeatEachIndex` for each of these cloned file suites
875- * - we add the cloned file suites to the project suite
876- */
877-
878894 const fileSuitesWithNewTestsToProjects = new Map ( )
879895 newTests . forEach ( newTest => {
880896 newTest . _ddIsNew = true
@@ -886,16 +902,7 @@ addHook({
886902 }
887903 } )
888904
889- for ( const [ fileSuite , projectSuite ] of fileSuitesWithNewTestsToProjects . entries ( ) ) {
890- for ( let repeatEachIndex = 1 ; repeatEachIndex <= earlyFlakeDetectionNumRetries ; repeatEachIndex ++ ) {
891- const copyFileSuite = deepCloneSuite ( fileSuite , isNewTest , [
892- '_ddIsNew' ,
893- '_ddIsEfdRetry'
894- ] )
895- applyRepeatEachIndex ( projectSuite . _fullProject , copyFileSuite , repeatEachIndex + 1 )
896- projectSuite . _addSuite ( copyFileSuite )
897- }
898- }
905+ applyRetriesToTests ( fileSuitesWithNewTestsToProjects , isNewTest , [ '_ddIsNew' , '_ddIsEfdRetry' ] )
899906 }
900907 }
901908
0 commit comments