diff --git a/mock/e2e/phy.spec.ts b/mock/e2e/phy.spec.ts index 6a51259..acba6e2 100644 --- a/mock/e2e/phy.spec.ts +++ b/mock/e2e/phy.spec.ts @@ -728,7 +728,7 @@ test("スイッチ・スタビの十字はトグルで出し、スタビ候補 const switchX = async () => (await mark.locator(".switch").boundingBox())!.x; const before = await switchX(); await page.getByLabel("switchOffset X").fill("0.625"); - await page.getByLabel("switchOffset X").blur(); + await page.getByLabel("switchOffset X").dispatchEvent("change"); await expect.poll(switchX).toBeGreaterThan(before + 10); await expect(mark.locator(".stab")).toHaveCount(4); diff --git a/mock/src/domain/history.ts b/mock/src/domain/history.ts index f50071d..6ee9509 100644 --- a/mock/src/domain/history.ts +++ b/mock/src/domain/history.ts @@ -10,12 +10,13 @@ export class ProjectHistory { ) { this.items = [structuredClone(initial)]; } - /** Adds one undoable snapshot unless a grouped edit is active. */ + /** Adds one undoable snapshot unless a grouped edit is active or nothing changed. */ push(value: ProjectFile): void { if (this.pending) { this.replaceTop(value); return; } + if (JSON.stringify(value) === JSON.stringify(this.items[this.cursor])) return; this.add(value); } /** Starts grouping subsequent pushes into a single operation. T-17. */ diff --git a/mock/tests/domain.test.ts b/mock/tests/domain.test.ts index 56e9033..801468a 100644 --- a/mock/tests/domain.test.ts +++ b/mock/tests/domain.test.ts @@ -149,6 +149,16 @@ describe("domain project flow", () => { expect(h.undo().phy.metadata.name).toBe(p.phy.metadata.name); expect(h.redo().phy.metadata.name).toBe("drag"); }); + it("does not add a history step for an unchanged snapshot", async () => { + const p = await createProjectFromKle(kle, { idGenerator: gen }), + h = new ProjectHistory(p); + const q = structuredClone(p); + q.phy.metadata.name = "edit"; + h.push(q); + h.push(structuredClone(q)); + expect(h.undo().phy.metadata.name).toBe(p.phy.metadata.name); + expect(h.canUndo).toBe(false); + }); it("imports the VIA geometry sample", async () => { const via = JSON.parse( readFileSync(new URL("../../samples/via/cr0wn60.json", import.meta.url), "utf8"),