- 桌面应用
- 云原生
- 容器编排
【免费下载链接】rancher-desktop
Container Management and Kubernetes on the Desktop
rancher-desktop/screenshots/README.md所描述的截图任务,是 Rancher Desktop 仓库中一个特殊的端到端(e2e)任务:它像普通 Playwright 测试一样运行,自动为 UI 的主要页面采集截图,并分别产出浅色(light)与深色(dark)两种模式的结果。本文将以该文档为核心骨架,结合 Screenshots.ts、screenshots.e2e.spec.ts、playwright-config.ts 等源码实现,完整讲解其工作原理、平台前置条件、运行方式、环境变量与输出产物,帮助你直接复用这套方案为自己的桌面应用搭建自动化截图流水线。
一、任务定位:一套"会截图的 e2e 测试"
从仓库结构看,截图任务位于 screenshots/ 目录,与常规 e2e 测试(e2e/)平级,但它是为收集 UI 截图这一单一目标服务的。其核心设计要点如下:
- 以 Playwright 为载体:任务本身就是一个 Playwright 测试(
screenshots.e2e.spec.ts),因此可以复用 e2e 体系中已有的启动、导航、断言与重试能力; - 平台原生工具负责"拍照":Playwright 自带的
page.screenshot()并未用于最终的产物采集,而是按平台分发到screencapture(macOS)、PowerShell 脚本(Windows)、xwininfo+GraphicsMagick(Linux)等系统工具,以便捕获真实的原生窗口画面; - 双主题产出:同一组页面分别以浅色、深色两种模式各截一遍,覆盖文档、市场宣传与 UI 回归检查对两种主题截图的需求。
对应 npm/yarn 脚本定义在 package.json:
"test:e2e:screenshots": "node scripts/ts-wrapper.js scripts/e2e.ts --config=screenshots/playwright-config.ts", "screenshots": "yarn screenshots:light && yarn screenshots:dark", "screenshots:dark": "cross-env THEME=dark yarn test:e2e:screenshots", "screenshots:light": "cross-env THEME=light yarn test:e2e:screenshots"可以看出yarn screenshots会依次执行浅色与深色两轮,每一轮都通过 scripts/e2e.ts 启动 Playwright,并显式指定screenshots/playwright-config.ts作为配置。
二、工作原理:从测试用例到原生截图
1. Playwright 配置中的主题切换
screenshots/playwright-config.ts 是这套任务的配置入口,几个关键点值得注意:
- 通过
process.env.RD_MOCK_FOR_SCREENSHOTS = 'true'显式声明"截图模式",让后端以 mock 数据运行,保证截图内容稳定、可复现; use.colorScheme直接由环境变量THEME决定:THEME=dark时用'dark',否则用'light';- 配置还在操作系统层面同步切换系统主题:macOS 上通过
osascript调用 System Events 设置系统深色/浅色外观(见 playwright-config.ts),Windows 上则写入注册表项HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize的AppsUseLightTheme(见 playwright-config.ts)。这样采集到的窗口真实反映了系统主题,而非仅改变页面内的 CSS 配色。
2. 跨平台截图分发
核心抽象类是Screenshots(Screenshots.ts),其screenshot()方法根据process.platform分发到三种实现:
- macOS(darwin):先用
GetWindowID按应用 Bundle 名与窗口标题(Rancher Desktop/Rancher Desktop - Preferences)查到窗口 ID,再调用screencapture -a -o -l <windowId>捕获指定窗口; - Windows(win32):调用
powershell.exe执行 screenshot.ps1,传入输出路径、窗口标题与-Foreground参数; - Linux(默认分支):先用
xwininfo -name <title> -tree定位窗口,再沿父窗口链向上回溯直到根窗口,得到真正包含边框的窗口 ID,最后优先使用gm import(GraphicsMagick),否则退回 ImageMagick 的import命令截图。
此外MainWindowScreenshots负责主窗口各页面的截图(窗口标题固定为Rancher Desktop),PreferencesScreenshots负责偏好设置窗口各 Tab 的截图(窗口标题为Rancher Desktop - Preferences),两者的take()都先通过导航页面/偏好页面对象完成跳转与等待,再落盘截图文件。
3. Windows 截图脚本的特殊处理
screenshot.ps1 的注释揭示了一个关键坑点:Rancher Desktop 基于 Electron/Chromium,使用 GPU 加速(OpenGL/DirectX)渲染,传统的BitBlt(基于 DC 复制)会产出全黑图片。因此该脚本改用DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS)取得不含阴影的窗口矩形,再CopyFromScreen截取全屏后裁剪到窗口区域。这也解释了 README 中"Windows 会裁剪全屏截图,因此任何重叠窗口都会出现在图中"的提示——截图时请确保目标窗口位于最上层且未被遮挡。
三、平台前置条件
按 README 的要求,不同平台需要准备对应的系统工具:
macOS
screencapture:操作系统自带(位于/usr/sbin),无需额外安装,用于按窗口 ID 捕获屏幕;GetWindowID:需要通过 Homebrew 安装:
brew install smokris/getwindowid/getwindowid- 权限问题:如果运行截图脚本时出现
screencapture: no file specified或could not create image from window报错,基本可以断定是隐私设置未授权。需要在系统设置 -> 隐私与安全性 -> 屏幕录制中启用终端(Terminal)的屏幕录制权限。这是 macOS 屏幕捕获类工具最常见的失败原因。
Windows
- 依赖PowerShell出现在
PATH中,且必须作为powershell(而非pwsh)被调用——这一点由 Screenshots.ts 中的spawnFile('powershell.exe', ...)硬性要求;PowerShell 随 Windows 系统自带; - 如前所述,Windows 采用"全屏截取后裁剪"的方式,任何与目标窗口重叠的其他窗口都会进入画面,采集前需整理桌面;
- 若在 CI 中运行且显示器分辨率过小,任务会调用 set-display-resolution.ps1 将分辨率至少提升到 1440×900(32 位色深)。该脚本通过
EnumDisplaySettings枚举当前显示器支持的显示模式,选择满足最低要求且面积最大的模式,再调用ChangeDisplaySettings应用(默认仅在CI环境变量存在时才真正改分辨率,本地运行时仅打印诊断信息)。入口位于 Screenshots.ts。
Linux
xwininfo:一般包含在x11-utils软件包中,负责定位窗口与回溯父窗口链;GraphicsMagick:提供gm import完成窗口截取;若未安装,脚本会回退到 ImageMagick 的import命令(见 Screenshots.ts)。
四、运行截图任务
第一步:安装依赖
yarn第二步:执行 Factory Reset
采集截图前务必先执行一次 "Factory Reset"(恢复出厂设置),让应用回到默认设置状态,避免截图里出现你本地的个性化配置(如自定义容器引擎、K8s 版本、代理设置等)。否则截图会与文档目标受众看到的默认界面不一致。
第三步(macOS / Linux):手动启动一次应用
在 Factory Reset 之后、正式截图之前,需要手动运行一次应用(yarn dev),其目的是"禁用管理员权限"。若不执行这一步,截图脚本运行到密码提示框(sudo/管理员认证)时会被卡住挂起。这一步只针对 macOS 和 Linux,Windows 无需处理。
第四步:采集截图
同时产出浅色与深色两套截图:
yarn screenshots仅浅色模式:
yarn screenshots:light仅深色模式:
yarn screenshots:dark每次执行实际上都会完整跑一遍 screenshots.e2e.spec.ts 中定义的测试用例。从该用例可以看出截图覆盖面:
- 主窗口页面:General(首页)、Containers(容器列表)、Container-Inspect(容器详情 Inspect)、Container-Logs(容器日志)、Container-Stats(容器资源统计)、PortForwarding(端口转发)、Images(镜像)、Volumes(卷)、Troubleshooting(故障排查)、Diagnostics(诊断)、Snapshots(快照,含空列表 / 创建弹窗 / 列表三种状态)、Extensions(扩展市场与已安装列表);
- 偏好设置窗口:Application(General / Behavior / Environment 三个 Tab)、WSL(Network / Integrations / Proxy,仅 Windows)、Virtual Machine(Hardware / Volumes / Emulation,其中 macOS 单独覆盖 VZ、virtiofs、9p 与 QEMU 组合)、Container Engine(General / Allowed Images)、Kubernetes;
- 锁定字段(locked fields)场景:通过 mock 锁定设置接口(
/settings/locked),专门截图被企业部署策略锁定时出现的 tooltip 提示(见 screenshots.e2e.spec.ts)。
五、环境变量
README 中定义了一个用于控制版本展示的环境变量:
RD_MOCK_VERSION
作用:自定义应用界面中显示的版本号,常用于发布周期尚未结束、但需要提前为文档准备截图素材的场景。示例:
export RD_MOCK_VERSION=1.0.0; yarn screenshots配合截图配置中的RD_MOCK_FOR_SCREENSHOTS(由 playwright-config.ts 自动设置),后端会以 mock 数据驱动 UI,使"版本号 + 界面数据"都可控、可复现。另外两个影响运行行为的隐式环境变量是THEME(由screenshots:light/screenshots:dark脚本注入,决定主题)与CI(放大超时、开启重试并触发 Windows 分辨率调整)。
六、输出位置与文件命名
截图统一保存到:
screenshots/output实际目录结构按"平台 + 主题 + 页面区块"组织。以 Screenshots.ts 的构造逻辑为准,输出路径为:
screenshots/output/<platform>/<light|dark>/<main|preferences>/<N>_<页面名>.png<platform>为process.platform()的结果(如darwin、win32、linux);<light|dark>来自 Playwright 的colorScheme参数,对应测试运行时的主题;<main|preferences>区分主窗口与偏好设置窗口(分别由MainWindowScreenshots与PreferencesScreenshots在构造时传入);- 文件名由静态计数器
screenshotIndex自增加标题组成,例如0_General.png、5_Container-Inspect.png,偏好设置则形如application_tabGeneral.png、containerEngine_tabAllowedImages_lockedFields.png(见 Screenshots.ts 与 screenshots.e2e.spec.ts 中的take()调用)。
七、让截图内容"稳定可控"的 mock 机制
截图任务与常规 e2e 的一个显著差异在于:它通过大量 mock 让页面内容确定化,避免真实容器状态、随机数据破坏截图的一致性。相关测试数据集中在 screenshots/test-data/:
- containers.ts:一组虚构的容器列表(如
postgres:15、webapp-postgres-1),用于容器列表、Inspect、Logs 等页面; - container-inspect.ts 与 container-stats.ts:容器详情与资源统计图表(CPU / 内存 / 网络 / IO)所需的样本序列;
- images.ts、volumes.ts、snapshots.ts、preferences.ts:分别驱动镜像、卷、快照列表与"锁定字段"设置接口。
从 screenshots.e2e.spec.ts 可以看到具体的注入方式:通过page.exposeFunction覆盖ddClient.docker.listContainers、rdListVolumes等扩展 API(见 screenshots.e2e.spec.ts),通过拦截 IPC 事件伪造container-stats数据流(见 screenshots.e2e.spec.ts),以及通过page.route拦截/snapshots、/settings/locked等 HTTP 请求(见 screenshots.e2e.spec.ts 与 screenshots.e2e.spec.ts)。这些 mock 均在beforeAll中注册、在afterAll中还原,保证测试间互不污染。
八、常见问题排查要点
结合 README 提示与源码实现,总结以下高频问题的处理思路:
| 现象 | 平台 | 处理方式 |
|---|---|---|
screencapture: no file specified或could not create image from window | macOS | 检查系统设置 -> 隐私与安全性 -> 屏幕录制,为终端开启屏幕录制权限;确认GetWindowID已通过brew install smokris/getwindowid/getwindowid安装 |
| 截图脚本在密码提示处挂起 | macOS / Linux | Factory Reset 后先用yarn dev手动启动一次应用,禁用管理员权限认证 |
| Windows 截图中混入其他窗口 | Windows | 关闭/移动其他窗口,确保目标窗口可见且未被遮挡 |
| 截图为全黑 | Windows | 确认走的是 screenshot.ps1 的全屏裁剪路径,不要用其他基于 BitBlt 的截图工具替换 |
| 截图内容不是默认界面 | 全部 | 重新执行 Factory Reset,清除本地配置后再采集 |
| CI 中分辨率不足 | Windows | 确认CI环境变量存在,任务会自动调用 set-display-resolution.ps1 提升到 1440×900 |
九、小结
Rancher Desktop 的截图任务演示了一种"Playwright 驱动 + 平台原生截图工具"的混合方案:Playwright 负责应用启动、页面导航、数据 mock 与状态断言,系统原生工具负责捕获真实窗口画面,两者配合既能保证截图内容可复现、可预期,又能真实反映各平台的主题与窗口渲染效果。如果你想为自己的 Electron/桌面应用搭建类似的自动化截图流水线,可以直接复用 screenshots/ 目录下的整套结构——Screenshots.ts的跨平台抽象、screenshot.ps1的 GPU 渲染窗口处理技巧,以及test-data的确定性 mock 思路,都是可以直接借鉴的实战经验。
- 桌面应用
- 云原生
- 容器编排
【免费下载链接】rancher-desktop
Container Management and Kubernetes on the Desktop
相关推荐
qwen-code Terminal Capture:基于 node-pty + xterm.js + Playwright 的 CLI 终端截图自动化方案
qwen code Terminal Capture:基于 node pty + xterm.js + Playwright 的 CLI 终端截图自动化方案 本
人工智能AI Agent代码智能体工具调用交互助手CLIQweniOS设备截图自动化:基于libimobiledevice screenshotr服务实现
iOS设备截图自动化:基于libimobiledevice screenshotr服务实现 在移动应用测试和自动化流程中,实时获取iOS设备屏幕截图是关键需求。
移动开发Super Productivity 自动化商店截图流水线:基于 Playwright 与单一种子数据集的可复现 App Store 截图方案
Super Productivity 自动化商店截图流水线:基于 Playwright 与单一种子数据集的可复现 App Store 截图方案 导读 Super
前端桌面应用移动开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考