fix(FN-1101): normalize browser verification checkbox state

- Detect browser verification selection from both template token and resolved workflow step IDs
- Normalize checkbox toggles by replacing resolved browser-verification step IDs with a single canonical token
- Preserve non-browser workflow step selections when checking or unchecking browser verification
- Add TaskForm tests for resolved-ID checked state, unchecked cleanup, and re-check normalization
- Add a patch changeset for @gsxdsm/fusion documenting the browser verification state fix
This commit is contained in:
gsxdsm
2026-04-07 22:13:37 -07:00
parent 6bc9ad5275
commit 5b441ca86c
3 changed files with 125 additions and 3 deletions

View File

@@ -356,6 +356,13 @@ export function TaskForm({
description: "Verify web application functionality using browser automation (agent-browser)",
});
const browserVerificationResolvedIds = workflowSteps
.filter((step) => step.templateId === "browser-verification")
.map((step) => step.id);
const isBrowserVerificationSelected =
selectedWorkflowSteps.includes("browser-verification") ||
browserVerificationResolvedIds.some((id) => selectedWorkflowSteps.includes(id));
const availableDeps = tasks
.filter((t) => !dependencies.includes(t.id))
.sort((a, b) => {
@@ -753,12 +760,16 @@ export function TaskForm({
>
<input
type="checkbox"
checked={selectedWorkflowSteps.includes("browser-verification")}
checked={isBrowserVerificationSelected}
onChange={(e) => {
const filteredSteps = selectedWorkflowSteps.filter(
(id) => id !== "browser-verification" && !browserVerificationResolvedIds.includes(id),
);
onWorkflowStepsChange(
e.target.checked
? [...selectedWorkflowSteps, "browser-verification"]
: selectedWorkflowSteps.filter((id) => id !== "browser-verification")
? [...filteredSteps, "browser-verification"]
: filteredSteps,
);
}}
disabled={disabled}

View File

@@ -216,6 +216,112 @@ describe("TaskForm", () => {
expect(onWorkflowStepsChange).toHaveBeenCalledWith(["browser-verification"]);
});
it("shows browser verification checkbox as checked when selectedWorkflowSteps has resolved WS step ID", async () => {
const { fetchWorkflowSteps } = await import("../../api");
vi.mocked(fetchWorkflowSteps).mockResolvedValueOnce([
{
id: "WS-005",
name: "Browser Verification",
description: "Verify in browser",
prompt: "Run browser verification",
templateId: "browser-verification",
enabled: true,
createdAt: "",
updatedAt: "",
},
]);
renderTaskForm({ selectedWorkflowSteps: ["WS-005"] });
await waitFor(() => {
const checkbox = screen.getByTestId("browser-verification-checkbox").querySelector('input[type="checkbox"]') as HTMLInputElement;
expect(checkbox.checked).toBe(true);
});
});
it("removes resolved WS step IDs when browser verification is unchecked", async () => {
const { fetchWorkflowSteps } = await import("../../api");
vi.mocked(fetchWorkflowSteps).mockResolvedValueOnce([
{
id: "WS-005",
name: "Browser Verification",
description: "Verify in browser",
prompt: "Run browser verification",
templateId: "browser-verification",
enabled: true,
createdAt: "",
updatedAt: "",
},
{
id: "WS-001",
name: "QA Check",
description: "Run tests",
prompt: "Run tests",
enabled: true,
createdAt: "",
updatedAt: "",
},
]);
const onWorkflowStepsChange = vi.fn();
renderTaskForm({
selectedWorkflowSteps: ["WS-001", "WS-005"],
onWorkflowStepsChange,
});
const checkbox = screen.getByTestId("browser-verification-checkbox").querySelector('input[type="checkbox"]') as HTMLInputElement;
await waitFor(() => {
expect(checkbox.checked).toBe(true);
});
fireEvent.click(checkbox);
expect(onWorkflowStepsChange).toHaveBeenCalledWith(["WS-001"]);
});
it("normalizes resolved WS step IDs to browser-verification when checkbox is checked", async () => {
const { fetchWorkflowSteps } = await import("../../api");
vi.mocked(fetchWorkflowSteps).mockResolvedValueOnce([
{
id: "WS-005",
name: "Browser Verification",
description: "Verify in browser",
prompt: "Run browser verification",
templateId: "browser-verification",
enabled: true,
createdAt: "",
updatedAt: "",
},
{
id: "WS-001",
name: "QA Check",
description: "Run tests",
prompt: "Run tests",
enabled: true,
createdAt: "",
updatedAt: "",
},
]);
const onWorkflowStepsChange = vi.fn();
renderTaskForm({
selectedWorkflowSteps: ["WS-001", "WS-005"],
onWorkflowStepsChange,
});
const checkbox = screen.getByTestId("browser-verification-checkbox").querySelector('input[type="checkbox"]') as HTMLInputElement;
await waitFor(() => {
expect(checkbox.checked).toBe(true);
});
checkbox.checked = false;
fireEvent.click(checkbox);
expect(onWorkflowStepsChange).toHaveBeenCalledWith(["WS-001", "browser-verification"]);
});
it("disables all inputs when disabled prop is true", () => {
renderTaskForm({
disabled: true,