A ui-test entry had survived into the active trip's dailies. Three independent failures had to line up for that, and all three were real: 1. cleanupEntry() used host-side fs.rmSync. Grav's Apache workers run as root, so every entry the form creates is root-owned and recursive removal needs write permission on that directory — which the host user lacks. Cleanup had never worked for form-created entries; it just threw inside a path nothing checked. It now falls back to `docker exec … rm -rf` in the container that actually serves USER_DIR. 2. globalTeardown's dailies sweep keyed off a `parent:` in post-form.md — a key deliberately removed (the write target comes from site.yaml active_trip, and CLAUDE.md forbids re-adding a static parent). The regex could never match, so dailiesDir was always null and the sweep silently did nothing. It now reuses helpers' own resolution instead of keeping a divergent copy. 3. Nothing pinned the suite to this checkout's server. playwright.config.js defaults to :8081, so a worktree run hit the MAIN checkout — entries created in one content tree while the specs asserted and cleaned up in another. test-ui now passes GRAV_BASE_URL from GRAV_PORT, and globalSetup hard-fails when the server's bind mount disagrees with the tree the specs read. Also fixed, found on the way to a green run: - test-account interpolated the password into an `sh -c` string, so a password containing a shell metacharacter was re-parsed by the container's shell (`sh: 2: <fragment>: not found`, no account, every UI run dead). It now travels via `docker exec -e`, making the recipe indifferent to its contents. - `make start` in a worktree always failed: travel-memories declares `env_file: .env` and worktree-new creates none. It degrades to start-grav there — a worktree with no server is what sent runs to :8081 in the first place. - test-form-config asserted a hero_image field that 8cf1145 deliberately removed; it had been failing ever since. Verified: config 22/22, post 6/6, location-override 20/20, and a full UI run now leaves zero ui-test entries behind. The remaining UI failures are pre-existing on main — site.yaml pins owner_username to a real account while the suite logs in as testrunner, so owner-only controls never render for it. Only trip-publish.spec.js patches that; delete-flow, edit-mode and anon-view do not. Left for a separate branch.
45 lines
1.8 KiB
JavaScript
45 lines
1.8 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Reuse the specs' own resolution rather than reimplementing it. The previous
|
|
// version of this file derived the dailies directory from a `parent:` key in
|
|
// pages/02.post/post-form.md — a key that was deliberately removed (the write
|
|
// target is injected server-side from site.yaml `active_trip`, and CLAUDE.md
|
|
// forbids re-adding a static parent). The regex therefore never matched,
|
|
// dailiesDir was always null, and the dailies sweep below silently did nothing.
|
|
// That is how ui-test entries survived into the active trip's content.
|
|
// removeEntryDir handles the root-owned case by deleting through the container —
|
|
// see its comment. Plain fs.rmSync cannot remove what Grav's Apache wrote.
|
|
const { USER_DIR, TRACKER_DIR, removeEntryDir } = require('./ui/helpers');
|
|
|
|
function sweepUiTestEntries(dir) {
|
|
if (!dir || !fs.existsSync(dir)) return 0;
|
|
const found = fs.readdirSync(dir).filter(e => e.includes('ui-test'));
|
|
let removed = 0;
|
|
found.forEach(e => {
|
|
const target = path.join(dir, e);
|
|
try {
|
|
removeEntryDir(target);
|
|
removed++;
|
|
} catch (err) {
|
|
// Loud, not silent — a swallowed failure here is exactly what let a
|
|
// ui-test entry survive into the active trip's content.
|
|
console.error(`[teardown] COULD NOT REMOVE ${target}: ${err.message}`);
|
|
}
|
|
});
|
|
return removed;
|
|
}
|
|
|
|
module.exports = async function globalTeardown() {
|
|
// Sweep both the post inbox and the active trip's dailies.
|
|
const n1 = sweepUiTestEntries(path.join(USER_DIR, 'pages/02.post'));
|
|
const n2 = sweepUiTestEntries(TRACKER_DIR);
|
|
|
|
if (n1 + n2 > 0) {
|
|
console.log(
|
|
`[teardown] removed ${n1} ui-test entries from 02.post, ` +
|
|
`${n2} from ${path.relative(USER_DIR, TRACKER_DIR)}`
|
|
);
|
|
}
|
|
};
|