浏览代码

Rewrite integration tests to actually run scenarios

- Tests now use UICatalogTop and call scenario.Main()
- First test simulates full UICatalog flow: run UICatalogTop, select scenario, run scenario
- Second test runs multiple scenarios in sequence to verify driver persistence
- Both tests properly clean up event handlers to avoid assertions
- Tests verify the fix works correctly by actually running scenarios

Co-authored-by: tig <[email protected]>
copilot-swe-agent[bot] 4 周之前
父节点
当前提交
f1a6534dca
共有 1 个文件被更改,包括 211 次插入42 次删除
  1. 211 42
      Tests/IntegrationTests/UICatalog/ForceDriverTests.cs

+ 211 - 42
Tests/IntegrationTests/UICatalog/ForceDriverTests.cs

@@ -16,11 +16,11 @@ public class ForceDriverTests
     }
 
     /// <summary>
-    ///     Tests that ForceDriver persists when opening a scenario after Init/Shutdown cycles.
-    ///     This verifies the fix for issue #4391.
+    ///     Tests that ForceDriver persists when running UICatalogTop and then opening a scenario.
+    ///     This simulates the actual UICatalog flow and verifies the fix for issue #4391.
     /// </summary>
     [Fact]
-    public void ForceDriver_Persists_Across_Init_Shutdown_Cycles ()
+    public void ForceDriver_Persists_From_UICatalogTop_To_Scenario ()
     {
         // Arrange
         const string expectedDriver = "fake";
@@ -28,6 +28,21 @@ public class ForceDriverTests
         ConfigurationManager.Disable (true);
         Application.ResetState (true);
 
+        // Initialize UICatalog.Options (required by UICatalogTop)
+        global::UICatalog.UICatalog.Options = new UICatalogCommandLineOptions
+        {
+            Driver = expectedDriver,
+            DontEnableConfigurationManagement = false,
+            Scenario = "none",
+            BenchmarkTimeout = 2500,
+            Benchmark = false,
+            ResultsFile = string.Empty,
+            DebugLogLevel = "Warning"
+        };
+
+        // Initialize cached scenarios (required by UICatalogTop)
+        UICatalogTop.CachedScenarios = Scenario.GetScenarios ();
+
         // Set ForceDriver in RuntimeConfig (simulating what UICatalog does with --driver option)
         ConfigurationManager.RuntimeConfig = $$"""
             {
@@ -38,54 +53,136 @@ public class ForceDriverTests
         // Enable ConfigurationManager with all locations (as UICatalog does)
         ConfigurationManager.Enable (ConfigLocations.All);
 
-        var firstDriverName = string.Empty;
-        var secondDriverName = string.Empty;
+        var topLevelDriverName = string.Empty;
+        var scenarioDriverName = string.Empty;
+        var iterationCount = 0;
+        EventHandler<IterationEventArgs>? iterationHandler = null;
 
         try
         {
-            // Act - Cycle 1: Init and check driver
-            _output.WriteLine ("Cycle 1: First Init");
+            // Phase 1: Run UICatalogTop (simulating main UI)
+            _output.WriteLine ("=== Phase 1: Running UICatalogTop ===");
             Application.Init ();
-            firstDriverName = Application.Driver?.GetName () ?? string.Empty;
-            _output.WriteLine ($"Cycle 1 driver: {firstDriverName}");
-            Application.Shutdown ();
+            topLevelDriverName = Application.Driver?.GetName () ?? string.Empty;
+            _output.WriteLine ($"UICatalogTop driver: {topLevelDriverName}");
 
-            // Act - Cycle 2: Reload RuntimeConfig and Init again (simulating scenario opening)
-            _output.WriteLine ("Cycle 2: Reload RuntimeConfig and Init again");
+            var top = new UICatalogTop ();
             
-            // This simulates what the fix does before each scenario
-            ConfigurationManager.Load (ConfigLocations.Runtime);
-            ConfigurationManager.Apply ();
+            // Set up to automatically select a scenario and stop
+            iterationHandler = (sender, e) =>
+            {
+                iterationCount++;
+                
+                // On first iteration, select a scenario and request stop
+                if (iterationCount == 1)
+                {
+                    // Select the first scenario
+                    if (UICatalogTop.CachedScenarios is { Count: > 0 })
+                    {
+                        UICatalogTop.CachedSelectedScenario = 
+                            (Scenario)Activator.CreateInstance (UICatalogTop.CachedScenarios[0].GetType ())!;
+                        Application.RequestStop ();
+                    }
+                }
+            };
+            
+            Application.Iteration += iterationHandler;
+            Application.Run (top);
+            Application.Iteration -= iterationHandler;
 
-            // Scenario calls Application.Init() without parameters
-            Application.Init ();
-            secondDriverName = Application.Driver?.GetName () ?? string.Empty;
-            _output.WriteLine ($"Cycle 2 driver: {secondDriverName}");
+            top.Dispose ();
             Application.Shutdown ();
+            
+            _output.WriteLine ($"Selected scenario: {UICatalogTop.CachedSelectedScenario?.GetName ()}");
+            _output.WriteLine ($"UICatalogTop completed after {iterationCount} iterations");
+
+            // Phase 2: Run the selected scenario (simulating what UICatalog.cs does)
+            if (UICatalogTop.CachedSelectedScenario is { } scenario)
+            {
+                _output.WriteLine ($"\n=== Phase 2: Running scenario '{scenario.GetName ()}' ===");
+                
+                // Reload RuntimeConfig before scenario (as the fix does)
+                if (!global::UICatalog.UICatalog.Options.DontEnableConfigurationManagement)
+                {
+                    ConfigurationManager.Load (ConfigLocations.Runtime);
+                    ConfigurationManager.Apply ();
+                    _output.WriteLine ("Reloaded RuntimeConfig");
+                }
+
+                // Track the driver used inside the scenario
+                string? driverInsideScenario = null;
+                EventHandler<EventArgs<bool>>? initHandler = null;
+                EventHandler<IterationEventArgs>? scenarioIterationHandler = null;
+                
+                initHandler = (s, e) =>
+                {
+                    if (e.Value)
+                    {
+                        driverInsideScenario = Application.Driver?.GetName ();
+                        
+                        // Request stop immediately so the scenario doesn't actually run
+                        scenarioIterationHandler = (_, _) =>
+                        {
+                            Application.RequestStop ();
+                            // Remove immediately to avoid assertions in Shutdown
+                            if (scenarioIterationHandler != null)
+                            {
+                                Application.Iteration -= scenarioIterationHandler;
+                                scenarioIterationHandler = null;
+                            }
+                        };
+                        Application.Iteration += scenarioIterationHandler;
+                    }
+                };
+                
+                Application.InitializedChanged += initHandler;
+
+                // Run the scenario's Main() method (this is what UICatalog does)
+                scenario.Main ();
+                scenarioDriverName = driverInsideScenario ?? string.Empty;
+                
+                Application.InitializedChanged -= initHandler;
+                scenario.Dispose ();
+                
+                _output.WriteLine ($"Scenario driver: {scenarioDriverName}");
+                _output.WriteLine ("Scenario completed and disposed");
+            }
+            else
+            {
+                _output.WriteLine ("ERROR: No scenario was selected");
+                Assert.Fail ("No scenario was selected");
+            }
 
             // Assert
-            Assert.Equal (expectedDriver, firstDriverName);
-            Assert.Equal (expectedDriver, secondDriverName);
-            _output.WriteLine ($"SUCCESS: Driver '{expectedDriver}' persisted across Init/Shutdown cycles");
+            _output.WriteLine ($"\n=== Results ===");
+            _output.WriteLine ($"UICatalogTop driver: {topLevelDriverName}");
+            _output.WriteLine ($"Scenario driver: {scenarioDriverName}");
+            
+            Assert.Equal (expectedDriver, topLevelDriverName);
+            Assert.Equal (expectedDriver, scenarioDriverName);
+            _output.WriteLine ($"SUCCESS: Driver '{expectedDriver}' persisted from UICatalogTop to scenario");
         }
         finally
         {
+            if (iterationHandler != null)
+            {
+                Application.Iteration -= iterationHandler;
+            }
             ConfigurationManager.Disable (true);
             Application.ResetState (true);
         }
     }
 
     /// <summary>
-    ///     Tests that ForceDriver is used when a scenario calls Application.Init() without parameters.
-    ///     This simulates the actual UICatalog scenario execution flow.
+    ///     Tests that ForceDriver persists when running multiple scenarios in sequence.
+    ///     This verifies the scenario loop in UICatalog works correctly.
     /// </summary>
     [Fact]
-    public void ForceDriver_Used_By_Scenario_Init ()
+    public void ForceDriver_Persists_Across_Multiple_Scenarios ()
     {
         // Arrange
         const string expectedDriver = "fake";
-        Scenario? scenario = null;
-
+        
         ConfigurationManager.Disable (true);
         Application.ResetState (true);
 
@@ -99,34 +196,106 @@ public class ForceDriverTests
         // Enable ConfigurationManager
         ConfigurationManager.Enable (ConfigLocations.All);
 
+        string? driver1 = null;
+        string? driver2 = null;
+        EventHandler<EventArgs<bool>>? initHandler1 = null;
+        EventHandler<EventArgs<bool>>? initHandler2 = null;
+        EventHandler<IterationEventArgs>? iterHandler1 = null;
+        EventHandler<IterationEventArgs>? iterHandler2 = null;
+
         try
         {
-            // Get the first available scenario
+            // Get two different scenarios to test
             var scenarios = Scenario.GetScenarios ();
-            Assert.NotEmpty (scenarios);
+            Assert.True (scenarios.Count >= 2, "Need at least 2 scenarios for this test");
+            
+            var scenario1 = scenarios[0];
+            var scenario2 = scenarios[1];
+            
+            _output.WriteLine ($"Testing with scenarios: {scenario1.GetName ()} and {scenario2.GetName ()}");
+
+            // Run scenario 1
+            initHandler1 = (s, e) =>
+            {
+                if (e.Value)
+                {
+                    driver1 = Application.Driver?.GetName ();
+                    iterHandler1 = (_, _) =>
+                    {
+                        Application.RequestStop ();
+                        // Remove immediately to avoid assertions in Shutdown
+                        if (iterHandler1 != null)
+                        {
+                            Application.Iteration -= iterHandler1;
+                            iterHandler1 = null;
+                        }
+                    };
+                    Application.Iteration += iterHandler1;
+                }
+            };
             
-            scenario = scenarios[0];
-            var scenarioName = scenario.GetName ();
-            _output.WriteLine ($"Testing with scenario: {scenarioName}");
+            Application.InitializedChanged += initHandler1;
+            scenario1.Main ();
+            Application.InitializedChanged -= initHandler1;
+            scenario1.Dispose ();
+            _output.WriteLine ($"Scenario 1 completed with driver: {driver1}");
 
-            // Reload RuntimeConfig before scenario (as the fix does)
+            // Reload RuntimeConfig before scenario 2 (as the fix does)
             ConfigurationManager.Load (ConfigLocations.Runtime);
             ConfigurationManager.Apply ();
+            _output.WriteLine ("Reloaded RuntimeConfig");
 
-            // Scenario calls Application.Init() - it should use ForceDriver
-            Application.Init ();
-            var driverName = Application.Driver?.GetName () ?? string.Empty;
-            _output.WriteLine ($"Scenario driver: {driverName}");
+            // Run scenario 2
+            initHandler2 = (s, e) =>
+            {
+                if (e.Value)
+                {
+                    driver2 = Application.Driver?.GetName ();
+                    iterHandler2 = (_, _) =>
+                    {
+                        Application.RequestStop ();
+                        // Remove immediately to avoid assertions in Shutdown
+                        if (iterHandler2 != null)
+                        {
+                            Application.Iteration -= iterHandler2;
+                            iterHandler2 = null;
+                        }
+                    };
+                    Application.Iteration += iterHandler2;
+                }
+            };
+            
+            Application.InitializedChanged += initHandler2;
+            scenario2.Main ();
+            Application.InitializedChanged -= initHandler2;
+            scenario2.Dispose ();
+            _output.WriteLine ($"Scenario 2 completed with driver: {driver2}");
 
             // Assert
-            Assert.Equal (expectedDriver, driverName);
-            _output.WriteLine ($"SUCCESS: Scenario uses ForceDriver '{expectedDriver}'");
-
-            Application.Shutdown ();
+            Assert.Equal (expectedDriver, driver1);
+            Assert.Equal (expectedDriver, driver2);
+            _output.WriteLine ($"SUCCESS: Driver '{expectedDriver}' persisted across both scenarios");
         }
         finally
         {
-            scenario?.Dispose ();
+            // Cleanup any remaining handlers
+            if (initHandler1 != null)
+            {
+                Application.InitializedChanged -= initHandler1;
+            }
+            if (iterHandler2 != null)
+            {
+                Application.InitializedChanged -= initHandler2;
+            }
+            if (iterHandler1 != null)
+            {
+                Application.Iteration -= iterHandler1;
+            }
+            if (iterHandler2 != null)
+            {
+                Application.Iteration -= iterHandler2;
+            }
+            
             ConfigurationManager.Disable (true);
             Application.ResetState (true);
         }