【免费下载链接】webmail
Self-hosted JMAP webmail for Stalwart Mail Server. Mail, calendar, contacts, and files in one client.
Bulwark Webmail 是一款面向 Stalwart Mail Server 的自托管 JMAP webmail 客户端,把邮件、日历、联系人和文件收纳进同一个界面。而它真正让人"放心发布"的底气,来自一套Vitest + Playwright + Stalwart 真机三层测试矩阵:543 个单元测试文件、5700+ 测试用例、17 个 Playwright 集成场景,全部跑在真实邮件服务器上。本文带你完整看懂这套测试体系是如何搭起来的。
为什么 Webmail 测试不能只靠"假数据"
Webmail 最难测的不是界面,而是同步:
- 邮件从别的客户端发进来,未读角标会不会跳?
- 服务器端删了一封邮件,列表会不会消失?
- 多账号统一收件箱的计数,切回来还是不是最新的?
这类"我的计数不对 / 文件夹没刷新"的 Bug,用 Mock 数据几乎测不出来。Bulwark Webmail 的答案很直接:测试时拉起一台真的 Stalwart 邮件服务器,浏览器直接和它说 JMAP。
三层测试矩阵一览
| 层级 | 工具 | 规模 | 运行方式 |
|---|---|---|---|
| 单元层 | Vitest(jsdom 环境) | 543 个测试文件 / 5700+ 用例 | npx vitest run |
| 集成层 | Playwright + Docker 内 Stalwart | 17 个 spec / 55 个场景 | npm run test:integration |
| 静态层 | Playwright Lite 冒烟 | 静态导出 + Stalwart 模拟器 | npm run test:lite-smoke |
三层各司其职:快、深、真。下面逐层拆解。
第一层:Vitest 单元测试——把每个角落锁死
入口配置在 vitest.config.ts:jsdom 环境、React 插件、@路径别名,并明确排除集成目录,避免和 Playwright 套件混跑。全局桩写在 vitest.setup.ts 里——mock 掉next-intl、next/navigation,补齐 jsdom 缺失的matchMedia和localStorage,让组件在测试里"开箱即渲染"。
用例分布基本和项目结构一一对应:
- lib/__tests__/:约 275 个文件,覆盖 JMAP 客户端、邮件线程化、HTML 净化、日历工具、主题编译等核心逻辑;
- stores/__tests__/:90 个文件,重点打磨 Zustand 状态库——账号切换竞态、登出孤儿、断网恢复等"手快点就炸"的场景都有专属用例;
- components/:133 个组件测试,配合 Testing Library 断言交互行为;
- hooks/__tests__/:22 个 Hook 测试,如键盘快捷键、侧边栏应用解析。
贡献者在 CONTRIBUTING.md 中有一行硬要求:提交 PR 前先跑
npm run typecheck && npm run lint && npx vitest run类型、风格、单测三关全过,才有资格进入评审。
第二层:Playwright + Stalwart 真机集成测试
这是整套矩阵里最有含金量的部分,独立成 integration/ 目录,README 就在 integration/README.md。
一键拉起"真机"环境
run-tests.sh 是推荐入口:
integration/run-tests.sh # 全量跑 integration/run-tests.sh 01-login # 只跑登录场景脚本先docker compose up起两个容器(见 docker-compose.yml):
- stalwart:JMAP + 管理端口
8025、SMTP 提交1025、IMAP1143,并用声明式 NDJSON 引导出alice/bob/carol三个测试邮箱; - webmail:被测应用本身,跑在
:3000。
Playwright 则跑在官方浏览器镜像里,绕开浏览器下载失败的老问题;globalSetup会等 Stalwart JMAP 和 webmail 健康检查双双就绪才开始跑(见 integration/tests/global-setup.ts)。
测试思路:改服务器,看浏览器
这是它和普通 E2E 的最大区别——变更走旁路,断言看界面:
- 用零依赖的 SMTP 客户端 helpers/smtp.ts 往邮箱"注入"一封真邮件(支持附件、内联图片);
- 用 JMAP 客户端 helpers/jmap.ts 在服务端执行读、移、删、建文件夹;
- 断言全部落在渲染出来的 UI上——读的是
[data-testid="folder-counts"]里的data-unread/data-total,与语言环境无关。
也就是说,测试回答的问题永远是:服务器变了,webmail 同步到了没有?
以 02-mail-sync.spec.ts 为例:SMTP 收进一封新邮件 → 断言收件箱未读数从 0 变 1;再点开标已读 → 断言服务端状态回落、计数清零。多账号隔离、跨账号移动、委托文件夹、跨账号附件下载等 55 个场景,全部按这套方法覆盖。
失败时"现场全留"
playwright.integration.config.ts 里几个细节很讲究:
screenshot: 'only-on-failure'+trace: 'retain-on-failure':失败才存截图和 trace;- 视频默认
retain-on-failure,想全程录像就IT_VIDEO=on integration/run-tests.sh,产物落在integration/test-results/<test>/video.webm; - CI 环境自动重试 1 次,HTML 报告输出到
integration/playwright-report。
这套"真机测试"到底抓出了什么
最有说服力的,是 integration/README.md 里"Findings"一节——测试矩阵实打实钉住并修复了若干同步缺陷:
- 共享账号计数:Stalwart SSE 只推主账号变更,后台账号变更客户端现在会在可见性对账时轮询补上;
- 跨账号移动:自己账号与共享文件夹之间、跨属主之间的移动,送达、读状态、源删除全部验证通过;
- 跨账号附件:附件 blob 是账号作用域的,All Mail 里下载他人账号邮件的附件曾 404,现在按消息归属的
accountId路由; - 草稿重开:重新打开草稿会还原所选发件人,不再被重置回默认身份(对应草稿场景测试)。
这些 Bug 有一个共同点:只测 UI 状态测不出来,必须让真服务器变一下再看浏览器——这正是整套真机矩阵存在的意义。
第三层:Lite 静态版冒烟测试
Bulwark Lite 是不依赖 Node 服务器的纯静态构建。它的冒烟套件在 scripts/lite/smoke/:
lite-demo.spec.ts:静态导出页在 SPA 回退和"裸 404 主机"两种托管方式下都能正确启动;lite-stalwart.spec.ts:用 Stalwart 模拟器验证部署前缀重定向、OAuth 客户端 id、深度链接、无越界请求。
对应命令npm run test:lite-smoke与npm run test:lite-smoke:stalwart。
CI 里怎么跑的
- 单元测试套件在每次 push 和 pull request都会跑;
- 集成测试工作流在main 分支每晚、带
integration标签的 PR、以及手动触发时运行; - 失败时自动上传 Playwright 报告、trace 和失败视频作为 artifact,并打印容器日志——排查问题不用本地复现。
小结:三层矩阵给普通用户带来了什么
| 你感知的功能 | 守护它的测试 |
|---|---|
| 未读角标、文件夹计数准确 | Vitest 计数逻辑 + 02-mail-sync / 09-live-counters |
| 多账号统一收件箱 | 03-multi-account / 04-all-mail |
| 草稿、委托文件夹、附件下载 | 07-drafts / 06-shared-folders / 10-attachments |
| 换设备打开都正常 | 组件/Hook 单测 + 响应式断言 |
一句话总结:单元测试管"写得对不对",Playwright 管"交互顺不顺",Stalwart 真机管"同步真不真"。想自己动手跑一遍?git clone https://gitcode.com/gh_mirrors/webm/webmail之后,npx vitest run看秒级反馈,integration/run-tests.sh体验真机全量回归——这就是 Bulwark Webmail 放心发布的全部底气。
【免费下载链接】webmail
Self-hosted JMAP webmail for Stalwart Mail Server. Mail, calendar, contacts, and files in one client.
相关推荐
CADmium测试策略:Vitest+Playwright全栈测试
CADmium测试策略:Vitest+Playwright全栈测试 引言:为什么CAD软件需要全面的测试策略? CAD(Computer Aided Desig
3D建模前端图形学WebAssembly桌面应用FoldCraftLauncher多版本支持详解:从1.7.10到最新快照
FoldCraftLauncher多版本支持详解:从1.7.10到最新快照 FoldCraftLauncher是一款专为Android设备设计的Minecraf
移动开发游戏开发硬件加速新纪元:揭秘Gemmini矩阵运算的底层革命
硬件加速新纪元:揭秘Gemmini矩阵运算的底层革命 在人工智能算法日新月异的今天,我们常常忽略了硬件层面的创新。当软件工程师们在云端训练着庞大的神经网络时,一
深度学习硬件开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考