ZDDC/tests/build-label.spec.js
ZDDC e7f6334daa chore: retire mdedit tool — markdown editor lives in browse now
mdedit/ is gone. Its functionality moved into browse's preview plugin
(browse/js/preview-markdown.js) — YAML front matter editing, outline,
and on-demand DOCX/HTML/PDF download all happen there. Browse is the
default_tool for working/ + reviewing/ as of the previous commit, so
existing URLs of the form /<project>/working land on browse without
operator action.

Removed:

  • mdedit/ source tree (Toast UI app, CSS, JS, template, build.sh)
  • zddc/internal/apps/embedded/mdedit.html (//go:embed blob)
  • tests/mdedit.spec.js + the "mdedit" project in playwright.config.js
  • mdedit entries in zddc/internal/apps/embed.go (//go:embed, var,
    switch case in EmbeddedBytes)
  • "mdedit" in zddc/internal/zddc/validate.go AppNames + the matching
    error-message app list
  • "mdedit.html" branch in zddc/internal/apps/handler.go MatchAppHTML
  • mdedit case in tests (handler_test.go, validate_test.go,
    zddchandler_test.go) — test fixtures now use browse/classifier
  • mdedit from build (per-tool build.sh loop, tool-list literals,
    composer cards) and shared/build-lib.sh ZDDC_RELEASE_TOOLS
  • mdedit from freshen-channel's tool list and usage banner
  • mdedit-specific paragraphs in AGENTS.md and ARCHITECTURE.md;
    Markdown Editor section in ARCHITECTURE.md rewritten to point at
    browse/js/preview-markdown.js
  • mdedit from CLAUDE.md, README.md, zddc/README.md tool lists

Historical mdedit_v*.html / mdedit_v*.html.sig files in
/srv/zddc/releases/ on the deploy host are immutable history — they
stay where they are. The next ./build release cut will simply not
produce new mdedit_v* artifacts.
2026-05-13 10:34:31 -05:00

77 lines
3.8 KiB
JavaScript

/**
* build-label.spec.js
*
* Verifies that the {{BUILD_LABEL}} placeholder is correctly substituted in all
* four tool dist and website files:
*
* - No placeholder text leaks through
* - The .build-timestamp element is present and visible in the browser
* - The label content is either a timestamp ("Built: 20...") or a version ("v...")
* - website/ files (when present) always show the version format
*
* Note: dist/ files may show either format depending on whether the last build
* was a dev build (timestamp) or a release build (version). Both are valid.
*/
import { test, expect } from '@playwright/test';
import * as path from 'path';
import * as fs from 'fs';
const tools = ['archive', 'transmittal', 'classifier', 'browse'];
for (const tool of tools) {
const distPath = path.resolve(`${tool}/dist/${tool}.html`);
const websitePath = path.resolve(`website/${tool}.html`);
test.describe(`${tool}: build-label`, () => {
test(`dist file: no placeholder text leaks through`, async () => {
const html = fs.readFileSync(distPath, 'utf8');
expect(html).not.toContain('{{BUILD_LABEL}}');
expect(html).not.toContain('{{BUILD_TIMESTAMP}}');
});
test(`dist file: .build-timestamp element is visible in browser`, async ({ page }) => {
// browse may load Toast UI lazily; wait for full load.
const waitUntil = tool === 'browse' ? 'load' : 'domcontentloaded';
await page.goto(`file://${distPath}`, { waitUntil });
const el = page.locator('.build-timestamp');
await expect(el).toBeVisible({ timeout: 10000 });
});
test(`dist file: label is a valid channel or version string`, async () => {
const html = fs.readFileSync(distPath, 'utf8');
// Channel labels (alpha/beta) are wrapped in an inner <span style="color:red...">;
// stable version labels are bare text.
const match = html.match(/class="build-timestamp">(?:<span[^>]*>)?([^<]+?)(?:<\/span>)?</);
expect(match, 'build-timestamp element must have text content').toBeTruthy();
const label = match[1];
// Plain dev builds and --release alpha|beta carry the next-stable
// target as a pre-release suffix; the trailing field differs:
// plain dev → full timestamp + short SHA (+ "-dirty"):
// "v0.0.17-alpha · 2026-04-29 00:50:17 · 714faf6-dirty"
// --release alpha|beta → date-only + a three-word source-SHA slug:
// "v0.0.17-beta · 2026-04-29 · candle-mast-pearl"
// stable cut → bare version: "v0.0.17"
const sha = '[0-9a-f]+(?:-dirty)?'; // plain dev build
const slug = '[a-z]+-[a-z]+-[a-z]+'; // --release alpha|beta
const isChannel = new RegExp(
`^v\\d+\\.\\d+\\.\\d+-(?:alpha|beta) · 20\\d\\d-\\d\\d-\\d\\d(?: \\d\\d:\\d\\d:\\d\\d)? · (?:${sha}|${slug})$`
).test(label);
const isVersion = /^v\d+\.\d+\.\d+$/.test(label);
expect(isChannel || isVersion,
`Expected channel or version label, got: "${label}"`
).toBe(true);
});
test(`website file: label shows version format (release build)`, async () => {
if (!fs.existsSync(websitePath)) {
test.skip(true, `website/${tool}.html not present — run sh ${tool}/build.sh --release first`);
return;
}
const html = fs.readFileSync(websitePath, 'utf8');
expect(html).not.toContain('{{BUILD_LABEL}}');
expect(html).not.toContain('{{BUILD_TIMESTAMP}}');
expect(html).toMatch(/class="build-timestamp">(?:<span[^>]*>)?v\d+\.\d+\.\d+( BETA)?(?:<\/span>)?</);
});
});
}