Establishes version control for the personal Logseq DB fork before starting the server-client architecture migration and domain features described in docs/agent-guide and the approved implementation plan. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
95 lines
3.6 KiB
Clojure
95 lines
3.6 KiB
Clojure
(ns logseq.e2e.undo-redo-test
|
|
(:require
|
|
[clojure.set :as set]
|
|
[clojure.string :as string]
|
|
[clojure.test :refer [deftest testing is use-fixtures]]
|
|
[logseq.e2e.api :refer [ls-api-call!]]
|
|
[logseq.e2e.assert :as assert]
|
|
[logseq.e2e.block :as b]
|
|
[logseq.e2e.fixtures :as fixtures]
|
|
[logseq.e2e.keyboard :as k]
|
|
[logseq.e2e.page :as p]
|
|
[logseq.e2e.util :as util]
|
|
[wally.main :as w]
|
|
[wally.repl :as repl]))
|
|
|
|
(use-fixtures :once fixtures/open-page)
|
|
|
|
(use-fixtures :each
|
|
fixtures/new-logseq-page
|
|
fixtures/validate-graph)
|
|
|
|
(deftest undo-redo-paste
|
|
(testing "Undo redo paste blocks"
|
|
(b/new-blocks ["b1" "b2"])
|
|
(b/select-blocks 2)
|
|
(b/copy)
|
|
(b/new-block "")
|
|
(b/paste)
|
|
(util/exit-edit)
|
|
(is (= ["b1" "b2" "b1" "b2"] (util/get-page-blocks-contents)))
|
|
(b/undo)
|
|
(util/exit-edit)
|
|
(is (= ["b1" "b2" ""] (util/get-page-blocks-contents)))
|
|
(b/redo)
|
|
(util/exit-edit)
|
|
(is (= ["b1" "b2" "b1" "b2"] (util/get-page-blocks-contents)))))
|
|
|
|
(deftest undo-latest-saved-block-content-once
|
|
(testing "Undo reverts the latest saved block content on the first attempt"
|
|
(b/new-blocks ["b1"])
|
|
(util/wait-timeout 2000)
|
|
(util/move-cursor-to-end)
|
|
(util/press-seq " new text" :delay 20)
|
|
(util/wait-timeout 1000)
|
|
(b/undo)
|
|
(util/exit-edit)
|
|
(is (= ["b1"] (util/get-page-blocks-contents)))))
|
|
|
|
(deftest cut-and-paste-preserves-multiple-block-trees
|
|
(testing "Cut waits for structured clipboard data before deleting nested blocks"
|
|
(let [page-name (p/get-page-name)
|
|
page-uuid (get (ls-api-call! :editor.getBlock page-name) "uuid")
|
|
target-uuid (get (first (ls-api-call! :editor.getPageBlocksTree page-name))
|
|
"uuid")]
|
|
(util/exit-edit)
|
|
(ls-api-call! :editor.insertBatchBlock
|
|
page-uuid
|
|
[{:content "parent a"
|
|
:children [{:content "child a1"}
|
|
{:content "child a2"}]}
|
|
{:content "parent b"
|
|
:children [{:content "child b1"}
|
|
{:content "child b2"}]}])
|
|
(w/click (util/get-by-text "child b2" true))
|
|
(b/select-blocks 6)
|
|
(k/press "ControlOrMeta+x" {:delay 100})
|
|
(loop [remaining 50]
|
|
(let [blocks (ls-api-call! :editor.getPageBlocksTree page-name)]
|
|
(when (some #(not (string/blank? (get % "content"))) blocks)
|
|
(when (zero? remaining)
|
|
(throw (ex-info "Cut did not remove the selected block trees" {})))
|
|
(util/wait-timeout 100)
|
|
(recur (dec remaining)))))
|
|
(w/click (format "#ls-block-%s .block-content" target-uuid))
|
|
(b/paste)
|
|
(util/exit-edit)
|
|
(let [tree (loop [remaining 50]
|
|
(let [blocks (remove #(string/blank? (get % "content"))
|
|
(ls-api-call! :editor.getPageBlocksTree page-name))]
|
|
(if (or (= 2 (count blocks)) (zero? remaining))
|
|
blocks
|
|
(do
|
|
(util/wait-timeout 100)
|
|
(recur (dec remaining))))))
|
|
titles (fn [blocks]
|
|
(mapv #(get % "content") blocks))
|
|
children (fn [block]
|
|
(titles (get block "children")))]
|
|
(is (= ["parent a" "parent b"] (titles tree)))
|
|
(is (= ["child a1" "child a2"] (children (first tree))))
|
|
(is (= ["child b1" "child b2"] (children (second tree)))))
|
|
(util/refresh-until-graph-loaded)
|
|
(assert/assert-is-visible (util/get-by-text "parent a" true))
|
|
(assert/assert-is-visible (util/get-by-text "parent b" true)))))
|