1
0
Эх сурвалжийг харах

Fix pasting race condition (#5964)

* Fix re-running e2e tests when it reuses old app instances

I'm not certain this doesn't break things for other OSes/setups, but it was required for e2e tests to run after the first time I ran them. It keeps a list of all previous (now missing) graphs in the sidebar, and this flow properly causes the new one to be selected, where the old flow did not match what the UI was doing anymore.

* Add e2e test for quickly pasting blocks after editing new blocks

* Fix pasting quickly after editing a new block

* Remove "test.only" focus

* Fix clicking add button in first test by closing error notification

* Improve some flaky race conditions in tests

* Remove unrelated waits in E2E tests

* Update playwright version; update tests to match

* Fix logic for checking if there are unsaved edits

* Fix typescript complaints

* Reduce how long we wait after closing each error popup
Phoenix Eliot 3 жил өмнө
parent
commit
0747d5ccb7

+ 33 - 1
e2e-tests/editor.spec.ts

@@ -178,4 +178,36 @@ test('copy & paste block ref and replace its content', async ({ page, block }) =
     } else {
         await page.keyboard.press('Control+Shift+v')
     }
-})
+})
+
+test('copy and paste block after editing new block', async ({ page, block }) => {
+  await createRandomPage(page)
+
+  // Create a block and copy it in block-select mode
+  await block.mustFill('Block being copied')
+  await page.waitForTimeout(100)
+  await page.keyboard.press('Escape')
+  await page.waitForTimeout(100)
+  if (IsMac) {
+    await page.keyboard.press('Meta+c')
+  } else {
+    await page.keyboard.press('Control+c')
+  }
+  // await page.waitForTimeout(100)
+  await page.keyboard.press('Enter')
+  await page.waitForTimeout(100)
+  await page.keyboard.press('Enter')
+  
+  await page.waitForTimeout(100)
+  // Create a new block with some text
+  await page.keyboard.insertText("Typed block")
+
+  // Quickly paste the copied block
+  if (IsMac) {
+      await page.keyboard.press('Meta+v')
+  } else {
+      await page.keyboard.press('Control+v')
+  }
+
+  await expect(page.locator('text="Typed block"')).toHaveCount(1);
+})

+ 18 - 13
e2e-tests/utils.ts

@@ -2,6 +2,7 @@ import { Page, Locator } from 'playwright'
 import { expect, ConsoleMessage } from '@playwright/test'
 import * as process from 'process'
 import { Block } from './types'
+import pathlib from 'path'
 
 export const IsMac = process.platform === 'darwin'
 export const IsLinux = process.platform === 'linux'
