108 lines
4.7 KiB
JavaScript
108 lines
4.7 KiB
JavaScript
'use strict';
|
||
// 在真实 Electron 窗口尺寸(420x690,与 main.js openSettingsWindow 一致)下
|
||
// 验证设置窗口的标签页与布局。
|
||
// 运行:electron test/settings-tabs.test.js
|
||
const assert = require('node:assert');
|
||
const path = require('node:path');
|
||
const { app, BrowserWindow, ipcMain } = require('electron');
|
||
|
||
const cfg = {
|
||
autoLaunch: false, maxItems: 0, displayLimit: 300, pollMs: 1000,
|
||
dataDir: 'C:\\Users\\guan\\.clipboard-app',
|
||
theme: 'linear', accent: 'purple', followSystem: false,
|
||
};
|
||
|
||
ipcMain.handle('settings:get', () => ({ ...cfg }));
|
||
ipcMain.handle('settings:set', () => ({ ...cfg }));
|
||
ipcMain.handle('settings:clear-history', () => 0);
|
||
ipcMain.handle('settings:open-dir', () => {});
|
||
ipcMain.handle('settings:choose-dir', () => ({ ok: false }));
|
||
ipcMain.handle('theme:get', () => ({ ...cfg }));
|
||
ipcMain.handle('theme:set', (_e, { theme }) => ({ theme, accent: cfg.accent }));
|
||
ipcMain.handle('theme:set-accent', (_e, { accent }) => ({ theme: cfg.theme, accent }));
|
||
ipcMain.handle('theme:set-follow-system', () => ({ theme: cfg.theme, accent: cfg.accent }));
|
||
// 与 settings-render.test.js 同理:settings.js 启动时会订阅主题变更,
|
||
// stub 缺这个 handler 会往终端打一条未捕获错误(此测试不断言 console,
|
||
// 但留着噪音会掩盖真问题)。
|
||
ipcMain.handle('theme:subscribe', () => true);
|
||
|
||
let passed = 0;
|
||
async function check(name, fn) {
|
||
try { await fn(); console.log(' ok -', name); passed++; }
|
||
catch (e) { console.error(' FAIL -', name, '\n', e.message); process.exitCode = 1; }
|
||
}
|
||
|
||
app.whenReady().then(async () => {
|
||
const win = new BrowserWindow({
|
||
width: 420, height: 690, show: false, frame: false, resizable: false,
|
||
webPreferences: {
|
||
preload: path.join(__dirname, '..', 'preload.js'),
|
||
contextIsolation: true, nodeIntegration: false, sandbox: false,
|
||
},
|
||
});
|
||
await win.loadFile(path.join(__dirname, '..', 'renderer', 'settings.html'));
|
||
await new Promise((r) => setTimeout(r, 900));
|
||
const js = (code) => win.webContents.executeJavaScript(code);
|
||
|
||
await check('三个标签存在且文案顺序正确', async () => {
|
||
const labels = JSON.parse(await js(
|
||
`JSON.stringify([...document.querySelectorAll('#tab-bar [role="tab"]')].map(t => t.textContent.trim()))`
|
||
));
|
||
assert.deepStrictEqual(labels, ['外观', '通用', '关于']);
|
||
});
|
||
|
||
await check('初始只显示「外观」页', async () => {
|
||
const r = JSON.parse(await js(`JSON.stringify({
|
||
visible: [...document.querySelectorAll('.tab-panel')].filter(p => !p.hidden).map(p => p.id),
|
||
selected: document.querySelector('[role="tab"][aria-selected="true"]').textContent.trim(),
|
||
})`));
|
||
assert.deepStrictEqual(r.visible, ['panel-appearance']);
|
||
assert.strictEqual(r.selected, '外观');
|
||
});
|
||
|
||
await check('点击「通用」切到通用页并互斥', async () => {
|
||
const r = JSON.parse(await js(`(() => {
|
||
document.getElementById('tab-general').click();
|
||
return JSON.stringify({
|
||
visible: [...document.querySelectorAll('.tab-panel')].filter(p => !p.hidden).map(p => p.id),
|
||
cur: document.getElementById('tab-general').getAttribute('aria-selected'),
|
||
prev: document.getElementById('tab-appearance').getAttribute('aria-selected'),
|
||
});
|
||
})()`));
|
||
assert.deepStrictEqual(r.visible, ['panel-general']);
|
||
assert.strictEqual(r.cur, 'true');
|
||
assert.strictEqual(r.prev, 'false');
|
||
});
|
||
|
||
await check('→ 键切到下一个标签,← 键回上一个', async () => {
|
||
const r = JSON.parse(await js(`(() => {
|
||
const bar = document.getElementById('tab-bar');
|
||
const cur = () => document.querySelector('[role="tab"][aria-selected="true"]').textContent.trim();
|
||
const key = (k) => bar.dispatchEvent(new KeyboardEvent('keydown', { key: k, bubbles: true }));
|
||
document.getElementById('tab-appearance').click();
|
||
key('ArrowRight'); const right = cur();
|
||
key('ArrowLeft'); const back = cur();
|
||
return JSON.stringify({ right, back });
|
||
})()`));
|
||
assert.strictEqual(r.right, '通用');
|
||
assert.strictEqual(r.back, '外观');
|
||
});
|
||
|
||
await check('每一页在 690px 窗口内都放得下(不需要滚动)', async () => {
|
||
const rows = JSON.parse(await js(`JSON.stringify(
|
||
[...document.querySelectorAll('#tab-bar [role="tab"]')].map(t => {
|
||
t.click();
|
||
const p = document.getElementById(t.getAttribute('aria-controls'));
|
||
return { id: p.id, clientH: p.clientHeight, scrollH: p.scrollHeight };
|
||
})
|
||
)`));
|
||
for (const r of rows) {
|
||
assert.ok(r.scrollH <= r.clientH + 1,
|
||
`${r.id} 内容溢出:${r.scrollH}px > 可视 ${r.clientH}px`);
|
||
}
|
||
});
|
||
|
||
console.log(`\n${passed} checks passed`);
|
||
app.exit(process.exitCode ? 1 : 0);
|
||
});
|