syntaxai/tdd.md · main · e2e / admin-block-editor.spec.ts
// E2E: Fase 2b block-editor surface. This is the SAMA-ported CMS UI at
// /admin/edit/:type/:slug — distinct from the legacy textarea editor at
// /edit/:section/:slug. The legacy editor is covered by
// git-native-proof.spec; this file proves the new block-editor
// infrastructure is alive on live:
//
// 1. /admin is auth-gated (anonymous → 401)
// 2. /admin/assets/blockeditor.js bundles + serves the client TS as
// JavaScript with an ETag (and 304s on re-request)
// 3. With the admin storage state, /admin renders the list page
// (no 401, contains the "+ New" button or admin chrome)
//
// We deliberately do NOT exercise create/edit/save here — those
// roundtrip sxdoc → SQLite → commit and need fixtures + cleanup.
// git-native-proof.spec already proves the commit-pipeline shape via
// the legacy editor; what this file proves is that the *new* surface
// also exists, is gated correctly, and ships its bundle.
import { test, expect } from "@playwright/test";
import * as fs from "fs";
const ADMIN_AUTH_FILE = ".auth/admin.json";
test.describe("admin block-editor infrastructure", () => {
test("anonymous /admin is 401 (auth-gate intact)", async ({ request }) => {
const res = await request.get("/admin", { failOnStatusCode: false });
expect(res.status()).toBe(401);
});
test("blockeditor bundle serves with ETag + 304 on re-request", async ({ request }) => {
const first = await request.get("/admin/assets/blockeditor.js");
expect(first.status()).toBe(200);
expect(first.headers()["content-type"]).toMatch(/javascript/);
const body = await first.text();
// It's an ES-module bundle compiled from src/client/blockeditor.ts +
// src/client/blocks.ts + src/client/slashmenu.ts — the slash-menu
// ID is a stable marker that survives minification.
expect(body.length).toBeGreaterThan(2000);
const etag = first.headers()["etag"];
expect(etag).toBeTruthy();
const second = await request.get("/admin/assets/blockeditor.js", {
headers: { "If-None-Match": etag! },
});
expect(second.status()).toBe(304);
});
});
test.describe("admin block-editor (authenticated)", () => {
test.skip(!fs.existsSync(ADMIN_AUTH_FILE), `no ${ADMIN_AUTH_FILE} found`);
test.use({ storageState: ADMIN_AUTH_FILE });
test("authenticated /admin renders the list page", async ({ page }) => {
const res = await page.goto("/admin");
expect(res?.status()).toBe(200);
// The list page links to /admin/new — that anchor is the canonical
// marker that the block-editor surface (not the legacy editor) is
// serving this request.
await expect(page.locator('a[href="/admin/new"]')).toBeVisible();
});
});