Bundles a stretch of in-progress work across the SPA tools so the
tree returns to a coherent shippable state ahead of cutting a new
zddc-server stable image:
- landing: substantial rework of the project picker (sortable/filterable
table, presets refactor, ?projects= filter, ?v= channel propagation,
loading/error states)
- archive: presets cleanup, source.js refactor, filtering/url-state
alignment with the landing page
- mdedit: file-system module split, resizer, file-tree improvements,
base/toc styling tweaks
- transmittal/classifier: small template touch-ups for shared chrome
- shared: build-lib.sh helpers, new favicon.svg
- bootstrap, build.sh: pick up the channel-aware install/track zip
generation
- tests: new landing.spec.js, expanded archive/mdedit/build-label specs
- docs: CLAUDE.md picks up the zddc-server section and freshens the
alpha-build exception note
- regenerated artifacts: install.zip, track-{alpha,beta,stable}.zip,
*_alpha.html — these are produced by `sh build.sh` and per project
convention are committed alongside the source changes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
3.3 KiB
JavaScript
69 lines
3.3 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', 'mdedit'];
|
|
|
|
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 }) => {
|
|
const waitUntil = tool === 'mdedit' ? '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:
|
|
// "alpha · 2026-04-29 00:50:17 · 714faf6-dirty" (plain, with timestamp + dirty marker)
|
|
// "alpha · 2026-04-29 · 714faf6" (--release alpha, date only)
|
|
// "beta · 2026-04-29 · 714faf6" (--release beta)
|
|
const isChannel = /^(alpha|beta) · 20\d\d-\d\d-\d\d( \d\d:\d\d:\d\d)? · [0-9a-f]+(-dirty)?$/.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>)?</);
|
|
});
|
|
});
|
|
}
|