Files
胡绍康andCopilot cf7817bb95 feat: UI全局美化重设计 + 恢复CI/测试/文档
UI 改进:
- 设置页面内嵌显示(不再弹窗)
- 临时邮箱卡片添加验证码提取按钮
- 导入账号弹窗 textarea 样式优化
- 账号头像 8 色渐变轮转
- 临时邮箱页顶栏邮箱点击复制
- 邮箱管理页自动选中默认分组
- 切换分组时重置邮件列 UI
- 修复收件箱/垃圾邮件 Tab 切换(.folder-tab → .email-tab)
- 修复从临时邮箱返回后账号列数据残留
- 仪表盘分组列表可点击导航

恢复:
- 恢复 .github/ CI 工作流
- 恢复 tests/ 测试目录
- 恢复 docs/ 文档目录
- 恢复 CONTRIBUTING.md, SECURITY.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 21:24:06 +08:00

114 lines
2.2 KiB
JavaScript

/**
* Jest 测试环境设置
* 模拟浏览器 API 和 DOM 环境
*/
// 模拟 localStorage
class LocalStorageMock {
constructor() {
this.store = {};
}
clear() {
this.store = {};
}
getItem(key) {
return this.store[key] || null;
}
setItem(key, value) {
this.store[key] = String(value);
}
removeItem(key) {
delete this.store[key];
}
get length() {
return Object.keys(this.store).length;
}
key(index) {
const keys = Object.keys(this.store);
return keys[index] || null;
}
}
global.localStorage = new LocalStorageMock();
// jsdom 环境下 window.localStorage 可能是独立实例;这里统一指向 mock,避免跨用例污染
try {
if (typeof window !== 'undefined') {
Object.defineProperty(window, 'localStorage', {
configurable: true,
value: global.localStorage
});
}
} catch (_) {
// ignore
}
// 模拟主应用的 toast(避免 LayoutManager.notify() 退化到 window.alert,触发 jsdom 的 not implemented 报错)
global.showToast = () => {};
try {
if (typeof window !== 'undefined') {
window.showToast = global.showToast;
}
} catch (_) {
// ignore
}
// 模拟 requestAnimationFrame
global.requestAnimationFrame = (callback) => {
return setTimeout(callback, 16);
};
global.cancelAnimationFrame = (id) => {
clearTimeout(id);
};
// 模拟 performance.now
if (!global.performance) {
global.performance = {};
}
global.performance.now = () => Date.now();
// 模拟 CSS.supports
if (!global.CSS) {
global.CSS = {};
}
global.CSS.supports = (property, value) => {
// 简单模拟,假设支持所有现代 CSS 特性
return true;
};
// 模拟 getComputedStyle
global.getComputedStyle = (element) => {
return {
getPropertyValue: (prop) => {
if (
element &&
element.style &&
typeof element.style.getPropertyValue === 'function'
) {
return element.style.getPropertyValue(prop) || '';
}
return '';
}
};
};
// 清理函数
afterEach(() => {
// 清空 localStorage
localStorage.clear();
// 清空 document.body
document.body.innerHTML = '';
// 重置 CSS 变量
if (document.documentElement.style) {
document.documentElement.style.cssText = '';
}
});