diff --git a/frontend/playwright/data/workspace/versions-init-fragment.json b/frontend/playwright/data/workspace/versions-init-fragment.json new file mode 100644 index 000000000..b18d2b15e --- /dev/null +++ b/frontend/playwright/data/workspace/versions-init-fragment.json @@ -0,0 +1 @@ +{"~:id":"~u406b7b01-d3e2-80e4-8005-3138b7cc5f0b","~:file-id":"~u406b7b01-d3e2-80e4-8005-3138ac5d449c","~:created-at":"~m1730197748513","~:data":{"~:options":{},"~:objects":{"~u00000000-0000-0000-0000-000000000000":{"~#shape":{"~:y":0,"~:hide-fill-on-export":false,"~:transform":{"~#matrix":{"~:a":1.0,"~:b":0.0,"~:c":0.0,"~:d":1.0,"~:e":0.0,"~:f":0.0}},"~:rotation":0,"~:name":"Root Frame","~:width":0.01,"~:type":"~:frame","~:points":[{"~#point":{"~:x":0.0,"~:y":0.0}},{"~#point":{"~:x":0.01,"~:y":0.0}},{"~#point":{"~:x":0.01,"~:y":0.01}},{"~#point":{"~:x":0.0,"~:y":0.01}}],"~:proportion-lock":false,"~:transform-inverse":{"~#matrix":{"~:a":1.0,"~:b":0.0,"~:c":0.0,"~:d":1.0,"~:e":0.0,"~:f":0.0}},"~:id":"~u00000000-0000-0000-0000-000000000000","~:parent-id":"~u00000000-0000-0000-0000-000000000000","~:frame-id":"~u00000000-0000-0000-0000-000000000000","~:strokes":[],"~:x":0,"~:proportion":1.0,"~:selrect":{"~#rect":{"~:x":0,"~:y":0,"~:width":0.01,"~:height":0.01,"~:x1":0,"~:y1":0,"~:x2":0.01,"~:y2":0.01}},"~:fills":[{"~:fill-color":"#FFFFFF","~:fill-opacity":1}],"~:flip-x":null,"~:height":0.01,"~:flip-y":null,"~:shapes":["~ua88f39e6-60a5-80c2-8005-3138aeee944b"]}},"~ua88f39e6-60a5-80c2-8005-3138aeee944b":{"~#shape":{"~:y":427,"~:hide-fill-on-export":false,"~:transform":{"~#matrix":{"~:a":1.0,"~:b":0.0,"~:c":0.0,"~:d":1.0,"~:e":0.0,"~:f":0.0}},"~:rotation":0,"~:grow-type":"~:fixed","~:hide-in-viewer":false,"~:name":"Board","~:width":551,"~:type":"~:frame","~:points":[{"~#point":{"~:x":637,"~:y":427}},{"~#point":{"~:x":1188,"~:y":427}},{"~#point":{"~:x":1188,"~:y":761}},{"~#point":{"~:x":637,"~:y":761}}],"~:proportion-lock":false,"~:transform-inverse":{"~#matrix":{"~:a":1.0,"~:b":0.0,"~:c":0.0,"~:d":1.0,"~:e":0.0,"~:f":0.0}},"~:id":"~ua88f39e6-60a5-80c2-8005-3138aeee944b","~:parent-id":"~u00000000-0000-0000-0000-000000000000","~:frame-id":"~u00000000-0000-0000-0000-000000000000","~:strokes":[],"~:x":637,"~:proportion":1,"~:selrect":{"~#rect":{"~:x":637,"~:y":427,"~:width":551,"~:height":334,"~:x1":637,"~:y1":427,"~:x2":1188,"~:y2":761}},"~:fills":[{"~:fill-color":"#FFFFFF","~:fill-opacity":1}],"~:flip-x":null,"~:height":334,"~:flip-y":null,"~:shapes":["~ua88f39e6-60a5-80c2-8005-3138b4d36f07"]}},"~ua88f39e6-60a5-80c2-8005-3138b196dd95":{"~#shape":{"~:y":489,"~:rx":0,"~:transform":{"~#matrix":{"~:a":1.0,"~:b":0.0,"~:c":0.0,"~:d":1.0,"~:e":0.0,"~:f":0.0}},"~:rotation":0,"~:grow-type":"~:fixed","~:hide-in-viewer":false,"~:name":"Rectangle","~:width":149,"~:type":"~:rect","~:points":[{"~#point":{"~:x":677,"~:y":489}},{"~#point":{"~:x":826,"~:y":489}},{"~#point":{"~:x":826,"~:y":629}},{"~#point":{"~:x":677,"~:y":629}}],"~:proportion-lock":false,"~:transform-inverse":{"~#matrix":{"~:a":1.0,"~:b":0.0,"~:c":0.0,"~:d":1.0,"~:e":0.0,"~:f":0.0}},"~:id":"~ua88f39e6-60a5-80c2-8005-3138b196dd95","~:parent-id":"~ua88f39e6-60a5-80c2-8005-3138b4d36f07","~:frame-id":"~ua88f39e6-60a5-80c2-8005-3138aeee944b","~:strokes":[],"~:x":677,"~:proportion":1,"~:selrect":{"~#rect":{"~:x":677,"~:y":489,"~:width":149,"~:height":140,"~:x1":677,"~:y1":489,"~:x2":826,"~:y2":629}},"~:fills":[{"~:fill-color":"#B1B2B5","~:fill-opacity":1}],"~:flip-x":null,"~:ry":0,"~:height":140,"~:flip-y":null}},"~ua88f39e6-60a5-80c2-8005-3138b4d36f07":{"~#shape":{"~:y":489,"~:transform":{"~#matrix":{"~:a":1.0,"~:b":0.0,"~:c":0.0,"~:d":1.0,"~:e":0.0,"~:f":0.0}},"~:rotation":0,"~:index":1,"~:name":"Group","~:width":149,"~:type":"~:group","~:points":[{"~#point":{"~:x":677,"~:y":489}},{"~#point":{"~:x":826,"~:y":489}},{"~#point":{"~:x":826,"~:y":629}},{"~#point":{"~:x":677,"~:y":629}}],"~:proportion-lock":false,"~:transform-inverse":{"~#matrix":{"~:a":1.0,"~:b":0.0,"~:c":0.0,"~:d":1.0,"~:e":0.0,"~:f":0.0}},"~:id":"~ua88f39e6-60a5-80c2-8005-3138b4d36f07","~:parent-id":"~ua88f39e6-60a5-80c2-8005-3138aeee944b","~:frame-id":"~ua88f39e6-60a5-80c2-8005-3138aeee944b","~:strokes":[],"~:x":677,"~:proportion":1,"~:selrect":{"~#rect":{"~:x":677,"~:y":489,"~:width":149,"~:height":140,"~:x1":677,"~:y1":489,"~:x2":826,"~:y2":629}},"~:fills":[],"~:flip-x":null,"~:height":140,"~:flip-y":null,"~:shapes":["~ua88f39e6-60a5-80c2-8005-3138b196dd95"]}}},"~:id":"~u406b7b01-d3e2-80e4-8005-3138ac5d449d","~:name":"Page 1"}} diff --git a/frontend/playwright/data/workspace/versions-init.json b/frontend/playwright/data/workspace/versions-init.json new file mode 100644 index 000000000..bf45f5be0 --- /dev/null +++ b/frontend/playwright/data/workspace/versions-init.json @@ -0,0 +1 @@ +{"~:features":{"~#set":["layout/grid","styles/v2","fdata/pointer-map","fdata/objects-map","components/v2","fdata/shape-data-type"]},"~:permissions":{"~:type":"~:membership","~:is-owner":true,"~:is-admin":true,"~:can-edit":true,"~:can-read":true,"~:is-logged":true},"~:has-media-trimmed":false,"~:comment-thread-seqn":0,"~:name":"New File 5","~:revn":2,"~:modified-at":"~m1730197748522","~:vern":0,"~:id":"~u406b7b01-d3e2-80e4-8005-3138ac5d449c","~:is-shared":false,"~:version":55,"~:project-id":"~u3ffbd505-2f26-800f-8004-f34da98bdad8","~:created-at":"~m1730197736824","~:data":{"~:pages":["~u406b7b01-d3e2-80e4-8005-3138ac5d449d"],"~:pages-index":{"~u406b7b01-d3e2-80e4-8005-3138ac5d449d":{"~#penpot/pointer":["~u406b7b01-d3e2-80e4-8005-3138b7cc5f0b",{"~:created-at":"~m1730197748531"}]}},"~:id":"~u406b7b01-d3e2-80e4-8005-3138ac5d449c","~:options":{"~:components-v2":true}}} diff --git a/frontend/playwright/data/workspace/versions-restore-snapshot-1.json b/frontend/playwright/data/workspace/versions-restore-snapshot-1.json new file mode 100644 index 000000000..b2076035a --- /dev/null +++ b/frontend/playwright/data/workspace/versions-restore-snapshot-1.json @@ -0,0 +1,4 @@ +{ + "~:id": "~u406b7b01-d3e2-80e4-8005-3140249a2f09", + "~:label": "INIT" +} diff --git a/frontend/playwright/data/workspace/versions-snapshot-1.json b/frontend/playwright/data/workspace/versions-snapshot-1.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/frontend/playwright/data/workspace/versions-snapshot-1.json @@ -0,0 +1 @@ +[] diff --git a/frontend/playwright/data/workspace/versions-snapshot-2.json b/frontend/playwright/data/workspace/versions-snapshot-2.json new file mode 100644 index 000000000..d9fe31496 --- /dev/null +++ b/frontend/playwright/data/workspace/versions-snapshot-2.json @@ -0,0 +1,10 @@ +[ + { + "~:id": "~u406b7b01-d3e2-80e4-8005-3140249a2f09", + "~:label": "October 29, 2024", + "~:revn": 2, + "~:created-at": "~m1730199694953", + "~:created-by": "user", + "~:profile-id": "~u4678a621-b446-818a-8004-e7b734def799" + } +] diff --git a/frontend/playwright/data/workspace/versions-snapshot-3.json b/frontend/playwright/data/workspace/versions-snapshot-3.json new file mode 100644 index 000000000..f5ec998f4 --- /dev/null +++ b/frontend/playwright/data/workspace/versions-snapshot-3.json @@ -0,0 +1,10 @@ +[ + { + "~:id": "~u406b7b01-d3e2-80e4-8005-3140249a2f09", + "~:label": "INIT", + "~:revn": 2, + "~:created-at": "~m1730199694953", + "~:created-by": "user", + "~:profile-id": "~u4678a621-b446-818a-8004-e7b734def799" + } +] diff --git a/frontend/playwright/data/workspace/versions-take-snapshot-1.json b/frontend/playwright/data/workspace/versions-take-snapshot-1.json new file mode 100644 index 000000000..d6b4b6e81 --- /dev/null +++ b/frontend/playwright/data/workspace/versions-take-snapshot-1.json @@ -0,0 +1 @@ +{"~:id":"~u406b7b01-d3e2-80e4-8005-3140249a2f09","~:label":"October 29, 2024"} diff --git a/frontend/playwright/data/workspace/versions-update-snapshot-1.json b/frontend/playwright/data/workspace/versions-update-snapshot-1.json new file mode 100644 index 000000000..0a09b25c1 --- /dev/null +++ b/frontend/playwright/data/workspace/versions-update-snapshot-1.json @@ -0,0 +1,8 @@ +{ + "~:id": "~u406b7b01-d3e2-80e4-8005-3140249a2f09", + "~:label": "INIT", + "~:revn": 2, + "~:profile-id": "~u4678a621-b446-818a-8004-e7b734def799", + "~:created-by": "user", + "~:created-at": null +} diff --git a/frontend/playwright/ui/specs/versions.spec.js b/frontend/playwright/ui/specs/versions.spec.js new file mode 100644 index 000000000..ab753a374 --- /dev/null +++ b/frontend/playwright/ui/specs/versions.spec.js @@ -0,0 +1,69 @@ +import { test, expect } from "@playwright/test"; +import { WorkspacePage } from "../pages/WorkspacePage"; +import { presenceFixture } from "../../data/workspace/ws-notifications"; + +test.beforeEach(async ({ page }) => { + await WorkspacePage.init(page); +}); + +test("Save and restore version", async ({ page }) => { + const workspacePage = new WorkspacePage(page); + await workspacePage.setupEmptyFile(page); + await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json"); + await workspacePage.mockRPC( + "get-file-fragment?file-id=*&fragment-id=406b7b01-d3e2-80e4-8005-3138b7cc5f0b", + "workspace/versions-init-fragment.json", + ); + + await workspacePage.mockRPC( + "update-file?id=*", + "workspace/update-file-create-rect.json", + ); + + await workspacePage.goToWorkspace({ + fileId: "406b7b01-d3e2-80e4-8005-3138ac5d449c", + pageId: "406b7b01-d3e2-80e4-8005-3138ac5d449d", + }); + + await workspacePage.mockRPC( + "get-file-snapshots?file-id=*", + "workspace/versions-snapshot-1.json", + ); + + await page.getByLabel("History (Alt+H)").click(); + + await workspacePage.mockRPC( + "take-file-snapshot", + "workspace/versions-take-snapshot-1.json", + ); + + await workspacePage.mockRPC( + "get-file-snapshots?file-id=*", + "workspace/versions-snapshot-2.json", + ); + + await page.getByRole("button", { name: "Save version" }).click(); + + await workspacePage.mockRPC( + "update-file-snapshot", + "workspace/versions-update-snapshot-1.json", + ); + + await workspacePage.mockRPC( + "get-file-snapshots?file-id=*", + "workspace/versions-snapshot-3.json", + ); + + await page.getByRole("textbox").fill("INIT"); + await page.getByRole("textbox").press("Enter"); + + await page.getByTestId("version(INIT)").getByRole("button").click(); + await page.getByRole("button", { name: "Restore" }).click(); + + await workspacePage.mockRPC( + "restore-file-snapshot", + "workspace/versions-restore-snapshot-1.json", + ); + + await page.getByRole("button", { name: "Restore" }).click(); +}); diff --git a/frontend/src/app/main/ui/workspace/sidebar/versions.cljs b/frontend/src/app/main/ui/workspace/sidebar/versions.cljs index fd0108c4c..c867e50c8 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/versions.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/versions.cljs @@ -109,7 +109,8 @@ (kbd/esc? event) (st/emit! (dwv/update-version-state {:editing nil})))))] - [:li {:class (stl/css :version-entry-wrap)} + [:li {:data-testid (dm/str "version(" (:label entry) ")") + :class (stl/css :version-entry-wrap)} [:div {:class (stl/css :version-entry :is-snapshot)} [:img {:class (stl/css :version-entry-avatar) :alt (:fullname profile)