feat: add a secret global flag to load graph progammtically (#3531)

* feat: add a secret global flag to load graph from a user defined dir

* fix: use LOGSEQ_OVERWRITE_OPEN_DIR env var to overwrite the openning graph dir

* e2e: add a test for load & check saved graph data

* fix: should also pass in process.env for testing fixtures

* feat: new way to set open dir folder

* fix: e2e

* fix: remove playwright global flag check

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
This commit is contained in:
Peng Xiao
2022-01-05 21:05:05 +08:00
committed by GitHub
parent 9f8028d51b
commit 17b5cdb9e8
10 changed files with 108 additions and 17 deletions

1
.gitignore vendored
View File

@@ -13,6 +13,7 @@ pom.xml.asc
node_modules/
static/
tmp
.cpcache/
/src/gen

View File

@@ -1,5 +1,7 @@
import { expect } from '@playwright/test'
import { test } from './fixtures'
import fs from 'fs/promises'
import path from 'path'
import { test, graphDir } from './fixtures'
import { randomString, createRandomPage, newBlock } from './utils'
@@ -41,7 +43,7 @@ test('search', async ({ page }) => {
})
test('create page and blocks', async ({ page }) => {
await createRandomPage(page)
const pageTitle = await createRandomPage(page)
// do editing
await page.fill(':nth-match(textarea, 1)', 'this is my first bullet')
@@ -81,6 +83,21 @@ test('create page and blocks', async ({ page }) => {
await page.keyboard.press('Escape')
await page.waitForTimeout(500)
expect(await page.$$('.ls-block')).toHaveLength(5)
await page.waitForTimeout(500)
const contentOnDisk = await fs.readFile(
path.join(graphDir, `pages/${pageTitle}.md`),
'utf8'
)
expect(contentOnDisk.trim()).toEqual(`
- this is my first bullet
- this is my second bullet
- this is my third bullet
- continue editing test
continue
- test ok`.trim())
})
test('delete and backspace', async ({ page }) => {

View File

@@ -1,9 +1,14 @@
import fs from 'fs'
import path from 'path'
import { test as base, expect, ConsoleMessage } from '@playwright/test';
import { ElectronApplication, Page, BrowserContext, _electron as electron } from 'playwright'
import { loadLocalGraph, randomString } from './utils';
let electronApp: ElectronApplication
let context: BrowserContext
let page: Page
let repoName = randomString(10)
export let graphDir = path.resolve(__dirname, '../tmp/e2e-graph', repoName)
// NOTE: This is a console log watcher for error logs.
const consoleLogWatcher = (msg: ConsoleMessage) => {
@@ -19,9 +24,14 @@ base.beforeAll(async () => {
return
}
fs.mkdirSync(graphDir, {
recursive: true,
});
electronApp = await electron.launch({
cwd: "./static",
args: ["electron.js"],
locale: 'en',
})
context = electronApp.context()
await context.tracing.start({ screenshots: true, snapshots: true });
@@ -51,6 +61,8 @@ base.beforeAll(async () => {
console.log('Page loaded!')
await page.screenshot({ path: 'startup.png' })
})
await loadLocalGraph(page, graphDir);
})
base.beforeEach(async () => {

View File

@@ -33,6 +33,8 @@ export async function createRandomPage(page: Page) {
await page.click('text=/.*New page: ".*/')
// wait for textarea of first block
await page.waitForSelector(':nth-match(textarea, 1)', { state: 'visible' })
return randomTitle;
}
/**
@@ -101,6 +103,48 @@ export async function escapeToBlockEditor(page: Page): Promise<void> {
await page.waitForTimeout(500)
}
export async function setMockedOpenDirPath(
page: Page,
path?: string
): Promise<void> {
// set next open directory
await page.evaluate(
([path]) => {
Object.assign(window, {
__MOCKED_OPEN_DIR_PATH__: path,
})
},
[path]
)
}
export async function loadLocalGraph(page: Page, path?: string): Promise<void> {
const hasOpenButton = await page.$('#head >> .button >> text=Open')
await setMockedOpenDirPath(page, path);
if (hasOpenButton) {
await page.click('#head >> .button >> text=Open')
} else {
if (!(await page.$('.ls-left-sidebar-open'))) {
await page.click('.cp__header-left-menu.button')
}
await page.click('#left-sidebar >> #repo-switch')
await page.click('text=Add new graph')
await page.waitForSelector('h1:has-text("Open a local directory")')
await page.click('h1:has-text("Open a local directory")')
}
setMockedOpenDirPath(page, ''); // reset it
await page.waitForSelector(':has-text("Parsing files")', {
state: 'hidden',
timeout: 1000 * 60 * 5,
})
await page.waitForFunction('window.document.title != "Loading"')
console.log('Graph loaded for ' + path)
}
export async function activateNewPage(page: Page) {
await page.click('.ls-block >> nth=0')
await page.waitForTimeout(500)

View File

@@ -83,13 +83,14 @@ contextBridge.exposeInMainWorld('apis', {
*
* @param {string} html html file with embedded state
*/
exportPublishAssets (html, customCSSPath, repoPath, assetFilenames) {
exportPublishAssets (html, customCSSPath, repoPath, assetFilenames, outputDir) {
ipcRenderer.invoke(
'export-publish-assets',
html,
customCSSPath,
repoPath,
assetFilenames
assetFilenames,
outputDir
)
},

View File

@@ -68,12 +68,10 @@
(.unregisterProtocol protocol LSP_SCHEME)
(.unregisterProtocol protocol "assets")))
(defn- handle-export-publish-assets [_event html custom-css-path repo-path asset-filenames]
(defn- handle-export-publish-assets [_event html custom-css-path repo-path asset-filenames output-path]
(p/let [app-path (. app getAppPath)
asset-filenames (js->clj asset-filenames)
result (. dialog showOpenDialog (clj->js {:properties ["openDirectory" "createDirectory" "promptToCreate", "multiSelections"]}))
result (get (js->clj result) "filePaths")
root-dir (first result)]
root-dir (or output-path (handler/open-dir-dialog))]
(when root-dir
(let [static-dir (path/join root-dir "static")
assets-from-dir (path/join repo-path "assets")

View File

@@ -139,11 +139,14 @@
(remove nil?))]
(vec (cons {:path (utils/fix-win-path! path)} result))))
(defmethod handle :openDir [^js window _messages]
(defn open-dir-dialog []
(p/let [result (.showOpenDialog dialog (bean/->js
{:properties ["openDirectory" "createDirectory" "promptToCreate"]}))
result (get (js->clj result) "filePaths")
path (first result)]
result (get (js->clj result) "filePaths")]
(p/resolved (first result))))
(defmethod handle :openDir [^js window _messages]
(p/let [path (open-dir-dialog)]
(if path
(p/resolved (bean/->js (get-files path)))
(p/rejected (js/Error "path empty")))))
@@ -269,10 +272,7 @@
(watcher/watch-dir! window dir)))
(defmethod handle :openDialog [^js window messages]
(p/let [result (.showOpenDialog dialog (bean/->js
{:properties ["openDirectory"]}))
result (get (js->clj result) "filePaths")]
(p/resolved (first result))))
(open-dir-dialog))
(defmethod handle :getLogseqDotDirRoot []
(utils/get-ls-dotdir-root))

View File

@@ -92,6 +92,13 @@
(error-handler error)
(log/error :write-file-failed error)))))))))
(defn- open-dir []
(p/let [dir-path (util/mocked-open-dir-path)
result (if dir-path
(ipc/ipc "getFiles" dir-path)
(ipc/ipc "openDir" {}))]
result))
(defrecord Node []
protocol/Fs
(mkdir! [this dir]
@@ -124,7 +131,7 @@
(let [path (concat-path dir path)]
(ipc/ipc "stat" path)))
(open-dir [this ok-handler]
(ipc/ipc "openDir" {}))
(open-dir))
(get-files [this path-or-handle ok-handler]
(ipc/ipc "getFiles" path-or-handle))
(watch-dir! [this dir]

View File

@@ -106,7 +106,12 @@
html-str (str "data:text/html;charset=UTF-8,"
(js/encodeURIComponent raw-html-str))]
(if (util/electron?)
(js/window.apis.exportPublishAssets raw-html-str (config/get-custom-css-path) (config/get-repo-dir repo) (clj->js asset-filenames))
(js/window.apis.exportPublishAssets
raw-html-str
(config/get-custom-css-path)
(config/get-repo-dir repo)
(clj->js asset-filenames)
(util/mocked-open-dir-path))
(when-let [anchor (gdom/getElement "download-as-html")]
(.setAttribute anchor "href" html-str)

View File

@@ -71,6 +71,12 @@
(let [ua (string/lower-case js/navigator.userAgent)]
(string/includes? ua " electron")))))
#?(:cljs
(defn mocked-open-dir-path
"Mocked open DIR path for by-passing open dir in electron during testing. Nil if not given"
[]
(when (electron?) (. js/window -__MOCKED_OPEN_DIR_PATH__))))
#?(:cljs
(def nfs? (and (not (electron?))
(not (is-native-platform?)))))