@@ -11,6 +11,9 @@ public class End2EndCommand : Command
11
11
{
12
12
private static readonly string [ ] ValidBrowsers = [ "chromium" , "firefox" , "webkit" , "safari" , "all" ] ;
13
13
14
+ // Get available self-contained systems
15
+ private static readonly string [ ] AvailableSelfContainedSystems = SelfContainedSystemHelper . GetAvailableSelfContainedSystems ( ) ;
16
+
14
17
public End2EndCommand ( ) : base ( "e2e" , "Run end-to-end tests using Playwright" )
15
18
{
16
19
// Add argument for test file patterns
@@ -27,7 +30,7 @@ public class End2EndCommand : Command
27
30
AddOption ( new Option < bool > ( [ "--quiet" ] , ( ) => false , "Suppress all output including terminal output and automatic report opening" ) ) ;
28
31
AddOption ( new Option < int ? > ( [ "--repeat-each" ] , "Number of times to repeat each test" ) ) ;
29
32
AddOption ( new Option < int ? > ( [ "--retries" ] , "Maximum retry count for flaky tests, zero for no retries" ) ) ;
30
- AddOption ( new Option < string ? > ( [ "<self-contained-system>" , "--self-contained-system" , "-s" ] , "The name of the self-contained system to test (account-management, back-office , etc.)" ) ) ;
33
+ AddOption ( new Option < string ? > ( [ "<self-contained-system>" , "--self-contained-system" , "-s" ] , $ "The name of the self-contained system to test ({ string . Join ( ", " , AvailableSelfContainedSystems ) } , etc.)") ) ;
31
34
AddOption ( new Option < bool > ( [ "--show-report" ] , ( ) => false , "Always show HTML report after test run" ) ) ;
32
35
AddOption ( new Option < bool > ( [ "--slow-motion" ] , ( ) => false , "Run tests in slow motion (automatically enables headed mode)" ) ) ;
33
36
AddOption ( new Option < bool > ( [ "--smoke" ] , ( ) => false , "Run only smoke tests" ) ) ;
@@ -60,23 +63,27 @@ private static void Execute(
60
63
{
61
64
Prerequisite . Ensure ( Prerequisite . Node ) ;
62
65
63
- // Get available self-contained systems
64
- var availableSystems = GetAvailableSelfContainedSystems ( ) ;
65
-
66
- if ( availableSystems . Length == 0 )
66
+ // If debug or UI mode is enabled, we need a specific self-contained system
67
+ if ( ( debug || ui ) && selfContainedSystem is null )
67
68
{
68
- AnsiConsole . MarkupLine ( "[red]No self-contained systems with e2e tests found.[/]" ) ;
69
- Environment . Exit ( 1 ) ;
69
+ selfContainedSystem = SelfContainedSystemHelper . PromptForSelfContainedSystem ( AvailableSelfContainedSystems ) ;
70
70
}
71
71
72
72
// Determine which self-contained systems to test based on the provided patterns or grep
73
- var selfContainedSystemsToTest = DetermineSystemsToTest ( selfContainedSystem , availableSystems , testPatterns , grep ) ;
73
+ string [ ] selfContainedSystemsToTest ;
74
+ if ( selfContainedSystem is not null )
75
+ {
76
+ if ( ! AvailableSelfContainedSystems . Contains ( selfContainedSystem ) )
77
+ {
78
+ AnsiConsole . MarkupLine ( $ "[red]Invalid self-contained system '{ selfContainedSystem } '. Available systems: { string . Join ( ", " , AvailableSelfContainedSystems ) } [/]") ;
79
+ Environment . Exit ( 1 ) ;
80
+ }
74
81
75
- // Validate self-contained system if provided
76
- if ( selfContainedSystem is not null && ! availableSystems . Contains ( selfContainedSystem ) )
82
+ selfContainedSystemsToTest = [ selfContainedSystem ] ;
83
+ }
84
+ else
77
85
{
78
- AnsiConsole . MarkupLine ( $ "[red]Invalid self-contained system '{ selfContainedSystem } '. Available systems: { string . Join ( ", " , availableSystems ) } [/]") ;
79
- Environment . Exit ( 1 ) ;
86
+ selfContainedSystemsToTest = DetermineSystemsToTest ( testPatterns , grep , AvailableSelfContainedSystems ) ;
80
87
}
81
88
82
89
// Validate browser option
@@ -103,7 +110,7 @@ private static void Execute(
103
110
{
104
111
overallSuccess = false ;
105
112
failedSelfContainedSystems . Add ( currentSelfContainedSystem ) ;
106
-
113
+
107
114
// If stop on first failure is enabled, exit the loop after the first failure
108
115
if ( stopOnFirstFailure )
109
116
{
@@ -215,7 +222,8 @@ private static bool RunTestsForSystem(
215
222
ProcessHelper . StartProcess ( processStartInfo , throwOnError : true ) ;
216
223
AnsiConsole . MarkupLine ( testsFailed
217
224
? $ "[red]Tests for { selfContainedSystem } failed[/]"
218
- : $ "[green]Tests for { selfContainedSystem } completed successfully[/]") ;
225
+ : $ "[green]Tests for { selfContainedSystem } completed successfully[/]"
226
+ ) ;
219
227
}
220
228
catch ( Exception )
221
229
{
@@ -251,51 +259,27 @@ private static void CheckWebsiteAccessibility()
251
259
Environment . Exit ( 1 ) ;
252
260
}
253
261
254
- private static string [ ] DetermineSystemsToTest ( string ? specifiedSelfContainedSystem , string [ ] availableSystems , string [ ] testPatterns , string ? grep )
262
+ private static string [ ] DetermineSystemsToTest ( string [ ] testPatterns , string ? grep , string [ ] availableSystems )
255
263
{
256
- // If a specific self-contained system is provided, use only that one
257
- if ( specifiedSelfContainedSystem != null )
258
- {
259
- return [ specifiedSelfContainedSystem ] ;
260
- }
261
-
262
- // If no patterns or grep are provided, run tests for all systems
263
264
if ( ( testPatterns . Length == 0 || testPatterns [ 0 ] == "*" ) && string . IsNullOrEmpty ( grep ) )
264
265
{
265
266
return availableSystems ;
266
267
}
267
268
268
- // Check if test patterns match specific files in any self-contained system
269
269
var matchingSystems = new HashSet < string > ( ) ;
270
270
271
- foreach ( var pattern in testPatterns )
271
+ foreach ( var pattern in testPatterns . Where ( p => p != null && p != "*" ) )
272
272
{
273
- // Skip wildcard patterns as they don't help us narrow down the systems
274
- if ( pattern == "*" || ( pattern . Contains ( "*" ) && ! pattern . EndsWith ( ".spec.ts" ) ) )
275
- {
276
- continue ;
277
- }
278
-
279
- if ( pattern is null )
280
- {
281
- continue ;
282
- }
283
-
284
- // Normalize the pattern to handle both file names and paths
285
273
var normalizedPattern = pattern . EndsWith ( ".spec.ts" ) ? pattern : $ "{ pattern } .spec.ts";
286
274
normalizedPattern = Path . GetFileName ( normalizedPattern ) ;
287
275
288
276
foreach ( var system in availableSystems )
289
277
{
290
278
var e2eTestsPath = Path . Combine ( Configuration . ApplicationFolder , system , "WebApp" , "e2e-tests" ) ;
291
- if ( ! Directory . Exists ( e2eTestsPath ) )
292
- {
293
- continue ;
294
- }
279
+ if ( ! Directory . Exists ( e2eTestsPath ) ) continue ;
295
280
296
281
var testFiles = Directory . GetFiles ( e2eTestsPath , "*.spec.ts" , SearchOption . AllDirectories )
297
- . Select ( Path . GetFileName )
298
- . ToArray ( ) ;
282
+ . Select ( Path . GetFileName ) ;
299
283
300
284
if ( testFiles . Any ( file => file ? . Equals ( normalizedPattern , StringComparison . OrdinalIgnoreCase ) == true ) )
301
285
{
@@ -304,71 +288,32 @@ private static string[] DetermineSystemsToTest(string? specifiedSelfContainedSys
304
288
}
305
289
}
306
290
307
- // If we found matching systems based on file patterns, return those
308
- if ( matchingSystems . Count > 0 )
309
- {
310
- return matchingSystems . ToArray ( ) ;
311
- }
291
+ if ( matchingSystems . Count > 0 ) return matchingSystems . ToArray ( ) ;
312
292
313
- // If grep is provided, try to find matching test content
314
293
if ( ! string . IsNullOrEmpty ( grep ) )
315
294
{
316
295
foreach ( var system in availableSystems )
317
296
{
318
297
var e2eTestsPath = Path . Combine ( Configuration . ApplicationFolder , system , "WebApp" , "e2e-tests" ) ;
319
- if ( ! Directory . Exists ( e2eTestsPath ) )
320
- {
321
- continue ;
322
- }
298
+ if ( ! Directory . Exists ( e2eTestsPath ) ) continue ;
323
299
324
300
var testFiles = Directory . GetFiles ( e2eTestsPath , "*.spec.ts" , SearchOption . AllDirectories ) ;
325
301
foreach ( var testFile in testFiles )
326
302
{
327
- var fileContent = File . ReadAllText ( testFile ) ;
328
- if ( fileContent . Contains ( grep , StringComparison . OrdinalIgnoreCase ) )
303
+ if ( File . ReadAllText ( testFile ) . Contains ( grep , StringComparison . OrdinalIgnoreCase ) )
329
304
{
330
305
matchingSystems . Add ( system ) ;
331
- break ; // Found a match in this system, no need to check other files
306
+ break ;
332
307
}
333
308
}
334
309
}
335
310
336
- if ( matchingSystems . Count > 0 )
337
- {
338
- return matchingSystems . ToArray ( ) ;
339
- }
311
+ if ( matchingSystems . Count > 0 ) return matchingSystems . ToArray ( ) ;
340
312
}
341
313
342
- // If we couldn't determine specific systems, run tests for all systems
343
314
return availableSystems ;
344
315
}
345
316
346
- private static string [ ] GetAvailableSelfContainedSystems ( )
347
- {
348
- var selfContainedSystems = new List < string > ( ) ;
349
-
350
- // Look for directories that contain WebApp/e2e-tests
351
- foreach ( var directory in Directory . GetDirectories ( Configuration . ApplicationFolder ) )
352
- {
353
- var directoryName = Path . GetFileName ( directory ) ;
354
-
355
- // Skip directories that are not self-contained systems
356
- if ( directoryName . StartsWith ( '.' ) || directoryName == "AppGateway" || directoryName == "AppHost" ||
357
- directoryName == "shared-kernel" || directoryName == "shared-webapp" )
358
- {
359
- continue ;
360
- }
361
-
362
- var e2eTestsPath = Path . Combine ( directory , "WebApp" , "e2e-tests" ) ;
363
- if ( Directory . Exists ( e2eTestsPath ) )
364
- {
365
- selfContainedSystems . Add ( directoryName ) ;
366
- }
367
- }
368
-
369
- return selfContainedSystems . ToArray ( ) ;
370
- }
371
-
372
317
private static string BuildPlaywrightArgs (
373
318
string [ ] testPatterns ,
374
319
string browser ,
@@ -427,6 +372,26 @@ private static string BuildPlaywrightArgs(
427
372
return string . Join ( " " , args ) ;
428
373
}
429
374
375
+ private static string PromptForSelfContainedSystem ( string [ ] availableSystems )
376
+ {
377
+ if ( availableSystems . Length == 0 )
378
+ {
379
+ AnsiConsole . MarkupLine ( "[red]No self-contained systems found.[/]" ) ;
380
+ Environment . Exit ( 1 ) ;
381
+ return string . Empty ; // This line will never be reached but is needed to satisfy the compiler
382
+ }
383
+
384
+ var selectedSystem = AnsiConsole . Prompt (
385
+ new SelectionPrompt < string > ( )
386
+ . Title ( "Select a [green]self-contained system[/] to test:" )
387
+ . PageSize ( 10 )
388
+ . MoreChoicesText ( "[grey](Move up and down to reveal more systems)[/]" )
389
+ . AddChoices ( availableSystems )
390
+ ) ;
391
+
392
+ return selectedSystem ;
393
+ }
394
+
430
395
private static void OpenHtmlReport ( string selfContainedSystem )
431
396
{
432
397
var reportPath = Path . Combine ( Configuration . ApplicationFolder , selfContainedSystem , "WebApp" , "playwright-report" , "index.html" ) ;
0 commit comments