From 490f4e3c0033dd2b15a8c15cca0896fcd3f84e59 Mon Sep 17 00:00:00 2001 From: chipfighter <92256151+chipfighter@users.noreply.github.com> Date: Wed, 30 Sep 2026 16:33:20 +0900 Subject: [PATCH] test(ui): cover agent creation form validation Signed-off-by: chipfighter <92256151+chipfighter@users.noreply.github.com> --- ui/playwright/tests/agents/agent-crud.spec.ts | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/ui/playwright/tests/agents/agent-crud.spec.ts b/ui/playwright/tests/agents/agent-crud.spec.ts index 28901b89ea..1f0482c7e7 100644 --- a/ui/playwright/tests/agents/agent-crud.spec.ts +++ b/ui/playwright/tests/agents/agent-crud.spec.ts @@ -1,7 +1,7 @@ import type { Page } from "@playwright/test"; import { test, expect } from "../../fixtures/test"; import { agentNewChat, dataRows, expectSettled, loadPage, rowNamed, routes } from "../../helpers/app"; -import { confirmDelete, selectOption } from "../../helpers/resource"; +import { confirmDelete, expectRequired, selectOption } from "../../helpers/resource"; import { clickNav } from "../../helpers/nav"; type Source = "reference" | "inline"; @@ -29,25 +29,49 @@ for (const { template, harness } of CASES) { await page.getByTestId("agents-new").click(); await expect(page).toHaveURL(/\/agents\/new$/); await expect(page.getByTestId("agent-form-namespace")).toContainText("kagent"); + const submit = page.getByTestId("agent-form-submit"); + const problems = page.getByTestId("agent-form-problems"); + + await expect(submit).toBeDisabled(); + await expect(problems).toHaveText("A name is required."); + await expectRequired(page, { + marked: ["Name", "Namespace", "Shared template", "Shared harness"], + unmarked: [], + }); await page.getByTestId("agent-form-name").fill(name); + await expect(submit).toBeDisabled(); + await expect(problems).toHaveText("Choose a template."); if (template === "inline") { await chooseSource(page, "template", "inline"); + await expect(submit).toBeDisabled(); + await expect(problems).toHaveText("Choose a model configuration for the inline template."); await selectOption(page, "template-form-model", "default-model-config"); await page.getByTestId("template-form-description").fill("Inline before edit"); await page.getByTestId("template-form-prompt").fill("You answer briefly."); } else { await selectOption(page, "agent-form-template-ref", "shared-brain"); } + await expect(submit).toBeDisabled(); + await expect(problems).toHaveText("Choose a harness."); if (harness === "inline") { await chooseSource(page, "harness", "inline"); + await expect(submit).toBeDisabled(); + await expect(problems).toHaveText("A digest-pinned workload image is required."); await page.getByTestId("harness-image").fill(IMAGE); + await expect(submit).toBeDisabled(); + await expect(problems).toHaveText("A worker pool is required."); await page.getByTestId("harness-worker-pool").fill("pool-before"); + await expect(submit).toBeDisabled(); + await expect(problems).toHaveText("A snapshot location is required."); await page.getByTestId("harness-snapshot").fill("gs://snapshots/crud/"); } else { await selectOption(page, "agent-form-harness-ref", "k8s-agent"); } - await page.getByTestId("agent-form-submit").click(); + await expect(problems).toHaveCount(0); + await expect(submit).toBeEnabled(); + await expect(page).toHaveURL(/\/agents\/new$/); + await submit.click(); }); await test.step("2. it appears in the list with its sources and status", async () => {