Files
MyNote/apps/desktop/tests/e2e/safety.spec.ts
T

90 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test';
import { _electron as electron } from 'playwright';
import { promises as fs } from 'node:fs';
import nodePath from 'node:path';
import os from 'node:os';
const MAIN_JS = nodePath.join(process.cwd(), 'dist-electron/main/index.js');
async function launch(userData: string) {
const app = await electron.launch({ args: ['--user-data-dir=' + userData, MAIN_JS] });
const page = await app.firstWindow();
await page.waitForLoadState('domcontentloaded');
const invoke = (ch: string, args: any) => page.evaluate(({ ch, args }) => (globalThis as any).dsh.invoke(ch, args), { ch, args });
return { app, page, invoke };
}
test('FR-T7:重命名文档后标签页路径同步', async () => {
const tmp = await fs.mkdtemp(nodePath.join(os.tmpdir(), 'hn-t7-'));
const userData = nodePath.join(tmp, 'userdata');
const vault = nodePath.join(tmp, 'vault');
await fs.mkdir(userData, { recursive: true });
await fs.mkdir(vault, { recursive: true });
const a = await launch(userData);
await a.invoke('vault:switch', { root: vault });
// 新建文档「原稿」并打开 → 标签页出现
await a.page.getByRole('button', { name: /新建文档/ }).click();
await a.page.getByPlaceholder(/输入文档标题/).fill('原稿');
await a.page.getByPlaceholder(/输入文档标题/).press('Enter');
await expect(a.page.getByTestId('tabbar').getByText('原稿', { exact: true })).toBeVisible({ timeout: 10000 });
// 文件树悬停「原稿」→ 点重命名 → 输入「改稿」→ 回车
await a.page.getByTestId('filetree').getByText('原稿', { exact: true }).hover();
await a.page.getByTestId('filetree').getByTitle('重命名').click();
// 重命名 input 是 filetree 内唯一的 input(搜索框在 filetree 外)
const renameInput = a.page.getByTestId('filetree').locator('input');
await renameInput.fill('改稿');
await renameInput.press('Enter');
// 标签页文本应从「原稿」变为「改稿」(路径已同步)
await expect(a.page.getByTestId('tabbar').getByText('改稿', { exact: true })).toBeVisible({ timeout: 10000 });
// 「原稿」标签页文本应消失
await expect(a.page.getByTestId('tabbar').getByText('原稿', { exact: true })).toHaveCount(0);
await a.app.close();
});
test('FR-V5+V6:设置页切换默认库路径 + 切库清空标签页', async () => {
const tmp = await fs.mkdtemp(nodePath.join(os.tmpdir(), 'hn-v56-'));
const userData = nodePath.join(tmp, 'userdata');
const vault1 = nodePath.join(tmp, 'vault1');
const vault2 = nodePath.join(tmp, 'vault2');
await fs.mkdir(userData, { recursive: true });
await fs.mkdir(vault1, { recursive: true });
await fs.mkdir(vault2, { recursive: true });
const a = await launch(userData);
await a.invoke('vault:switch', { root: vault1 });
// 在 vault1 新建并打开文档 → 标签页出现
await a.page.getByRole('button', { name: /新建文档/ }).click();
await a.page.getByPlaceholder(/输入文档标题/).fill('库1文档');
await a.page.getByPlaceholder(/输入文档标题/).press('Enter');
await expect(a.page.getByTestId('tabbar').getByText('库1文档', { exact: true })).toBeVisible({ timeout: 10000 });
// 设置 → 文件路径页 → 填入 vault2 路径 → 立即切换
await a.page.getByTitle('设置').click();
await a.page.getByRole('button', { name: '文件路径' }).click();
await a.page.getByPlaceholder(/填写或浏览/).fill(vault2);
await a.page.getByRole('button', { name: '立即切换' }).click();
// 等待切换完成
await expect(a.page.getByText(/已切换/)).toBeVisible({ timeout: 10000 });
// FR-V6:标签页应被清空(TabBar 返回 null → DOM 中无 tabbar)
await expect(a.page.getByTestId('tabbar')).toHaveCount(0);
// FR-V5:库元数据应更新为 vault2
const meta: { currentRoot: string } = await a.invoke('vault:list', null);
expect(meta.currentRoot).toBe(vault2);
// 关闭设置面板(点击遮罩层),在 vault2 新建文档应正常工作
await a.page.mouse.click(5, 5);
await a.page.getByRole('button', { name: /新建文档/ }).click();
await a.page.getByPlaceholder(/输入文档标题/).fill('库2文档');
await a.page.getByPlaceholder(/输入文档标题/).press('Enter');
await expect(a.page.getByTestId('tabbar').getByText('库2文档', { exact: true })).toBeVisible({ timeout: 10000 });
await a.app.close();
});