feat(FN-677): add browser verification workflow step template

- Add browser verification workflow step template to WORKFLOW_STEP_TEMPLATES
- Update NewTaskModal UI with browser verification checkbox
- Update InlineCreateCard UI with browser verification toggle
- Add tests for browser verification feature
- Create changeset for minor version bump
This commit is contained in:
gsxdsm
2026-04-02 10:20:22 -07:00
parent 1ec0dccb69
commit c5a75702c3
6 changed files with 286 additions and 38 deletions

View File

@@ -19,6 +19,7 @@ vi.mock("lucide-react", () => ({
Zap: () => null,
ChevronDown: () => null,
ChevronUp: () => null,
Globe: () => null,
}));
// Mock the api module
@@ -740,4 +741,89 @@ describe("InlineCreateCard button visibility when collapsed", () => {
// Footer should now be in the DOM
expect(document.getElementById("inline-create-controls")).toBeTruthy();
});
describe("browser verification", () => {
it("shows browser verification button when expanded", () => {
const { props } = renderCard();
// Button should not be visible when collapsed
expect(screen.queryByTestId("browser-verification-toggle")).toBeNull();
// Expand the card
expandCard();
// Button should now be visible
expect(screen.getByTestId("browser-verification-toggle")).toBeTruthy();
});
it("toggles browser verification when button is clicked", () => {
const { props } = renderCard();
expandCard();
const button = screen.getByTestId("browser-verification-toggle");
// Initially not active
expect(button).not.toHaveClass("btn-active");
// Click to enable
fireEvent.click(button);
expect(button).toHaveClass("btn-active");
// Click to disable
fireEvent.click(button);
expect(button).not.toHaveClass("btn-active");
});
it("includes browser-verification in enabledWorkflowSteps when submitting with browser verification enabled", async () => {
const mockOnSubmit = vi.fn().mockResolvedValue(createMockTask());
const { props } = renderCard([], { onSubmit: mockOnSubmit });
expandCard();
// Enable browser verification
fireEvent.click(screen.getByTestId("browser-verification-toggle"));
// Fill in description
const textarea = screen.getByPlaceholderText("What needs to be done?");
fireEvent.change(textarea, { target: { value: "Test task with browser verification" } });
// Submit
fireEvent.click(screen.getByTestId("save-button"));
await waitFor(() => {
expect(mockOnSubmit).toHaveBeenCalledWith(
expect.objectContaining({
enabledWorkflowSteps: ["browser-verification"],
}),
);
});
});
it("resets browser verification state after successful submission", async () => {
const mockOnSubmit = vi.fn().mockResolvedValue(createMockTask({ id: "FN-042" }));
const { props } = renderCard([], { onSubmit: mockOnSubmit });
expandCard();
// Enable browser verification
fireEvent.click(screen.getByTestId("browser-verification-toggle"));
// Verify button is active
expect(screen.getByTestId("browser-verification-toggle")).toHaveClass("btn-active");
// Fill in description and submit
const textarea = screen.getByPlaceholderText("What needs to be done?");
fireEvent.change(textarea, { target: { value: "Task to complete" } });
fireEvent.click(screen.getByTestId("save-button"));
// Wait for submission to complete
await waitFor(() => {
expect(mockOnSubmit).toHaveBeenCalled();
});
// Collapse and expand to reset
expandCard();
// Browser verification should be reset (button not active)
expect(screen.getByTestId("browser-verification-toggle")).not.toHaveClass("btn-active");
});
});
});

View File

@@ -3,6 +3,12 @@ import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { NewTaskModal } from "../NewTaskModal";
import type { Task, Column } from "@fusion/core";
// Mock lucide-react
vi.mock("lucide-react", () => ({
Sparkles: () => null,
Globe: () => null,
}));
// Mock the api module
vi.mock("../../api", () => ({
uploadAttachment: vi.fn().mockResolvedValue({}),
@@ -233,4 +239,75 @@ describe("NewTaskModal", () => {
const createButton = screen.getByRole("button", { name: "Create Task" });
expect(createButton).not.toBeDisabled();
});
// Browser verification tests
describe("browser verification", () => {
it("shows browser verification checkbox", () => {
renderNewTaskModal();
expect(screen.getByTestId("browser-verification-checkbox")).toBeTruthy();
expect(screen.getByText("Browser Verification")).toBeTruthy();
});
it("adds browser-verification to selected workflow steps when checkbox is checked", async () => {
const { props } = renderNewTaskModal();
const checkbox = screen.getByTestId("browser-verification-checkbox").querySelector('input[type="checkbox"]') as HTMLInputElement;
fireEvent.click(checkbox);
await waitFor(() => {
expect(checkbox.checked).toBe(true);
});
const descTextarea = screen.getByLabelText(/Description/i);
fireEvent.change(descTextarea, { target: { value: "Test task" } });
fireEvent.click(screen.getByRole("button", { name: "Create Task" }));
await waitFor(() => {
expect(props.onCreateTask).toHaveBeenCalledWith(
expect.objectContaining({
enabledWorkflowSteps: expect.arrayContaining(["browser-verification"]),
}),
);
});
});
it("removes browser-verification from selected workflow steps when checkbox is unchecked", async () => {
renderNewTaskModal();
const checkbox = screen.getByTestId("browser-verification-checkbox").querySelector('input[type="checkbox"]') as HTMLInputElement;
// Check then uncheck
fireEvent.click(checkbox);
await waitFor(() => {
expect(checkbox.checked).toBe(true);
});
fireEvent.click(checkbox);
await waitFor(() => {
expect(checkbox.checked).toBe(false);
});
});
it("includes browser-verification in enabledWorkflowSteps when submitting with checkbox checked", async () => {
const { props } = renderNewTaskModal();
const checkbox = screen.getByTestId("browser-verification-checkbox").querySelector('input[type="checkbox"]') as HTMLInputElement;
fireEvent.click(checkbox);
const descTextarea = screen.getByLabelText(/Description/i);
fireEvent.change(descTextarea, { target: { value: "Browser test task" } });
fireEvent.click(screen.getByRole("button", { name: "Create Task" }));
await waitFor(() => {
expect(props.onCreateTask).toHaveBeenCalledWith(
expect.objectContaining({
enabledWorkflowSteps: ["browser-verification"],
}),
);
});
});
});
});