Files
MyNote/apps/desktop/tests/e2e/graph-render.spec.ts
hunter-dev c0ba8df9b6 perf(renderer): 整体优化响应速度 — rAF 合并编辑器刷新/自动保存缓存/粒子引擎空闲自停
同时: 不透明窗口 + 精简主题(8到2)、TabBar 简化、图谱宽松布局、MoreActions 层级修复
2026-09-10 00:41:24 +08:00

79 lines
3.9 KiB
TypeScript
Raw Permalink 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');
test('思维导图+知识图谱渲染验证(含可见性)', async () => {
const tmp = await fs.mkdtemp(nodePath.join(os.tmpdir(), 'hn-graph-fix-'));
const userData = nodePath.join(tmp, 'userdata');
const vault = nodePath.join(tmp, 'vault');
await fs.mkdir(userData, { recursive: true });
await fs.mkdir(vault, { recursive: true });
await fs.writeFile(nodePath.join(vault, 'doc1.md'), '---\ntitle: 文档一\nlinks:\n - doc2.md\n---\n# 文档一\n链接到 doc2');
await fs.writeFile(nodePath.join(vault, 'doc2.md'), '---\ntitle: 文档二\n---\n# 文档二\n内容');
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 });
await invoke('vault:switch', { root: vault });
await page.evaluate(() => (window as any).__STORE__.getState().loadTree());
await page.waitForTimeout(1000);
// Switch to graph view (default mode is mindmap)
await page.getByTitle('切换 编辑器/图谱').click();
await page.waitForTimeout(2000);
// Mindmap: verify SVG has non-zero size AND visible content
const mindmap = await page.evaluate(() => {
const svg = document.querySelector('.markmap-dark svg');
if (!svg) return { found: false };
const rect = svg.getBoundingClientRect();
const fo = svg.querySelectorAll('foreignObject').length;
const g = svg.querySelectorAll('g').length;
// Check that content is actually visible (has bounding boxes within the svg)
const visibleContent = Array.from(svg.querySelectorAll('g.markmap-node')).some((el) => {
const r = el.getBoundingClientRect();
return r.width > 0 && r.height > 0;
});
return { found: true, w: rect.width, h: rect.height, foreignObject: fo, g, visibleContent };
});
console.log('Mindmap:', JSON.stringify(mindmap));
expect(mindmap.found).toBe(true);
expect(mindmap.h).toBeGreaterThan(100); // svg must have real height
expect(mindmap.foreignObject).toBeGreaterThan(0);
expect(mindmap.visibleContent).toBe(true); // content must be visibly rendered
// Switch to knowledge graph mode
await page.getByRole('button', { name: '知识图谱' }).click();
await page.waitForTimeout(3000);
const graph = await page.evaluate(() => {
const svgs = document.querySelectorAll('svg');
let svg: SVGElement | null = null;
for (const s of svgs) { if (s.querySelectorAll('g[transform]').length > 0 || s.querySelectorAll('rect').length > 1) { svg = s; break; } }
if (!svg) return { found: false };
const rect = svg.getBoundingClientRect();
const rects = svg.querySelectorAll('rect').length;
const texts = svg.querySelectorAll('text').length;
const lines = svg.querySelectorAll('line').length;
const linkPaths = svg.querySelectorAll('path').length;
// Check a node card is visible within the svg
const visibleCard = Array.from(svg.querySelectorAll('rect')).some((r) => {
const b = r.getBoundingClientRect();
return b.width > 0 && b.height > 0;
});
return { found: true, w: rect.width, h: rect.height, rects, texts, lines, linkPaths, visibleCard };
});
console.log('Knowledge graph:', JSON.stringify(graph));
expect(graph.found).toBe(true);
expect(graph.h).toBeGreaterThan(100);
expect(graph.rects).toBeGreaterThanOrEqual(3); // 2 卡 rect + 1 背景 rect(demo 卡片无左侧色条)
expect(graph.linkPaths).toBeGreaterThanOrEqual(1); // 曲线连线为 path
expect(graph.visibleCard).toBe(true);
await app.close();
});