obsidian-testing-framework 0.4.9 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/fixtures.d.ts +6 -3
- package/lib/index.d.ts +23 -4
- package/lib/index.js +96 -71
- package/lib/internal-util.d.ts +5 -2
- package/lib/internal-util.js +38 -17
- package/lib/setup.d.ts +1 -1
- package/lib/setup.js +38 -6
- package/package.json +3 -1
package/lib/fixtures.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Browser, JSHandle, Page } from "playwright";
|
|
2
2
|
import { ObsidianTestingConfig } from "./index.js";
|
|
3
3
|
import { App } from "obsidian";
|
|
4
4
|
export interface ObsidianTestFixtures {
|
|
5
|
-
electronApp:
|
|
5
|
+
electronApp: Browser;
|
|
6
6
|
page: Page;
|
|
7
7
|
obsidian: ObsidianTestingConfig;
|
|
8
|
-
|
|
8
|
+
___internal: {
|
|
9
|
+
vaultId: string;
|
|
10
|
+
release: () => Promise<void>;
|
|
11
|
+
};
|
|
9
12
|
appHandle: JSHandle<App>;
|
|
10
13
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ObsidianTestFixtures } from "./fixtures.js";
|
|
2
1
|
import { Concurrency } from "./internal-util.js";
|
|
3
2
|
export interface ObsidianTestingConfig {
|
|
4
3
|
vaultPoolDir?: string;
|
|
@@ -6,8 +5,28 @@ export interface ObsidianTestingConfig {
|
|
|
6
5
|
obsidianPath?: string;
|
|
7
6
|
concurrent?: Concurrency;
|
|
8
7
|
}
|
|
9
|
-
export declare const test: import("vitest").TestAPI<Omit<object, "$
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
export declare const test: import("vitest").TestAPI<Omit<Omit<Omit<object, "$__file"> & Record<"___internal", {
|
|
9
|
+
vaultId: string;
|
|
10
|
+
release: () => Promise<void>;
|
|
11
|
+
}> & {
|
|
12
|
+
readonly $__worker?: unknown;
|
|
13
|
+
readonly $__file?: Record<"___internal", {
|
|
14
|
+
vaultId: string;
|
|
15
|
+
release: () => Promise<void>;
|
|
16
|
+
}>;
|
|
12
17
|
readonly $__test?: unknown;
|
|
18
|
+
}, "$__file"> & Record<"electronApp", import("playwright-core").Browser> & {
|
|
19
|
+
readonly $__worker?: unknown;
|
|
20
|
+
readonly $__file?: Record<"___internal", {
|
|
21
|
+
vaultId: string;
|
|
22
|
+
release: () => Promise<void>;
|
|
23
|
+
}> & Record<"electronApp", import("playwright-core").Browser>;
|
|
24
|
+
readonly $__test?: unknown;
|
|
25
|
+
}, "$__test"> & Record<"page", import("playwright-core").Page> & {
|
|
26
|
+
readonly $__worker?: unknown;
|
|
27
|
+
readonly $__file?: Record<"___internal", {
|
|
28
|
+
vaultId: string;
|
|
29
|
+
release: () => Promise<void>;
|
|
30
|
+
}> & Record<"electronApp", import("playwright-core").Browser>;
|
|
31
|
+
readonly $__test?: Record<"page", import("playwright-core").Page>;
|
|
13
32
|
}>;
|
package/lib/index.js
CHANGED
|
@@ -1,76 +1,101 @@
|
|
|
1
1
|
import { test as base, inject } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import { chromium } from "playwright";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { readFileSync
|
|
5
|
-
import { findConfig, generateVaultConfig } from "./internal-util.js";
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
|
+
import { findConfig, generateVaultConfig, addConsoleListener, getAsar, } from "./internal-util.js";
|
|
6
6
|
import { pageUtils, waitForIndexingComplete } from "./util.js";
|
|
7
7
|
import { randomBytes } from "crypto";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
8
|
+
import { retryUntilTruthy, ipcRendererSend } from "electron-playwright-helpers";
|
|
9
|
+
export const test = base
|
|
10
|
+
.extend("___internal", { auto: true, scope: "file" }, async ({}, {}) => {
|
|
11
|
+
const concurrent = inject("concurrent") ?? "copy";
|
|
12
|
+
const vault = inject("vault");
|
|
13
|
+
const vaultPoolDir = inject("vaultPoolDir");
|
|
14
|
+
const vaultId = randomBytes(8).toString("hex").toLocaleLowerCase();
|
|
15
|
+
console.debug("about to lock");
|
|
16
|
+
const release = async () => { };
|
|
17
|
+
console.debug("lock acquired !");
|
|
18
|
+
await generateVaultConfig(vault, vaultId, concurrent, vaultPoolDir);
|
|
19
|
+
return { vaultId, release };
|
|
20
|
+
})
|
|
21
|
+
.extend("electronApp", { auto: true, scope: "file" }, async ({ ___internal: { vaultId } }, { onCleanup }) => {
|
|
22
|
+
const obsidianPath = inject("obsidianPath") ?? undefined;
|
|
23
|
+
const vaultPoolDir = inject("vaultPoolDir");
|
|
24
|
+
console.log("asar located at:", getAsar(obsidianPath));
|
|
25
|
+
const tmp = JSON.parse(readFileSync(path.join(findConfig(), "obsidian.json")).toString());
|
|
26
|
+
console.log("vaultid", vaultId, vaultId in tmp.vaults);
|
|
27
|
+
const dbgInfo = await fetch("http://localhost:9222/json/version").then((res) => res.json());
|
|
28
|
+
console.log("dbgInfo", dbgInfo);
|
|
29
|
+
const browser = await chromium.connectOverCDP(dbgInfo.webSocketDebuggerUrl, {
|
|
30
|
+
isLocal: true,
|
|
31
|
+
slowMo: 100,
|
|
32
|
+
});
|
|
33
|
+
console.log("app launched");
|
|
34
|
+
addConsoleListener(browser);
|
|
35
|
+
console.log("ctx", browser.contexts().length);
|
|
36
|
+
const ctx = browser.contexts()[0];
|
|
37
|
+
const titles = await Promise.all(ctx.pages().map((p) => p.title()));
|
|
38
|
+
const page = ctx.pages().find((_, i) => titles[i] === "Obsidian");
|
|
39
|
+
await ipcRendererSend(page, "vault-open", path.join(vaultPoolDir, `vault-${vaultId}`), false);
|
|
40
|
+
console.log("dialogs restored");
|
|
41
|
+
{
|
|
42
|
+
const page = await retryUntilTruthy(async () => {
|
|
43
|
+
const pages = ctx.pages();
|
|
44
|
+
console.log("finding", vaultId);
|
|
45
|
+
console.log("num windows", pages.length);
|
|
46
|
+
console.log("page titles", await Promise.all(pages.map((w) => w.title())));
|
|
47
|
+
const titles = await Promise.all(pages.map((w) => w.title()));
|
|
48
|
+
const idx = titles.findIndex((t) => t.includes(`vault-${vaultId}`));
|
|
49
|
+
console.log("idx", idx);
|
|
50
|
+
return pages[idx];
|
|
51
|
+
});
|
|
52
|
+
await page.waitForLoadState("domcontentloaded");
|
|
53
|
+
await page.waitForSelector(".modal-button-container", {
|
|
54
|
+
state: "attached",
|
|
55
|
+
});
|
|
56
|
+
const mbc = page.locator(".modal-button-container");
|
|
57
|
+
await mbc.locator("button").first().click();
|
|
58
|
+
const focusedElementHandle = await page.evaluateHandle(() => document.activeElement);
|
|
59
|
+
await focusedElementHandle.press("Escape");
|
|
60
|
+
console.log("esc pressed");
|
|
61
|
+
try {
|
|
62
|
+
await waitForIndexingComplete(page);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
console.warn("timed out waiting for metadata cache. continuing...");
|
|
66
|
+
}
|
|
67
|
+
for (let fn of Object.entries(pageUtils)) {
|
|
68
|
+
await page.exposeFunction(fn[0], fn[1]);
|
|
69
|
+
}
|
|
70
|
+
page.on("pageerror", (exc) => {
|
|
71
|
+
console.error("EXCEPTION");
|
|
72
|
+
console.error(exc);
|
|
73
|
+
});
|
|
74
|
+
page.on("console", async (msg) => {
|
|
75
|
+
console.log(...(await Promise.all(msg.args().map((a) => a.jsonValue()))));
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
console.debug("[electronApp] running tests");
|
|
79
|
+
onCleanup(async () => {
|
|
80
|
+
const titles = await Promise.all(ctx.pages().map((p) => p.title()));
|
|
81
|
+
const idx = titles.findIndex((t) => t.includes(`vault-${vaultId}`));
|
|
82
|
+
const page = ctx.pages()[idx];
|
|
83
|
+
await page.close();
|
|
84
|
+
});
|
|
85
|
+
return browser;
|
|
86
|
+
})
|
|
87
|
+
.extend("page", { auto: true }, async ({ electronApp, ___internal: { vaultId } }, {}) => {
|
|
88
|
+
let page = await retryUntilTruthy(async () => {
|
|
89
|
+
const ctx = electronApp.contexts()[0];
|
|
90
|
+
const pages = ctx.pages();
|
|
91
|
+
console.log("finding", vaultId);
|
|
92
|
+
console.log("num windows", pages.length);
|
|
93
|
+
console.log("page titles", await Promise.all(pages.map((w) => w.title())));
|
|
94
|
+
const titles = await Promise.all(pages.map((w) => w.title()));
|
|
95
|
+
const idx = titles.findIndex((t) => t.includes(`vault-${vaultId}`));
|
|
96
|
+
console.log("idx", idx);
|
|
97
|
+
return pages[idx];
|
|
98
|
+
});
|
|
99
|
+
console.debug("[page] running tests @", vaultId);
|
|
100
|
+
return page;
|
|
76
101
|
});
|
package/lib/internal-util.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Browser } from "playwright";
|
|
2
2
|
export type ConfigJson = {
|
|
3
3
|
vaults: {
|
|
4
4
|
[key: string]: {
|
|
@@ -10,7 +10,10 @@ export type ConfigJson = {
|
|
|
10
10
|
};
|
|
11
11
|
export type Concurrency = false | "copy" | "symlink";
|
|
12
12
|
export declare function checkToy(): void;
|
|
13
|
+
export declare function getAsar(obsidianPath?: string): string;
|
|
13
14
|
export declare function getExe(obsidianPath?: string): string;
|
|
14
|
-
export declare function addConsoleListener(app:
|
|
15
|
+
export declare function addConsoleListener(app: Browser): void;
|
|
15
16
|
export declare function findConfig(): any;
|
|
16
17
|
export declare function generateVaultConfig(vault: string, vaultHash: string, concurrent: Concurrency, vaultPoolDir: string): Promise<string>;
|
|
18
|
+
export declare function sleep(ms: number): Promise<unknown>;
|
|
19
|
+
export declare function timeout<T, A extends any[]>(fn: (...args: A) => Promise<T>, ms: number, ...args: A): Promise<T>;
|
package/lib/internal-util.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
3
|
-
import { cp, readFile,
|
|
4
|
-
import { lock } from "proper-lockfile";
|
|
3
|
+
import { cp, readFile, rm } from "fs/promises";
|
|
5
4
|
import symlinkDir from "symlink-dir";
|
|
6
5
|
export function checkToy() {
|
|
7
6
|
if (process.platform == "darwin") {
|
|
8
7
|
throw new Error("use a non-toy operating system, dumbass");
|
|
9
8
|
}
|
|
10
9
|
}
|
|
11
|
-
export function
|
|
10
|
+
export function getAsar(obsidianPath) {
|
|
12
11
|
checkToy();
|
|
12
|
+
const asarName = "app.asar";
|
|
13
13
|
if (obsidianPath) {
|
|
14
14
|
return path.join(obsidianPath, "Resources", "app.asar");
|
|
15
15
|
}
|
|
16
16
|
if (process.platform == "win32") {
|
|
17
|
-
let p = path.join(process.env.LOCALAPPDATA, "Obsidian", "Resources",
|
|
17
|
+
let p = path.join(process.env.LOCALAPPDATA, "Obsidian", "Resources", asarName);
|
|
18
18
|
if (existsSync(p)) {
|
|
19
19
|
return p;
|
|
20
20
|
}
|
|
21
|
-
p = path.join(process.env.PROGRAMFILES, "Obsidian", "Resources",
|
|
21
|
+
p = path.join(process.env.PROGRAMFILES, "Obsidian", "Resources", asarName);
|
|
22
22
|
if (existsSync(p)) {
|
|
23
23
|
return p;
|
|
24
24
|
}
|
|
@@ -34,14 +34,21 @@ export function getExe(obsidianPath) {
|
|
|
34
34
|
for (let i = 0; i < possibleDirs.length; i++) {
|
|
35
35
|
if (existsSync(possibleDirs[i])) {
|
|
36
36
|
// console.log(execSync(`ls -l ${possibleDirs[i]}`).toString());
|
|
37
|
-
return path.join(possibleDirs[i], "resources",
|
|
37
|
+
return path.join(possibleDirs[i], "resources", asarName);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
return "";
|
|
41
41
|
}
|
|
42
|
+
export function getExe(obsidianPath) {
|
|
43
|
+
const dirname = path.dirname(getAsar(obsidianPath));
|
|
44
|
+
let filename = process.platform == "win32" ? "Obsidian.exe" : "obsidian";
|
|
45
|
+
return path.normalize(path.join(dirname, "..", filename));
|
|
46
|
+
}
|
|
42
47
|
export function addConsoleListener(app) {
|
|
43
|
-
app.
|
|
44
|
-
|
|
48
|
+
app.contexts().forEach(context => {
|
|
49
|
+
context.on("console", async (msg) => {
|
|
50
|
+
console.log(...(await Promise.all(msg.args().map((a) => a.jsonValue()))));
|
|
51
|
+
});
|
|
45
52
|
});
|
|
46
53
|
}
|
|
47
54
|
export function findConfig() {
|
|
@@ -66,35 +73,32 @@ export async function generateVaultConfig(vault, vaultHash, concurrent, vaultPoo
|
|
|
66
73
|
if (!existsSync(obsidianConfigFile)) {
|
|
67
74
|
writeFileSync(obsidianConfigFile, JSON.stringify({ vaults: {} }));
|
|
68
75
|
}
|
|
69
|
-
let releaser;
|
|
70
|
-
releaser = await lock(obsidianConfigFile, {
|
|
71
|
-
retries: 5,
|
|
72
|
-
});
|
|
73
76
|
try {
|
|
74
77
|
const json = JSON.parse((await readFile(obsidianConfigFile)).toString());
|
|
75
78
|
const hasVault = Object.values(json.vaults).some((a) => a.path === vault) && !concurrent;
|
|
79
|
+
console.log("vpd", vaultPoolDir);
|
|
76
80
|
if (concurrent === "symlink") {
|
|
77
81
|
await symlinkDir(vault, path.join(vaultPoolDir, `vault-${vaultHash}`));
|
|
78
82
|
}
|
|
79
83
|
else if (concurrent === "copy") {
|
|
80
84
|
await cp(vault, path.join(vaultPoolDir, `vault-${vaultHash}`), { recursive: true });
|
|
81
85
|
}
|
|
86
|
+
if (concurrent) {
|
|
87
|
+
await rm(path.join(vaultPoolDir, `vault-${vaultHash}`, ".obsidian/workspace.json"));
|
|
88
|
+
}
|
|
82
89
|
if (!hasVault) {
|
|
83
90
|
json.vaults[vaultHash] = {
|
|
84
91
|
path: concurrent ? path.join(vaultPoolDir, `vault-${vaultHash}`) : vault,
|
|
85
92
|
ts: Date.now(),
|
|
86
93
|
};
|
|
87
|
-
await writeFile(obsidianConfigFile, JSON.stringify(json, null, "\t"));
|
|
88
|
-
await writeFile(path.join(configLocation, `${vaultHash}.json`), "{}");
|
|
94
|
+
// await writeFile(obsidianConfigFile, JSON.stringify(json, null, "\t"));
|
|
95
|
+
// await writeFile(path.join(configLocation, `${vaultHash}.json`), "{}");
|
|
89
96
|
}
|
|
90
97
|
}
|
|
91
98
|
catch (err) {
|
|
92
99
|
console.error("error generating vault config", err);
|
|
93
100
|
throw err;
|
|
94
101
|
}
|
|
95
|
-
finally {
|
|
96
|
-
await releaser();
|
|
97
|
-
}
|
|
98
102
|
const json = JSON.parse((await readFile(obsidianConfigFile)).toString());
|
|
99
103
|
const hasVault = Object.values(json.vaults).some((a) => a.path === vault);
|
|
100
104
|
if (hasVault) {
|
|
@@ -102,3 +106,20 @@ export async function generateVaultConfig(vault, vaultHash, concurrent, vaultPoo
|
|
|
102
106
|
}
|
|
103
107
|
return vaultHash;
|
|
104
108
|
}
|
|
109
|
+
export async function sleep(ms) {
|
|
110
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
111
|
+
}
|
|
112
|
+
export async function timeout(fn, ms, ...args) {
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
const timeout = setTimeout(() => {
|
|
115
|
+
reject(new Error(`timeout after ${ms}ms`));
|
|
116
|
+
}, ms);
|
|
117
|
+
fn(...args).then((result) => {
|
|
118
|
+
clearTimeout(timeout);
|
|
119
|
+
resolve(result);
|
|
120
|
+
}).catch((err) => {
|
|
121
|
+
clearTimeout(timeout);
|
|
122
|
+
reject(err);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
package/lib/setup.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { TestProject } from "vitest/node";
|
|
2
|
-
export default function setup(project: TestProject): () => Promise<void
|
|
2
|
+
export default function setup(project: TestProject): Promise<() => Promise<void>>;
|
package/lib/setup.js
CHANGED
|
@@ -1,22 +1,54 @@
|
|
|
1
|
+
import { _electron as electron } from "playwright";
|
|
1
2
|
import path from "path";
|
|
2
3
|
import os from "os";
|
|
3
|
-
import { mkdtempSync, rmdirSync, readFileSync, writeFileSync } from "fs";
|
|
4
|
-
import { findConfig } from "./internal-util.js";
|
|
5
|
-
export default function setup(project) {
|
|
4
|
+
import { mkdtempSync, rmdirSync, readFileSync, writeFileSync, unlinkSync, } from "fs";
|
|
5
|
+
import { findConfig, getAsar } from "./internal-util.js";
|
|
6
|
+
export default async function setup(project) {
|
|
6
7
|
const concurrent = project.config.provide.concurrent ?? "copy";
|
|
7
8
|
if (!concurrent) {
|
|
8
9
|
return async () => { };
|
|
9
10
|
}
|
|
10
|
-
const prefix =
|
|
11
|
-
const
|
|
11
|
+
const prefix = "obsidian-testing-framework-vault-pool-";
|
|
12
|
+
const fullPrefix = path.join(os.tmpdir(), prefix);
|
|
13
|
+
const vaultPoolDir = mkdtempSync(fullPrefix);
|
|
12
14
|
project.provide("vaultPoolDir", vaultPoolDir);
|
|
15
|
+
project.globTestFiles;
|
|
13
16
|
console.log("BEFORE", vaultPoolDir);
|
|
17
|
+
const launch = async () => {
|
|
18
|
+
return await electron.launch({
|
|
19
|
+
timeout: 60000,
|
|
20
|
+
args: [
|
|
21
|
+
getAsar(project.config.provide.obsidianPath),
|
|
22
|
+
"--remote-debugging-address=0.0.0.0",
|
|
23
|
+
"--remote-debugging-port=9222",
|
|
24
|
+
"--",
|
|
25
|
+
"obsidian://choose-vault",
|
|
26
|
+
].filter((a) => !!a),
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
let app = await launch();
|
|
30
|
+
project.onTestsRerun(async () => {
|
|
31
|
+
await app.close();
|
|
32
|
+
app = await launch();
|
|
33
|
+
});
|
|
14
34
|
return async () => {
|
|
15
35
|
console.log("AFTER");
|
|
36
|
+
await app.close();
|
|
16
37
|
rmdirSync(vaultPoolDir, { recursive: true });
|
|
17
38
|
const configFile = path.join(findConfig(), "obsidian.json");
|
|
18
39
|
const json = JSON.parse(readFileSync(configFile).toString());
|
|
19
|
-
const filtered = Object.fromEntries(Object.entries(json.vaults).filter(([, v]) => !v.path.includes(
|
|
40
|
+
const filtered = Object.fromEntries(Object.entries(json.vaults).filter(([, v]) => !v.path.includes(fullPrefix)));
|
|
41
|
+
const toRemove = Object.entries(json.vaults)
|
|
42
|
+
.filter(([, v]) => v.path.includes(prefix))
|
|
43
|
+
.map(([k]) => k);
|
|
20
44
|
writeFileSync(configFile, JSON.stringify({ vaults: filtered }));
|
|
45
|
+
for (const vault of toRemove) {
|
|
46
|
+
try {
|
|
47
|
+
unlinkSync(path.join(findConfig(), `${vault}.json`));
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
21
53
|
};
|
|
22
54
|
}
|
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"asar": "^3.2.0",
|
|
11
11
|
"async-mutex": "^0.5.0",
|
|
12
12
|
"electron": "^33.0.2",
|
|
13
|
+
"electron-playwright-helpers": "^2.1.0",
|
|
13
14
|
"obsidian": "latest",
|
|
14
15
|
"playwright": "^1.58.2",
|
|
15
16
|
"proper-lockfile": "^4.1.2",
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
".": "./lib/index.js"
|
|
30
31
|
},
|
|
31
32
|
"readme": "",
|
|
32
|
-
"version": "0.
|
|
33
|
+
"version": "0.5.0",
|
|
33
34
|
"main": "./lib/index.js",
|
|
34
35
|
"typings": "./lib/index.d.ts",
|
|
35
36
|
"repository": {
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@types/proper-lockfile": "^4",
|
|
47
48
|
"@types/tmp": "^0",
|
|
49
|
+
"playwright-core": "^1.58.2",
|
|
48
50
|
"rimraf": "^6.0.1",
|
|
49
51
|
"vitest": "^4.1.0"
|
|
50
52
|
}
|