@@ -159,39 +160,35 @@ export async function openLeftSidebar(page: Page): Promise<void> {
   let sidebar = page.locator('#left-sidebar')
 
   // Left sidebar is toggled by `is-open` class
-  if (!/is-open/.test(await sidebar.getAttribute('class'))) {
+  if (!/is-open/.test(await sidebar.getAttribute('class') || '')) {
     await page.click('#left-menu.button')
     await page.waitForTimeout(10)
     await expect(sidebar).toHaveClass(/is-open/)
   }
 }
 
-export async function loadLocalGraph(page: Page, path?: string): Promise<void> {
+export async function loadLocalGraph(page: Page, path: string): Promise<void> {
   await setMockedOpenDirPath(page, path);
-
+  
   const onboardingOpenButton = page.locator('strong:has-text("Choose a folder")')
 
   if (await onboardingOpenButton.isVisible()) {
     await onboardingOpenButton.click()
   } else {
-    await page.click('#left-menu.button')
+    console.log("No onboarding button, loading file manually")
     let sidebar = page.locator('#left-sidebar')
-    if (!/is-open/.test(await sidebar.getAttribute('class'))) {
+    if (!/is-open/.test(await sidebar.getAttribute('class') || '')) {
       await page.click('#left-menu.button')
       await expect(sidebar).toHaveClass(/is-open/)
     }
-
+    
     await page.click('#left-sidebar #repo-switch');
     await page.waitForSelector('#left-sidebar .dropdown-wrapper >> text="Add new graph"',
-      { state: 'visible', timeout: 5000 })
-
+    { state: 'visible', timeout: 5000 })
     await page.click('text=Add new graph')
-    await page.waitForSelector('strong:has-text("Choose a folder")',
-      { state: 'visible', timeout: 5000 })
-    await page.click('strong:has-text("Choose a folder")')
+    await page.waitForSelector('strong:has-text("Choose a folder")',{ state: 'visible', timeout: 5000 })
 
-    const skip = page.locator('a:has-text("Skip")')
-    await skip.click()
+    expect(page.locator('#repo-name')).toHaveText(pathlib.basename(path))
   }
 
   setMockedOpenDirPath(page, ''); // reset it
@@ -207,6 +204,14 @@ export async function loadLocalGraph(page: Page, path?: string): Promise<void> {
   }
 
   await page.waitForFunction('window.document.title === "Logseq"')
+  await page.waitForTimeout(500)
+
+  // If there is an error notification from a previous test graph being deleted,
+  // close it first so it doesn't cover up the UI
+  while (await (page.locator('.notification-close-button').first()?.isVisible())) {
+    await page.click('.notification-close-button')
+    await page.waitForTimeout(250)
+  }
 
   console.log('Graph loaded for ' + path)
 }

+ 2 - 2
package.json

@@ -5,7 +5,7 @@
     "main": "static/electron.js",
     "devDependencies": {
         "@capacitor/cli": "3.2.2",
-        "@playwright/test": "^1.19.2",
+        "@playwright/test": "^1.24.2",
         "@tailwindcss/ui": "0.7.2",
         "@types/gulp": "^4.0.7",
         "cross-env": "^7.0.3",
@@ -14,7 +14,7 @@
         "gulp": "^4.0.2",
         "gulp-clean-css": "^4.3.0",
         "npm-run-all": "^4.1.5",
-        "playwright": "^1.19.2",
+        "playwright": "^1.24.2",
         "postcss": "8.2.13",
         "postcss-cli": "8.3.1",
         "postcss-import": "^14.0.0",

+ 7 - 2
src/main/frontend/handler/editor.cljs

@@ -1940,6 +1940,9 @@
   (let [editing-block (when-let [editing-block (state/get-edit-block)]
                         (some-> (db/pull (:db/id editing-block))
                                 (assoc :block/content (state/get-edit-content))))
+        has-unsaved-edits (and editing-block
+                               (not= (:block/content (db/pull (:db/id editing-block)))
+                                     (state/get-edit-content)))
         target-block (or target-block editing-block)
         block (db/entity (:db/id target-block))
         page (if (:block/name block) block
@@ -1954,10 +1957,12 @@
 
                    :else
                    true)]
+    (when has-unsaved-edits
+      (outliner-tx/transact!
+        {:outliner-op :save-block}
+        (outliner-core/save-block! editing-block)))
     (outliner-tx/transact!
       {:outliner-op :insert-blocks}
-      (when editing-block
-        (outliner-core/save-block! editing-block))
       (when target-block
         (let [format (or (:block/format target-block) (state/get-preferred-format))
               blocks' (map (fn [block]

+ 1 - 1
src/main/frontend/ui.cljs

@@ -219,7 +219,7 @@
                                                                      :class color-class}
              content]]
            [:div.ml-4.flex-shrink-0.flex
-            [:button.inline-flex.text-gray-400.focus:outline-none.focus:text-gray-500.transition.ease-in-out.duration-150
+            [:button.inline-flex.text-gray-400.focus:outline-none.focus:text-gray-500.transition.ease-in-out.duration-150.notification-close-button
              {:on-click (fn []
                           (notification-handler/clear! uid))}
              [:svg.h-5.w-5

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 44 - 627
yarn.lock


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно