Skip to content

Commit f1a6534

Browse files
Copilottig
andcommitted
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]>
1 parent 0d6debd commit f1a6534

File tree

1 file changed

+211
-42
lines changed

1 file changed

+211
-42
lines changed

Tests/IntegrationTests/UICatalog/ForceDriverTests.cs

Lines changed: 211 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,33 @@ public ForceDriverTests (ITestOutputHelper output)
1616
}
1717

1818
/// <summary>
19-
/// Tests that ForceDriver persists when opening a scenario after Init/Shutdown cycles.
20-
/// This verifies the fix for issue #4391.
19+
/// Tests that ForceDriver persists when running UICatalogTop and then opening a scenario.
20+
/// This simulates the actual UICatalog flow and verifies the fix for issue #4391.
2121
/// </summary>
2222
[Fact]
23-
public void ForceDriver_Persists_Across_Init_Shutdown_Cycles ()
23+
public void ForceDriver_Persists_From_UICatalogTop_To_Scenario ()
2424
{
2525
// Arrange
2626
const string expectedDriver = "fake";
2727

2828
ConfigurationManager.Disable (true);
2929
Application.ResetState (true);
3030

31+
// Initialize UICatalog.Options (required by UICatalogTop)
32+
global::UICatalog.UICatalog.Options = new UICatalogCommandLineOptions
33+
{
34+
Driver = expectedDriver,
35+
DontEnableConfigurationManagement = false,
36+
Scenario = "none",
37+
BenchmarkTimeout = 2500,
38+
Benchmark = false,
39+
ResultsFile = string.Empty,
40+
DebugLogLevel = "Warning"
41+
};
42+
43+
// Initialize cached scenarios (required by UICatalogTop)
44+
UICatalogTop.CachedScenarios = Scenario.GetScenarios ();
45+
3146
// Set ForceDriver in RuntimeConfig (simulating what UICatalog does with --driver option)
3247
ConfigurationManager.RuntimeConfig = $$"""
3348
{
@@ -38,54 +53,136 @@ public void ForceDriver_Persists_Across_Init_Shutdown_Cycles ()
3853
// Enable ConfigurationManager with all locations (as UICatalog does)
3954
ConfigurationManager.Enable (ConfigLocations.All);
4055

41-
var firstDriverName = string.Empty;
42-
var secondDriverName = string.Empty;
56+
var topLevelDriverName = string.Empty;
57+
var scenarioDriverName = string.Empty;
58+
var iterationCount = 0;
59+
EventHandler<IterationEventArgs>? iterationHandler = null;
4360

4461
try
4562
{
46-
// Act - Cycle 1: Init and check driver
47-
_output.WriteLine ("Cycle 1: First Init");
63+
// Phase 1: Run UICatalogTop (simulating main UI)
64+
_output.WriteLine ("=== Phase 1: Running UICatalogTop ===");
4865
Application.Init ();
49-
firstDriverName = Application.Driver?.GetName () ?? string.Empty;
50-
_output.WriteLine ($"Cycle 1 driver: {firstDriverName}");
51-
Application.Shutdown ();
66+
topLevelDriverName = Application.Driver?.GetName () ?? string.Empty;
67+
_output.WriteLine ($"UICatalogTop driver: {topLevelDriverName}");
5268

53-
// Act - Cycle 2: Reload RuntimeConfig and Init again (simulating scenario opening)
54-
_output.WriteLine ("Cycle 2: Reload RuntimeConfig and Init again");
69+
var top = new UICatalogTop ();
5570

56-
// This simulates what the fix does before each scenario
57-
ConfigurationManager.Load (ConfigLocations.Runtime);
58-
ConfigurationManager.Apply ();
71+
// Set up to automatically select a scenario and stop
72+
iterationHandler = (sender, e) =>
73+
{
74+
iterationCount++;
75+
76+
// On first iteration, select a scenario and request stop
77+
if (iterationCount == 1)
78+
{
79+
// Select the first scenario
80+
if (UICatalogTop.CachedScenarios is { Count: > 0 })
81+
{
82+
UICatalogTop.CachedSelectedScenario =
83+
(Scenario)Activator.CreateInstance (UICatalogTop.CachedScenarios[0].GetType ())!;
84+
Application.RequestStop ();
85+
}
86+
}
87+
};
88+
89+
Application.Iteration += iterationHandler;
90+
Application.Run (top);
91+
Application.Iteration -= iterationHandler;
5992

60-
// Scenario calls Application.Init() without parameters
61-
Application.Init ();
62-
secondDriverName = Application.Driver?.GetName () ?? string.Empty;
63-
_output.WriteLine ($"Cycle 2 driver: {secondDriverName}");
93+
top.Dispose ();
6494
Application.Shutdown ();
95+
96+
_output.WriteLine ($"Selected scenario: {UICatalogTop.CachedSelectedScenario?.GetName ()}");
97+
_output.WriteLine ($"UICatalogTop completed after {iterationCount} iterations");
98+
99+
// Phase 2: Run the selected scenario (simulating what UICatalog.cs does)
100+
if (UICatalogTop.CachedSelectedScenario is { } scenario)
101+
{
102+
_output.WriteLine ($"\n=== Phase 2: Running scenario '{scenario.GetName ()}' ===");
103+
104+
// Reload RuntimeConfig before scenario (as the fix does)
105+
if (!global::UICatalog.UICatalog.Options.DontEnableConfigurationManagement)
106+
{
107+
ConfigurationManager.Load (ConfigLocations.Runtime);
108+
ConfigurationManager.Apply ();
109+
_output.WriteLine ("Reloaded RuntimeConfig");
110+
}
111+
112+
// Track the driver used inside the scenario
113+
string? driverInsideScenario = null;
114+
EventHandler<EventArgs<bool>>? initHandler = null;
115+
EventHandler<IterationEventArgs>? scenarioIterationHandler = null;
116+
117+
initHandler = (s, e) =>
118+
{
119+
if (e.Value)
120+
{
121+
driverInsideScenario = Application.Driver?.GetName ();
122+
123+
// Request stop immediately so the scenario doesn't actually run
124+
scenarioIterationHandler = (_, _) =>
125+
{
126+
Application.RequestStop ();
127+
// Remove immediately to avoid assertions in Shutdown
128+
if (scenarioIterationHandler != null)
129+
{
130+
Application.Iteration -= scenarioIterationHandler;
131+
scenarioIterationHandler = null;
132+
}
133+
};
134+
Application.Iteration += scenarioIterationHandler;
135+
}
136+
};
137+
138+
Application.InitializedChanged += initHandler;
139+
140+
// Run the scenario's Main() method (this is what UICatalog does)
141+
scenario.Main ();
142+
scenarioDriverName = driverInsideScenario ?? string.Empty;
143+
144+
Application.InitializedChanged -= initHandler;
145+
scenario.Dispose ();
146+
147+
_output.WriteLine ($"Scenario driver: {scenarioDriverName}");
148+
_output.WriteLine ("Scenario completed and disposed");
149+
}
150+
else
151+
{
152+
_output.WriteLine ("ERROR: No scenario was selected");
153+
Assert.Fail ("No scenario was selected");
154+
}
65155

66156
// Assert
67-
Assert.Equal (expectedDriver, firstDriverName);
68-
Assert.Equal (expectedDriver, secondDriverName);
69-
_output.WriteLine ($"SUCCESS: Driver '{expectedDriver}' persisted across Init/Shutdown cycles");
157+
_output.WriteLine ($"\n=== Results ===");
158+
_output.WriteLine ($"UICatalogTop driver: {topLevelDriverName}");
159+
_output.WriteLine ($"Scenario driver: {scenarioDriverName}");
160+
161+
Assert.Equal (expectedDriver, topLevelDriverName);
162+
Assert.Equal (expectedDriver, scenarioDriverName);
163+
_output.WriteLine ($"SUCCESS: Driver '{expectedDriver}' persisted from UICatalogTop to scenario");
70164
}
71165
finally
72166
{
167+
if (iterationHandler != null)
168+
{
169+
Application.Iteration -= iterationHandler;
170+
}
73171
ConfigurationManager.Disable (true);
74172
Application.ResetState (true);
75173
}
76174
}
77175

78176
/// <summary>
79-
/// Tests that ForceDriver is used when a scenario calls Application.Init() without parameters.
80-
/// This simulates the actual UICatalog scenario execution flow.
177+
/// Tests that ForceDriver persists when running multiple scenarios in sequence.
178+
/// This verifies the scenario loop in UICatalog works correctly.
81179
/// </summary>
82180
[Fact]
83-
public void ForceDriver_Used_By_Scenario_Init ()
181+
public void ForceDriver_Persists_Across_Multiple_Scenarios ()
84182
{
85183
// Arrange
86184
const string expectedDriver = "fake";
87-
Scenario? scenario = null;
88-
185+
89186
ConfigurationManager.Disable (true);
90187
Application.ResetState (true);
91188

@@ -99,34 +196,106 @@ public void ForceDriver_Used_By_Scenario_Init ()
99196
// Enable ConfigurationManager
100197
ConfigurationManager.Enable (ConfigLocations.All);
101198

199+
string? driver1 = null;
200+
string? driver2 = null;
201+
EventHandler<EventArgs<bool>>? initHandler1 = null;
202+
EventHandler<EventArgs<bool>>? initHandler2 = null;
203+
EventHandler<IterationEventArgs>? iterHandler1 = null;
204+
EventHandler<IterationEventArgs>? iterHandler2 = null;
205+
102206
try
103207
{
104-
// Get the first available scenario
208+
// Get two different scenarios to test
105209
var scenarios = Scenario.GetScenarios ();
106-
Assert.NotEmpty (scenarios);
210+
Assert.True (scenarios.Count >= 2, "Need at least 2 scenarios for this test");
211+
212+
var scenario1 = scenarios[0];
213+
var scenario2 = scenarios[1];
214+
215+
_output.WriteLine ($"Testing with scenarios: {scenario1.GetName ()} and {scenario2.GetName ()}");
216+
217+
// Run scenario 1
218+
initHandler1 = (s, e) =>
219+
{
220+
if (e.Value)
221+
{
222+
driver1 = Application.Driver?.GetName ();
223+
iterHandler1 = (_, _) =>
224+
{
225+
Application.RequestStop ();
226+
// Remove immediately to avoid assertions in Shutdown
227+
if (iterHandler1 != null)
228+
{
229+
Application.Iteration -= iterHandler1;
230+
iterHandler1 = null;
231+
}
232+
};
233+
Application.Iteration += iterHandler1;
234+
}
235+
};
107236

108-
scenario = scenarios[0];
109-
var scenarioName = scenario.GetName ();
110-
_output.WriteLine ($"Testing with scenario: {scenarioName}");
237+
Application.InitializedChanged += initHandler1;
238+
scenario1.Main ();
239+
Application.InitializedChanged -= initHandler1;
240+
scenario1.Dispose ();
241+
_output.WriteLine ($"Scenario 1 completed with driver: {driver1}");
111242

112-
// Reload RuntimeConfig before scenario (as the fix does)
243+
// Reload RuntimeConfig before scenario 2 (as the fix does)
113244
ConfigurationManager.Load (ConfigLocations.Runtime);
114245
ConfigurationManager.Apply ();
246+
_output.WriteLine ("Reloaded RuntimeConfig");
115247

116-
// Scenario calls Application.Init() - it should use ForceDriver
117-
Application.Init ();
118-
var driverName = Application.Driver?.GetName () ?? string.Empty;
119-
_output.WriteLine ($"Scenario driver: {driverName}");
248+
// Run scenario 2
249+
initHandler2 = (s, e) =>
250+
{
251+
if (e.Value)
252+
{
253+
driver2 = Application.Driver?.GetName ();
254+
iterHandler2 = (_, _) =>
255+
{
256+
Application.RequestStop ();
257+
// Remove immediately to avoid assertions in Shutdown
258+
if (iterHandler2 != null)
259+
{
260+
Application.Iteration -= iterHandler2;
261+
iterHandler2 = null;
262+
}
263+
};
264+
Application.Iteration += iterHandler2;
265+
}
266+
};
267+
268+
Application.InitializedChanged += initHandler2;
269+
scenario2.Main ();
270+
Application.InitializedChanged -= initHandler2;
271+
scenario2.Dispose ();
272+
_output.WriteLine ($"Scenario 2 completed with driver: {driver2}");
120273

121274
// Assert
122-
Assert.Equal (expectedDriver, driverName);
123-
_output.WriteLine ($"SUCCESS: Scenario uses ForceDriver '{expectedDriver}'");
124-
125-
Application.Shutdown ();
275+
Assert.Equal (expectedDriver, driver1);
276+
Assert.Equal (expectedDriver, driver2);
277+
_output.WriteLine ($"SUCCESS: Driver '{expectedDriver}' persisted across both scenarios");
126278
}
127279
finally
128280
{
129-
scenario?.Dispose ();
281+
// Cleanup any remaining handlers
282+
if (initHandler1 != null)
283+
{
284+
Application.InitializedChanged -= initHandler1;
285+
}
286+
if (iterHandler2 != null)
287+
{
288+
Application.InitializedChanged -= initHandler2;
289+
}
290+
if (iterHandler1 != null)
291+
{
292+
Application.Iteration -= iterHandler1;
293+
}
294+
if (iterHandler2 != null)
295+
{
296+
Application.Iteration -= iterHandler2;
297+
}
298+
130299
ConfigurationManager.Disable (true);
131300
Application.ResetState (true);
132301
}

0 commit comments

Comments
 (0)