☰
Rancher Desktop 截图自动化:基于 Playwright 的跨平台 UI 截图 e2e 任务全解析
2026/9/28 2:41:23 网站建设 项目流程
  • 桌面应用
  • 云原生
  • 容器编排

【免费下载链接】rancher-desktop

Container Management and Kubernetes on the Desktop

项目地址:https://gitcode.com/gh_mirrors/ra/rancher-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 windowmacOS检查系统设置 -> 隐私与安全性 -> 屏幕录制,为终端开启屏幕录制权限;确认GetWindowID已通过brew install smokris/getwindowid/getwindowid安装
截图脚本在密码提示处挂起macOS / LinuxFactory 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

项目地址:https://gitcode.com/gh_mirrors/ra/rancher-desktop
点击查看免费下载

相关推荐

上一篇:5步完成黑苹果EFI配置:从硬件诊断到系统部署的完整解决方案
下一篇:STARK源代码结构解析:轻松理解核心模块与API设计

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询