test(e2e): make org-template import spec fail-closed (#2809) #2811

Closed
agent-dev-a wants to merge 1 commits from fix/2809-org-template-import-fail-closed into main
+24 -11
View File
@@ -2,14 +2,30 @@ import { test, expect } from "@playwright/test";
const API = process.env.E2E_API_URL ?? "http://localhost:8080";
test.describe("Org template import (PLAN.md §20.3)", () => {
test("org templates section renders inside the palette", async ({ page }) => {
// Sanity: platform must serve /org/templates
const res = await page.request.get(`${API}/org/templates`);
expect(res.ok()).toBeTruthy();
const orgs: { dir: string; name: string; workspaces: number }[] = await res.json();
test.skip(orgs.length === 0, "No org templates configured");
interface OrgTemplate {
dir: string;
name: string;
workspaces: number;
}
test.describe("Org template import (PLAN.md §20.3)", () => {
let orgs: OrgTemplate[] = [];
test.beforeAll(async ({ request }) => {
const res = await request.get(`${API}/org/templates`);
expect(res.ok(), "GET /org/templates must succeed").toBeTruthy();
orgs = (await res.json()) as OrgTemplate[];
// Fail-closed: this E2E exists to prove the org-template import surface
// renders real templates. An empty registry is a setup failure, not a
// reason to skip coverage. Component tests cover the empty-state UI.
expect(
orgs.length,
"No org templates configured — run scripts/clone-manifest.sh (or equivalent) before this E2E suite",
).toBeGreaterThan(0);
});
test("org templates section renders inside the palette", async ({ page }) => {
await page.goto("/", { waitUntil: "networkidle" });
// The Org Templates section lives in TWO places: inside the EmptyState
@@ -34,10 +50,6 @@ test.describe("Org template import (PLAN.md §20.3)", () => {
});
test("import button exists for every org template returned by the API", async ({ page }) => {
const res = await page.request.get(`${API}/org/templates`);
const orgs: { dir: string }[] = await res.json();
test.skip(orgs.length === 0, "No org templates configured");
await page.goto("/", { waitUntil: "networkidle" });
const paletteToggle = page.getByTitle("Template Palette");
if (await paletteToggle.isVisible()) {
@@ -45,6 +57,7 @@ test.describe("Org template import (PLAN.md §20.3)", () => {
}
const section = page.getByTestId("org-templates-section").first();
await expect(section).toBeVisible({ timeout: 15000 });
// Wait for the API result to render (one Import button per org)
const buttons = section.getByRole("button", { name: /Import org/i });
await expect(buttons).toHaveCount(orgs.length, { timeout: 15000 });