Преглед на файлове

Merge branch 'master' into dev/malli-schema&kondo-config

Gabriel Horner преди 2 години
родител
ревизия
d1157b0181
променени са 9 файла, в които са добавени 188 реда и са изтрити 72 реда
  1. 11 4
      docs/dev-practices.md
  2. 87 0
      e2e-tests/editor.spec.ts
  3. 1 1
      package.json
  4. 1 1
      resources/package.json
  5. 45 23
      src/electron/electron/handler.cljs
  6. 4 4
      src/main/frontend/handler/editor.cljs
  7. 1 1
      src/main/frontend/mobile/mobile_bar.cljs
  8. 34 34
      static/yarn.lock
  9. 4 4
      yarn.lock

+ 11 - 4
docs/dev-practices.md

@@ -77,10 +77,13 @@ mistakes [as noted here](./contributing-to-translations.md#fix-mistakes).
 
 ## Testing
 
+Even though we have a nightly release channel, it's hard for testing users (thanks to the brave users!) to notice all issues in a limited time, as Logseq is covering so many features (and the hell of combinations) 
+The only solution is automatic end-to-end tests - adding tests for GUI software is always painful but necessary
 We have unit and end to end tests.
 
 ### End to End Tests
 
+https://github.com/logseq/logseq/pulls?q=E2E 
 To run end to end tests
 
 ```sh
@@ -95,11 +98,15 @@ If e2e failed after first running:
 - `rm -rdf <repo dir>/tmp/`  
 - Windows: `rmdir /s %APPDATA%/Electron`  (Reference: https://www.electronjs.org/de/docs/latest/api/app#appgetpathname)
 
-If e2e tests fail, they can be debugged by examining a trace dump with [the
+There's a `traceAll()` helper function to enable playwright trace file dump for specific test files https://github.com/logseq/logseq/pull/8332
+
+If e2e tests fail in the file, they can be debugged by examining a trace dump with [the
 playwright trace
-viewer](https://playwright.dev/docs/trace-viewer#recording-a-trace). Locally
-this will get dumped into e2e-dump/. On CI the trace file will be under
-Artifacts at the bottom of a run page e.g.
+viewer](https://playwright.dev/docs/trace-viewer#recording-a-trace). 
+
+Locally this will get dumped into e2e-dump/. 
+
+On CI the trace file will be under Artifacts at the bottom of a run page e.g.
 https://github.com/logseq/logseq/actions/runs/3574600322.
 
 ### Unit Testing

+ 87 - 0
e2e-tests/editor.spec.ts

@@ -596,3 +596,90 @@ test('should not erase typed text when expanding block quickly after typing #389
     ''
   )
 })
+
+test('should keep correct undo and redo seq after indenting or outdenting the block #7615',async({page,block}) => {
+  await createRandomPage(page)
+
+  await block.mustFill("foo")
+  
+  await page.keyboard.press("Enter")
+  await expect(page.locator('textarea >> nth=0')).toHaveText("")
+  await block.indent()
+  await block.mustFill("bar")
+  await expect(page.locator('textarea >> nth=0')).toHaveText("bar")
+
+  if (IsMac) {
+    await page.keyboard.press('Meta+z')
+  } else {
+    await page.keyboard.press('Control+z')
+  }
+  // should undo "bar" input
+  await expect(page.locator('textarea >> nth=0')).toHaveText("")
+  if (IsMac) {
+    await page.keyboard.press('Shift+Meta+z')
+  } else {
+    await page.keyboard.press('Shift+Control+z')
+  }
+  // should redo "bar" input
+  await expect(page.locator('textarea >> nth=0')).toHaveText("bar")
+  await page.keyboard.press("Shift+Tab")
+  
+  await page.keyboard.press("Enter")
+  await expect(page.locator('textarea >> nth=0')).toHaveText("")
+  // swap input seq
+  await block.mustFill("baz")
+  await block.indent()
+
+  if (IsMac) {
+    await page.keyboard.press('Meta+z')
+  } else {
+    await page.keyboard.press('Control+z')
+  }
+  // should undo indention
+  await expect(page.locator('textarea >> nth=0')).toHaveText("baz")
+  await page.keyboard.press("Shift+Tab")
+
+  await page.keyboard.press("Enter")
+  await expect(page.locator('textarea >> nth=0')).toHaveText("")
+  // #7615
+  await page.keyboard.type("aaa")
+  await block.indent()
+  await page.keyboard.type(" bbb")
+  await expect(page.locator('textarea >> nth=0')).toHaveText("aaa bbb")
+  if (IsMac) {
+    await page.keyboard.press('Meta+z')
+  } else {
+    await page.keyboard.press('Control+z')
+  }
+  await expect(page.locator('textarea >> nth=0')).toHaveText("aaa")
+  if (IsMac) {
+    await page.keyboard.press('Meta+z')
+  } else {
+    await page.keyboard.press('Control+z')
+  }
+  await expect(page.locator('textarea >> nth=0')).toHaveText("aaa")
+  if (IsMac) {
+    await page.keyboard.press('Meta+z')
+  } else {
+    await page.keyboard.press('Control+z')
+  }
+  await expect(page.locator('textarea >> nth=0')).toHaveText("")
+  if (IsMac) {
+    await page.keyboard.press('Shift+Meta+z')
+  } else {
+    await page.keyboard.press('Shift+Control+z')
+  }
+  await expect(page.locator('textarea >> nth=0')).toHaveText("aaa")
+  if (IsMac) {
+    await page.keyboard.press('Shift+Meta+z')
+  } else {
+    await page.keyboard.press('Shift+Control+z')
+  }
+  await expect(page.locator('textarea >> nth=0')).toHaveText("aaa")
+  if (IsMac) {
+    await page.keyboard.press('Shift+Meta+z')
+  } else {
+    await page.keyboard.press('Shift+Control+z')
+  }
+  await expect(page.locator('textarea >> nth=0')).toHaveText("aaa bbb")
+})

+ 1 - 1
package.json

@@ -90,7 +90,7 @@
         "@capawesome/capacitor-background-task": "^2.0.0",
         "@excalidraw/excalidraw": "0.12.0",
         "@hugotomazi/capacitor-navigation-bar": "^2.0.0",
-        "@logseq/capacitor-file-sync": "0.0.17",
+        "@logseq/capacitor-file-sync": "0.0.18",
         "@logseq/react-tweet-embed": "1.3.1-1",
         "@sentry/react": "^6.18.2",
         "@sentry/tracing": "^6.18.2",

+ 1 - 1
resources/package.json

@@ -37,7 +37,7 @@
     "https-proxy-agent": "5.0.0",
     "@sentry/electron": "2.5.1",
     "posthog-js": "1.10.2",
-    "@logseq/rsapi": "0.0.59",
+    "@logseq/rsapi": "0.0.60",
     "electron-deeplink": "1.0.10",
     "abort-controller": "3.0.0",
     "fastify": "latest",

+ 45 - 23
src/electron/electron/handler.cljs

@@ -1,34 +1,34 @@
 (ns electron.handler
   "This ns starts the event handling for the electron main process and defines
   all the application-specific event types"
-  (:require ["electron" :refer [ipcMain dialog app autoUpdater shell]]
-            [cljs-bean.core :as bean]
-            ["fs" :as fs]
+  (:require ["/electron/utils" :as js-utils]
+            ["abort-controller" :as AbortController]
             ["buffer" :as buffer]
+            ["diff-match-patch" :as google-diff]
+            ["electron" :refer [app autoUpdater dialog ipcMain shell]]
+            ["fs" :as fs]
             ["fs-extra" :as fs-extra]
-            ["path" :as path]
             ["os" :as os]
-            ["diff-match-patch" :as google-diff]
-            ["/electron/utils" :as js-utils]
-            ["abort-controller" :as AbortController]
-            [electron.shell :as shell]
-            [electron.fs-watcher :as watcher]
-            [electron.configs :as cfgs]
-            [promesa.core :as p]
-            [clojure.string :as string]
-            [electron.utils :as utils]
-            [electron.logger :as logger]
-            [electron.state :as state]
+            ["path" :as path]
+            [cljs-bean.core :as bean]
+            [cljs.reader :as reader]
             [clojure.core.async :as async]
-            [electron.search :as search]
+            [clojure.string :as string]
+            [electron.backup-file :as backup-file]
+            [electron.configs :as cfgs]
+            [electron.file-sync-rsapi :as rsapi]
+            [electron.find-in-page :as find]
+            [electron.fs-watcher :as watcher]
             [electron.git :as git]
+            [electron.logger :as logger]
             [electron.plugin :as plugin]
-            [electron.window :as win]
-            [electron.file-sync-rsapi :as rsapi]
-            [electron.backup-file :as backup-file]
-            [cljs.reader :as reader]
+            [electron.search :as search]
             [electron.server :as server]
-            [electron.find-in-page :as find]))
+            [electron.shell :as shell]
+            [electron.state :as state]
+            [electron.utils :as utils]
+            [electron.window :as win]
+            [promesa.core :as p]))
 
 (defmulti handle (fn [_window args] (keyword (first args))))
 
@@ -177,12 +177,34 @@
           result (get (js->clj result) "filePaths")]
     (p/resolved (first result))))
 
-(defmethod handle :openDir [^js _window _messages]
+(defn- pretty-print-js-error
+  "Converts file related JS Error messages to a human readable format.
+   Ex.:
+   Error: EACCES: permission denied, scandir '/tmp/test'
+   Permission denied for path: '/tmp/test' (Code: EACCES)"
+  [e]
+  (some->>
+   e
+   str
+   ;; Message parsed as "Error: $ERROR_CODE$: $REASON$, function $PATH$"
+   (re-matches #"(?:Error\: )(.+)(?:\: )(.+)(?:, \w+ )('.+')")
+   rest
+   (#(str (string/capitalize (second %)) " for path: " (nth % 2) " (Code: " (first %) ")"))))
+
+(defmethod handle :openDir [^js window _messages]
   (logger/info ::open-dir "open folder selection dialog")
   (p/let [path (open-dir-dialog)]
     (logger/debug ::open-dir {:path path})
     (if path
-      (p/resolved (bean/->js (get-files path)))
+      (try
+        (p/resolved (bean/->js (get-files path)))
+        (catch js/Error e 
+          (do
+            (utils/send-to-renderer window "notification" {:type "error"
+                                                           :payload (str "Opening the specified directory failed.\n"
+                                                                         (or (pretty-print-js-error e) (str "Unexpected error: " e)))})
+            (p/rejected e))))
+
       (p/rejected (js/Error "path empty")))))
 
 (defmethod handle :getFiles [_window [_ path]]

+ 4 - 4
src/main/frontend/handler/editor.cljs

@@ -1660,11 +1660,11 @@
   [up?]
   (fn [event]
     (util/stop event)
+    (save-current-block!)
     (let [edit-block-id (:block/uuid (state/get-edit-block))
           move-nodes (fn [blocks]
                        (outliner-tx/transact!
                         {:outliner-op :move-blocks}
-                        (save-current-block!)
                         (outliner-core/move-blocks-up-down! blocks up?))
                        (when-let [block-node (util/get-first-block-by-id (:block/uuid (first blocks)))]
                          (.scrollIntoView block-node #js {:behavior "smooth" :block "nearest"})))]
@@ -2139,10 +2139,10 @@
   [node]
   (when-not (parent-is-page? node)
     (let [parent-node (tree/-get-parent node)]
+      (save-current-block!)
       (outliner-tx/transact!
        {:outliner-op :move-blocks
         :real-outliner-op :indent-outdent}
-       (save-current-block!)
        (outliner-core/move-blocks! [(:data node)] (:data parent-node) true)))))
 
 (defn- last-top-level-child?
@@ -2666,6 +2666,7 @@
 
 (defn indent-outdent
   [indent?]
+  (save-current-block!)
   (state/set-editor-op! :indent-outdent)
   (let [pos (some-> (state/get-input) cursor/pos)
         {:keys [block]} (get-state)]
@@ -2674,8 +2675,7 @@
       (outliner-tx/transact!
        {:outliner-op :move-blocks
         :real-outliner-op :indent-outdent}
-       (save-current-block!)
-       (outliner-core/indent-outdent-blocks! [block] indent?)))
+        (outliner-core/indent-outdent-blocks! [block] indent?)))
     (state/set-editor-op! :nil)))
 
 (defn keydown-tab-handler

+ 1 - 1
src/main/frontend/mobile/mobile_bar.cljs

@@ -99,4 +99,4 @@
         (for [command commands]
           command)]
        [:div.toolbar-hide-keyboard
-        (command #(state/clear-edit!) "keyboard-show")]])))
+        (command #(state/clear-edit!) {:icon "keyboard-show"})]])))

+ 34 - 34
static/yarn.lock

@@ -392,41 +392,41 @@
   resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
   integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
 
-"@logseq/[email protected].59":
-  version "0.0.59"
-  resolved "https://registry.yarnpkg.com/@logseq/rsapi-darwin-arm64/-/rsapi-darwin-arm64-0.0.59.tgz#3b478c1e045246a536446b39ee0df6943403ec8f"
-  integrity sha512-mi7Z8UVocVGayCB2kKUgq6MGRNI7BX9EZeTnf7JWRLdfVZe4Rf3FDe1Kr/zlY5lO27KYsPzqLC/Pw6IkQtZsvQ==
-
-"@logseq/[email protected].59":
-  version "0.0.59"
-  resolved "https://registry.yarnpkg.com/@logseq/rsapi-darwin-x64/-/rsapi-darwin-x64-0.0.59.tgz#7a3d746d4807523dfe0197658d1f1266c66534f3"
-  integrity sha512-hDf5QUa+vQRHJ7p0OBAREWYOwHepUpDUEIbyXhSzTb7g5vsr5yBEOygnRt1Jt6a1DfadMPDdrl925AaUrkZAjA==
-
-"@logseq/[email protected].59":
-  version "0.0.59"
-  resolved "https://registry.yarnpkg.com/@logseq/rsapi-linux-arm64-gnu/-/rsapi-linux-arm64-gnu-0.0.59.tgz#58e83687912deae39e6e15e57093e558d80cf7ea"
-  integrity sha512-3kqeSsIjPgd+O/DvhsawJIXdIa4aPVxNtmQ/YJeyXV7Alx5jPY1kPaxKsZUl6h3qr8Zrr5/wTtg0pUS33BwHPg==
-
-"@logseq/[email protected].59":
-  version "0.0.59"
-  resolved "https://registry.yarnpkg.com/@logseq/rsapi-linux-x64-gnu/-/rsapi-linux-x64-gnu-0.0.59.tgz#5dd228df20befbd642044d99e0a41df86d9cdda5"
-  integrity sha512-iBTxAlQNKX4g4AMJa2l4tOlActXchIFf0tFrNkSWKmyW1mi2AyQ78eObl90F9H1OAHbziOhOs+zzu8nZvJBIJQ==
-
-"@logseq/[email protected].59":
-  version "0.0.59"
-  resolved "https://registry.yarnpkg.com/@logseq/rsapi-win32-x64-msvc/-/rsapi-win32-x64-msvc-0.0.59.tgz#3a44b310ad8fa725cd2d1cb6056dc5d66fa644b2"
-  integrity sha512-tupB5/uxcChl6PZO1Wb1g9w8MpiMArM9wu4d2b0KGTccOExKrMwZzKcusFfgWsCqwiIqF2ozBPVd8JKMnAd+yw==
-
-"@logseq/[email protected].59":
-  version "0.0.59"
-  resolved "https://registry.yarnpkg.com/@logseq/rsapi/-/rsapi-0.0.59.tgz#94b359237632279e2ccaf58fbbd563b0718307dc"
-  integrity sha512-m3Y4/k2VmyuLLrNo1EuSBOiNASXrZHtC8bsN2a/AyHFeFuCDThqiTNJ0g5VqvqeaQBBZBaIUawg3OKsmjkRHhQ==
+"@logseq/[email protected].60":
+  version "0.0.60"
+  resolved "https://registry.yarnpkg.com/@logseq/rsapi-darwin-arm64/-/rsapi-darwin-arm64-0.0.60.tgz#5edd887b38dd4d26cae51d397ff0c6f3d96bec43"
+  integrity sha512-Bv0ck+pjHb0z6OaGbuIl4RNbKF1KRF281zDdpiVisdSByVQ6sCQ55lemvgDFgwlZWp3Bp6vyMTrfjlzeuP86ZQ==
+
+"@logseq/[email protected].60":
+  version "0.0.60"
+  resolved "https://registry.yarnpkg.com/@logseq/rsapi-darwin-x64/-/rsapi-darwin-x64-0.0.60.tgz#3c099b77f6e4fa5578a61de83e9907bfaf3ac3fa"
+  integrity sha512-iasBB89fB1h5kWAfrV2DQcynlUMKdR85GyruaVbJYspYp0SlkB+ZiR9vh5lkJQyNkMM8Y1hvLRh2ZTMAl+acWA==
+
+"@logseq/[email protected].60":
+  version "0.0.60"
+  resolved "https://registry.yarnpkg.com/@logseq/rsapi-linux-arm64-gnu/-/rsapi-linux-arm64-gnu-0.0.60.tgz#77e6ef67e87c975ca6a639da3a0b47a69afad8e7"
+  integrity sha512-op47HnJZUKYvrHsMFnlzkTd5uMeYCGkQXF1bYvYYgQrgREJyU2CzJHKKDoFZth13ahF8rjAccHeXhqg3TGccSg==
+
+"@logseq/[email protected].60":
+  version "0.0.60"
+  resolved "https://registry.yarnpkg.com/@logseq/rsapi-linux-x64-gnu/-/rsapi-linux-x64-gnu-0.0.60.tgz#fd96e37e902d9b4b031c603ec4fe1d06d9b2e594"
+  integrity sha512-LeM/PrGdVH3ix43erCVkKM0N5saXhJG7yxNl000/4bNAUkqdGOQ2Cnhy/TyekgZtMqblKjDl/1tJWboLA5jjLQ==
+
+"@logseq/[email protected].60":
+  version "0.0.60"
+  resolved "https://registry.yarnpkg.com/@logseq/rsapi-win32-x64-msvc/-/rsapi-win32-x64-msvc-0.0.60.tgz#ed2d072df731c01681c4a24caf5a26baa5ff37a9"
+  integrity sha512-22/RRF/VUAb5flW2DLkG0RUMj+LujghSP9pMgv2zkyap104HG1+Wy8xO4j1DkqtpZnwVd2MCohVuHeimHn8IMA==
+
+"@logseq/[email protected].60":
+  version "0.0.60"
+  resolved "https://registry.yarnpkg.com/@logseq/rsapi/-/rsapi-0.0.60.tgz#45763b9988e558c0e9513826cf55069ea0a413c1"
+  integrity sha512-fn2tdNyx8XCvh100YG3yD5yBI+kjv0Hz9WeFKFMHb/8JujwS/MnZdM/IKDbw+JtDp/46TfXPXttLm6FQBa7O2w==
   optionalDependencies:
-    "@logseq/rsapi-darwin-arm64" "0.0.59"
-    "@logseq/rsapi-darwin-x64" "0.0.59"
-    "@logseq/rsapi-linux-arm64-gnu" "0.0.59"
-    "@logseq/rsapi-linux-x64-gnu" "0.0.59"
-    "@logseq/rsapi-win32-x64-msvc" "0.0.59"
+    "@logseq/rsapi-darwin-arm64" "0.0.60"
+    "@logseq/rsapi-darwin-x64" "0.0.60"
+    "@logseq/rsapi-linux-arm64-gnu" "0.0.60"
+    "@logseq/rsapi-linux-x64-gnu" "0.0.60"
+    "@logseq/rsapi-win32-x64-msvc" "0.0.60"
 
 "@malept/cross-spawn-promise@^1.0.0", "@malept/cross-spawn-promise@^1.1.0":
   version "1.1.1"

+ 4 - 4
yarn.lock

@@ -487,10 +487,10 @@
     "@jridgewell/resolve-uri" "^3.0.3"
     "@jridgewell/sourcemap-codec" "^1.4.10"
 
-"@logseq/[email protected]7":
-  version "0.0.17"
-  resolved "https://registry.yarnpkg.com/@logseq/capacitor-file-sync/-/capacitor-file-sync-0.0.17.tgz#4bb9000c64aee8cc07d79069f5e3cbc0908b2613"
-  integrity sha512-B+VHtmH9tGNXiGcHDKNMY2Ype/YHPg+V+HaGYXqEEtzSVtw2QOe/RLkOZG+wKFhokSk3hNQyVd1/WdMGhdHS/Q==
+"@logseq/[email protected]8":
+  version "0.0.18"
+  resolved "https://registry.yarnpkg.com/@logseq/capacitor-file-sync/-/capacitor-file-sync-0.0.18.tgz#9e6c1386483fb693ce5fdd5b5a3fbb8627de40fc"
+  integrity sha512-tRcwc9OBh4oayhbMGj9iL+86jsUAT+Y76mLqsdYGsbKhck4Hv+YV3dZ0M9GUEFf18xE1pj6H7sB+qYGMd23X6w==
 
 "@logseq/[email protected]":
   version "1.3.1-1"