@@ -60,7 +60,7 @@ public AspNetProcess(
60
60
Process = ProcessEx . Run ( output , workingDirectory , DotNetMuxer . MuxerPathOrDefault ( ) , arguments , envVars : environmentVariables ) ;
61
61
if ( hasListeningUri )
62
62
{
63
- ListeningUri = GetListeningUri ( output ) ;
63
+ ListeningUri = GetListeningUri ( output ) ?? throw new InvalidOperationException ( "Couldn't find the listening URL." ) ;
64
64
}
65
65
}
66
66
@@ -175,16 +175,15 @@ private Uri GetListeningUri(ITestOutputHelper output)
175
175
{
176
176
// Wait until the app is accepting HTTP requests
177
177
output . WriteLine ( "Waiting until ASP.NET application is accepting connections..." ) ;
178
- var listeningMessage = Process
179
- . OutputLinesAsEnumerable
180
- . Where ( line => line != null )
181
- . FirstOrDefault ( line => line . Trim ( ) . StartsWith ( ListeningMessagePrefix , StringComparison . Ordinal ) ) ;
178
+ var listeningMessage = GetListeningMessage ( ) ;
182
179
183
180
if ( ! string . IsNullOrEmpty ( listeningMessage ) )
184
181
{
185
182
listeningMessage = listeningMessage . Trim ( ) ;
186
183
// Verify we have a valid URL to make requests to
187
- var listeningUrlString = listeningMessage . Substring ( ListeningMessagePrefix . Length ) ;
184
+ var listeningUrlString = listeningMessage . Substring ( listeningMessage . IndexOf (
185
+ ListeningMessagePrefix , StringComparison . Ordinal ) + ListeningMessagePrefix . Length ) ;
186
+
188
187
output . WriteLine ( $ "Detected that ASP.NET application is accepting connections on: { listeningUrlString } ") ;
189
188
listeningUrlString = listeningUrlString . Substring ( 0 , listeningUrlString . IndexOf ( ':' ) ) +
190
189
"://localhost" +
@@ -199,6 +198,25 @@ private Uri GetListeningUri(ITestOutputHelper output)
199
198
}
200
199
}
201
200
201
+ private string GetListeningMessage ( )
202
+ {
203
+ try
204
+ {
205
+ return Process
206
+ // This will timeout at most after 5 minutes.
207
+ . OutputLinesAsEnumerable
208
+ . Where ( line => line != null )
209
+ // This used to do StartsWith, but this is less strict and can prevent issues (very rare) where
210
+ // console logging interleaves with other console output in a bad way. For example:
211
+ // dbugNow listening on: http://127.0.0.1:12857
212
+ . FirstOrDefault ( line => line . Trim ( ) . Contains ( ListeningMessagePrefix , StringComparison . Ordinal ) ) ;
213
+ }
214
+ catch ( OperationCanceledException )
215
+ {
216
+ return null ;
217
+ }
218
+ }
219
+
202
220
private bool IsSuccessStatusCode ( HttpResponseMessage response )
203
221
{
204
222
return response . IsSuccessStatusCode || response . StatusCode == HttpStatusCode . Redirect ;
0 commit comments