Two real findings from adversarial review of the previous commit (the v4 UI port's route change), both fixed: - app/tests-layout/*.spec.js (20 files, 133 tests): every one of these navigated to /funpack/ and asserted on composer-specific DOM (.cx-workspace*, window.FunPack) that no longer exists there now that the ported v4 frontend is served at that URL instead. Left as-is they would silently time out on every run. Each file now carries an explicit test.skip(true, "...") with a comment explaining why and pointing at the plan's pixel-exactness step, which is what will eventually rewrite these against the new DOM -- declared and tracked, not quietly broken. - core/tests/test_registry.py's fixture-based tests never exercised the new category field through the real announcement_of()/scan() path -- only test_schema.py's direct validate() calls did, which bypass registry.py's FIELDS name-mapping entirely. A typo there (e.g. "Category" instead of "CATEGORY") would have passed every existing test. The "good module" fixture gained CATEGORY = "guidance" and test_the_good_module_loads now asserts on it, closing the gap. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
80 lines
3.7 KiB
JavaScript
80 lines
3.7 KiB
JavaScript
// The timeline strip: drag to reorder, zoom to change clip width. jsdom
|
|
// covers the wiring against a fake store; this is a real drag in a real
|
|
// browser against the real store.
|
|
|
|
import { test, expect } from "@playwright/test";
|
|
|
|
// Skipped: / now serves the ported v4 frontend (app/legacy/), not composer --
|
|
// these specs assert on .cx-workspace*/window.FunPack, which no longer exist
|
|
// on the served page. Pending rewrite against the v4-derived DOM as part of
|
|
// the v4-UI-onto-v5-backend port's pixel-exactness verification step (see
|
|
// the plan file). Not deleted: the assertions are still the right SHAPE of
|
|
// check, just against selectors this page no longer has.
|
|
test.skip(true, "composer retired in favor of the v4 UI port -- rewrite against app/legacy's DOM");
|
|
|
|
test.describe.configure({ mode: "serial" });
|
|
|
|
/** A real HTML5 drag: dragstart on `from`, dragover + drop on `to`. */
|
|
async function dragCell(page, from, to) {
|
|
await page.evaluate(([fromSel, toSel]) => {
|
|
const source = document.querySelectorAll(".cx-strip-cell")[fromSel];
|
|
const target = document.querySelectorAll(".cx-strip-cell")[toSel];
|
|
const dt = new DataTransfer();
|
|
source.dispatchEvent(new DragEvent("dragstart", { bubbles: true, dataTransfer: dt }));
|
|
target.dispatchEvent(new DragEvent("dragover", { bubbles: true, cancelable: true, dataTransfer: dt }));
|
|
target.dispatchEvent(new DragEvent("drop", { bubbles: true, cancelable: true, dataTransfer: dt }));
|
|
}, [from, to]);
|
|
}
|
|
|
|
test("dragging a clip to a new spot reorders the project's scenes", async ({ page }) => {
|
|
await page.goto("/funpack/");
|
|
await page.waitForFunction(() => window.FunPack !== undefined);
|
|
|
|
const ids = await page.evaluate(() => {
|
|
const { project } = window.FunPack;
|
|
while (project.scenes.length < 3) project.addScene();
|
|
return project.scenes.slice(0, 3).map((s) => s.id);
|
|
});
|
|
|
|
await expect(page.locator(".cx-strip-cell")).toHaveCount(ids.length);
|
|
await dragCell(page, 0, 2);
|
|
|
|
const after = await page.evaluate(() => window.FunPack.project.scenes.map((s) => s.id));
|
|
expect(after.slice(0, 3)).toEqual([ids[1], ids[2], ids[0]]);
|
|
});
|
|
|
|
test("dropping a clip on itself changes nothing", async ({ page }) => {
|
|
await page.goto("/funpack/");
|
|
await page.waitForFunction(() => window.FunPack !== undefined);
|
|
const before = await page.evaluate(() => {
|
|
const { project } = window.FunPack;
|
|
while (project.scenes.length < 2) project.addScene();
|
|
return project.scenes.map((s) => s.id);
|
|
});
|
|
|
|
await dragCell(page, 0, 0);
|
|
|
|
const after = await page.evaluate(() => window.FunPack.project.scenes.map((s) => s.id));
|
|
expect(after).toEqual(before);
|
|
});
|
|
|
|
test("zoom changes clip width and survives a reload", async ({ page }) => {
|
|
// Cells also carry flex-grow (proportional to a scene's length), which can
|
|
// dominate rendered width when there is spare row to fill -- the variable
|
|
// zoom actually sets is the honest thing to check, not the geometry that
|
|
// competes with it.
|
|
await page.goto("/funpack/");
|
|
await page.waitForFunction(() => window.FunPack !== undefined);
|
|
await page.evaluate(() => { while (window.FunPack.project.scenes.length < 1) window.FunPack.project.addScene(); });
|
|
|
|
await page.getByRole("radio", { name: "L", exact: true }).click();
|
|
await expect.poll(() => page.locator(".cx-strip").evaluate((el) => el.style.getPropertyValue("--strip-w")))
|
|
.toBe("128px");
|
|
|
|
await page.reload();
|
|
await page.waitForFunction(() => window.FunPack !== undefined);
|
|
await expect(page.getByRole("radio", { name: "L", exact: true })).toHaveAttribute("aria-checked", "true");
|
|
await expect.poll(() => page.locator(".cx-strip").evaluate((el) => el.style.getPropertyValue("--strip-w")))
|
|
.toBe("128px");
|
|
});
|