@@ -60,6 +60,8 @@ public void Complete()
6060 }
6161 }
6262 this . RegisterFile ( path ) ;
63+
64+ this . PersistTestOutputOnSuccessfulTest ( ) ;
6365 }
6466
6567#if NETCOREAPP
@@ -133,12 +135,47 @@ private void AddLastEventLogEntries(EventLogEntryType eventLogEntryType, int cou
133135{ x . Message } ") ) ;
134136 }
135137
138+ // The test run directory is cleaned up, if all tests in the current run have passed.
139+ // Therefore we copy the test output to a dedicated directory, if specified.
140+ // Ultimately, this is done once after the whole test run is completed, to determine, if all tests have actually passed.
141+ // Unfortunately, there is no way for us at this level to execute code with a test context, after the whole test run has completed.
142+ // So this is executed after each test, that has passed, without knowing, if there is another failed test in the run,
143+ // preventing the original test results folder from getting cleaned up.
144+ private void PersistTestOutputOnSuccessfulTest ( )
145+ {
146+ if ( this . _testContext . CurrentTestOutcome != UnitTestOutcome . Passed )
147+ return ;
148+
149+ string privateTestResultsDirectory = ( string ) this . _testContext . Properties [ "PrivateTestResultsDirectory" ] ;
150+ if ( privateTestResultsDirectory == null )
151+ return ;
152+
153+ CopyDirectoryContents ( this . _runDirectory , privateTestResultsDirectory ) ;
154+ }
155+
136156 private static void WriteContentToFile ( string path , string content )
137157 {
138158 if ( File . Exists ( path ) )
139159 throw new InvalidOperationException ( $ "Path exists already: { path } ") ;
140160
141161 File . WriteAllText ( path , content ) ;
142162 }
163+
164+ private static void CopyDirectoryContents ( string sourceDirectory , string targetDirectory )
165+ {
166+ foreach ( string directory in Directory . EnumerateDirectories ( sourceDirectory , "*" , SearchOption . AllDirectories ) )
167+ {
168+ string relativeDirectoryPath = directory . Substring ( sourceDirectory . Length + 1 ) ;
169+ string targetDirectoryPath = Path . Combine ( targetDirectory , relativeDirectoryPath ) ;
170+ Directory . CreateDirectory ( targetDirectoryPath ) ;
171+ }
172+
173+ foreach ( string file in Directory . EnumerateFiles ( sourceDirectory , "*" , SearchOption . AllDirectories ) )
174+ {
175+ string relativeFilePath = file . Substring ( sourceDirectory . Length + 1 ) ;
176+ string targetFilePath = Path . Combine ( targetDirectory , relativeFilePath ) ;
177+ File . Copy ( file , targetFilePath ) ;
178+ }
179+ }
143180 }
144181}
0 commit comments