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

67 lines
3.1 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';
import zlib from 'node:zlib';
const MAIN_JS = nodePath.join(process.cwd(), 'dist-electron/main/index.js');
// 生成 1x1 RGB PNG(避免依赖图像库)
function crc32(buf: Buffer): number {
let c = ~0;
for (let i = 0; i < buf.length; i++) { c ^= buf[i]; for (let j = 0; j < 8; j++) c = (c >>> 1) ^ (0xedb88320 & -(c & 1)); }
return ~c >>> 0;
}
function makePng(r: number, g: number, b: number): Buffer {
const sig = Buffer.from([0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a]);
const ihdr = Buffer.from([0,0,0,1, 0,0,0,1, 8, 2, 0, 0, 0]); // 1x1, 8bit, RGB
const idatRaw = Buffer.from([0, r, g, b]);
const idat = zlib.deflateSync(idatRaw);
const chunk = (type: string, data: Buffer) => {
const t = Buffer.from(type, 'ascii'); const len = Buffer.alloc(4); len.writeUInt32BE(data.length, 0);
const crc = Buffer.alloc(4); crc.writeUInt32BE(crc32(Buffer.concat([t, data])), 0);
return Buffer.concat([len, t, data, crc]);
};
return Buffer.concat([sig, chunk('IHDR', ihdr.subarray(0,13)), chunk('IDAT', idat), chunk('IEND', Buffer.alloc(0))]);
}
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-A8/A9)', async () => {
const tmp = await fs.mkdtemp(nodePath.join(os.tmpdir(), 'hn-bg-'));
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 pngPath = nodePath.join(tmp, 'white.png');
await fs.writeFile(pngPath, makePng(255, 255, 255)); // 纯白 → 智能取色 mode=light, blur=12
// 上传背景图 + 保存
const a1 = await launch(userData);
await a1.invoke('vault:switch', { root: vault });
await a1.page.getByTitle('外观定制').click();
await a1.page.locator('input[type="file"]').setInputFiles(pngPath);
// 智能取色:白图 → blurPx 12(午夜蓝默认 16)
await expect(a1.page.locator('img[alt="bg"]')).toBeVisible({ timeout: 10000 });
await a1.page.getByRole('button', { name: '保存外观' }).click();
await expect(a1.page.getByText('外观定制').first()).toBeHidden();
await a1.app.close();
// 重开:恢复背景图 + 智能取色结果
const a2 = await launch(userData);
const cfg: { bgImage: string | null } | null = await a2.invoke('appearance:load', null);
expect(cfg?.bgImage).not.toBeNull();
// 背景图层渲染
await expect(a2.page.locator('div').filter({ hasText: '' }).first()).toBeTruthy();
const blur = await a2.page.evaluate(() => getComputedStyle(document.documentElement).getPropertyValue('--blur-px').trim());
expect(blur).toBe('12px');
await a2.app.close();
});