Merge branch 'worktree-agent-a24fb696f5eee22f2' into feat/instance-picker
This commit is contained in:
@@ -603,10 +603,27 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
"""{"type":"object","properties":{"n":{"type":"integer"}},"required":["n"]}""", 20);
|
||||
private static readonly FlowScriptOption Tick = new("Tick", "Interval", null, null, null);
|
||||
|
||||
/// <summary>
|
||||
/// Picks an instance through the <c>InstancePicker</c> combobox that replaced the flat
|
||||
/// instance <c><select></c> (design 2026-09-08): open the panel, click the row. The
|
||||
/// fixture instance has no area, so its row sits at the root and needs no expansion.
|
||||
/// </summary>
|
||||
private static void PickInstance(IRenderedComponent<FlowDebuggerPage> cut, int id)
|
||||
{
|
||||
cut.Find("[data-test='flow-instance-toggle']").Click();
|
||||
cut.Find($"[data-test='flow-instance-row'][data-instance-id='{id}']").Click();
|
||||
}
|
||||
|
||||
/// <summary>Clicks the picker row (an area label toggles it, an instance label selects it).</summary>
|
||||
private static void ClickPickerRow(IRenderedComponent<FlowDebuggerPage> cut, string label) =>
|
||||
cut.FindAll("[data-test='flow-instance-row']").First(r => r.TextContent.Trim() == label).Click();
|
||||
|
||||
private void WireInstance()
|
||||
{
|
||||
_templates.GetInstancesBySiteIdAsync(1, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<Instance>>([new Instance("Sim01") { Id = 7, SiteId = 1, TemplateId = 10 }]));
|
||||
_templates.GetAreasBySiteIdAsync(1, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<Area>>([]));
|
||||
_templates.GetInstanceByIdAsync(7, Arg.Any<CancellationToken>()).Returns(new Instance("Sim01") { Id = 7, SiteId = 1, TemplateId = 10 });
|
||||
_flow.GetInstanceScriptsAsync(7, Arg.Any<CancellationToken>()).Returns(Task.FromResult<IReadOnlyList<FlowScriptOption>>([Manual, OnFlag, Tick]));
|
||||
_flow.PredictScriptAsync(7, Arg.Any<string>(), Arg.Any<CancellationToken>()).Returns(ThreeNodePrediction());
|
||||
@@ -620,7 +637,7 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
cut.Find("button[data-test='flow-entry-script']").Click();
|
||||
cut.Find("select[data-test='flow-site-select']").Change("1");
|
||||
cut.Find("select[data-test='flow-instance-select']").Change("7");
|
||||
PickInstance(cut, 7);
|
||||
var options = cut.FindAll("select[data-test='flow-script-select'] option").Select(o => o.TextContent.Trim()).ToList();
|
||||
Assert.Equal(["— choose —", "Manual (Call)", "OnFlag (ValueChange: Flag)", "Tick (Interval)"], options);
|
||||
Assert.Empty(cut.FindAll("select[data-test='flow-attribute-select']"));
|
||||
@@ -634,7 +651,7 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
cut.Find("button[data-test='flow-entry-script']").Click();
|
||||
cut.Find("select[data-test='flow-site-select']").Change("1");
|
||||
cut.Find("select[data-test='flow-instance-select']").Change("7");
|
||||
PickInstance(cut, 7);
|
||||
cut.Find("select[data-test='flow-script-select']").Change("OnFlag");
|
||||
|
||||
Assert.Contains("Flag", cut.Find("[data-test='flow-inputs']").TextContent);
|
||||
@@ -653,7 +670,7 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
cut.Find("button[data-test='flow-entry-script']").Click();
|
||||
cut.Find("select[data-test='flow-site-select']").Change("1");
|
||||
cut.Find("select[data-test='flow-instance-select']").Change("7");
|
||||
PickInstance(cut, 7);
|
||||
cut.Find("select[data-test='flow-script-select']").Change("Manual");
|
||||
|
||||
Assert.NotEmpty(cut.FindAll("[data-test='flow-script-params']"));
|
||||
@@ -672,7 +689,7 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
cut.Find("button[data-test='flow-entry-script']").Click();
|
||||
cut.Find("select[data-test='flow-site-select']").Change("1");
|
||||
cut.Find("select[data-test='flow-instance-select']").Change("7");
|
||||
PickInstance(cut, 7);
|
||||
cut.Find("select[data-test='flow-script-select']").Change("Tick");
|
||||
Assert.Contains("takes no parameters", cut.Find("[data-test='flow-inputs']").TextContent);
|
||||
Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
|
||||
@@ -714,7 +731,7 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
cut.Find("button[data-test='flow-entry-script']").Click();
|
||||
cut.Find("select[data-test='flow-site-select']").Change("1");
|
||||
cut.Find("select[data-test='flow-instance-select']").Change("7");
|
||||
PickInstance(cut, 7);
|
||||
cut.Find("select[data-test='flow-script-select']").Change("Manual");
|
||||
cut.Find("#param-n").Input("abc"); // not an integer: the form parks a parse error
|
||||
Assert.True(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
|
||||
@@ -751,4 +768,51 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
Assert.Contains("takes no parameters", cut.Find("[data-test='flow-inputs']").TextContent);
|
||||
Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScriptEntry_InstancePicker_ShowsAreasCollapsed_UntilExpanded()
|
||||
{
|
||||
RegisterServices();
|
||||
WireInstance();
|
||||
// Same instance, now filed under Line1 / Cell A so the picker has a tree to drill into.
|
||||
_templates.GetAreasBySiteIdAsync(1, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<Area>>(
|
||||
[new Area("Line1") { Id = 1, SiteId = 1 }, new Area("Cell A") { Id = 2, SiteId = 1, ParentAreaId = 1 }]));
|
||||
_templates.GetInstancesBySiteIdAsync(1, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<Instance>>(
|
||||
[new Instance("Sim01") { Id = 7, SiteId = 1, TemplateId = 10, AreaId = 2 }]));
|
||||
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
cut.Find("button[data-test='flow-entry-script']").Click();
|
||||
cut.Find("select[data-test='flow-site-select']").Change("1");
|
||||
cut.Find("[data-test='flow-instance-toggle']").Click();
|
||||
|
||||
// The panel opens collapsed: only the root area, and the instance is not rendered at all.
|
||||
Assert.Equal(["Line1"], cut.FindAll("[data-test='flow-instance-row']").Select(r => r.TextContent.Trim()).ToList());
|
||||
Assert.Empty(cut.FindAll("[data-test='flow-instance-row'][data-instance-id='7']"));
|
||||
|
||||
ClickPickerRow(cut, "Line1");
|
||||
Assert.Empty(cut.FindAll("[data-test='flow-instance-row'][data-instance-id='7']"));
|
||||
|
||||
ClickPickerRow(cut, "Cell A");
|
||||
cut.Find("[data-test='flow-instance-row'][data-instance-id='7']").Click();
|
||||
|
||||
// Picking the row ran OnInstanceChangedAsync, so the script list is loaded.
|
||||
var options = cut.FindAll("select[data-test='flow-script-select'] option").Select(o => o.TextContent.Trim()).ToList();
|
||||
Assert.Equal(["— choose —", "Manual (Call)", "OnFlag (ValueChange: Flag)", "Tick (Interval)"], options);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScriptEntry_DeepLink_InstanceId_ShowsItsNameInThePicker()
|
||||
{
|
||||
RegisterServices();
|
||||
WireInstance();
|
||||
var nav = Services.GetRequiredService<NavigationManager>();
|
||||
nav.NavigateTo("/deployment/flow-debugger?instanceId=7");
|
||||
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
|
||||
cut.WaitForAssertion(() =>
|
||||
Assert.Equal("Sim01", cut.Find("[data-test='flow-instance-input']").GetAttribute("value")));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user