Preflight Permissions 是一个用于 macOS 平台的自动化测试前置技能,目标是在运行 XCUITest 套件之前,确保所有 macOS 系统权限已经授予,从而防止 XCUITest 因权限弹窗而挂起,或在 TCC 阻止访问时静默失败。
【何时使用】 在启动新项目、克隆仓库之后,或当测试因权限相关错误而失败时运行一次该技能。它是 journey-builder 和 journey-loop 的前置条件。
【主要能力】
- 设置自签名代码签名证书,使权限在重新构建后依然保留。
- 使用该证书构建应用与测试运行器。
- 检测应用需要哪些 TCC 权限。
- 引导用户在系统设置中逐项授予权限。
- 运行冒烟 XCUITest 验证权限是否生效。
- 报告每项权限的通过/失败状态。
【工作流程】 第 1 步:检测项目配置。读取 project.yml(XcodeGen)或扫描 *.xcodeproj,获取应用 bundle ID、UI 测试 target 名称、应用 target 名称、现有 CODE_SIGN_IDENTITY(若已设置为 "-" 以外的值则跳过证书创建)、以及 entitlements 文件。
第 2 步:创建自签名证书。采用 /macos-codesign 技能做法,证书名称必须为 "{AppName} Dev"。若证书已存在则跳过创建;否则使用 openssl 生成证书与私钥,通过 security import 导入钥匙串并信任,然后清理临时文件。若证书刚创建或 CODE_SIGN_IDENTITY 为 "-",则更新项目:若有 project.yml,把 CODE_SIGN_IDENTITY: "-" 改为 "{AppName} Dev" 并运行 xcodegen generate 重新生成工程;绝不手动编辑 .xcodeproj。
第 3 步:构建应用。使用 xcodebuild build 构建应用 target 生成已签名二进制,始终使用 -derivedDataPath build 使 .app 落在项目根目录的可预测路径下,构建成功后打印 app 路径。若构建失败需先诊断修复,常见问题包括证书未受信任、钥匙串被锁定。
第 4 步:检测所需权限。读取应用 entitlements 与源码判断需要哪些 TCC 权限:屏幕录制(entitlement com.apple.security.screen-capture 或使用 ScreenCaptureKit/CGWindowList)、麦克风(com.apple.security.device.audio-input 或使用 AVCaptureDevice 处理音频)、辅助功能(使用 AXIsProcessTrusted() 或 Accessibility API)、自动化(XCUITest 需要辅助功能访问以控制应用)、完全磁盘访问(应用在自身容器外读写文件时,否则每次启动都会弹出 "would like to access data of other apps" 对话框,阻塞无人值守 UI 测试)。并可通过 grep 检查源码线索,以及检查应用是否访问用户主目录路径或 /tmp/ 目录。
第 5 步:引导用户授予权限。对每项所需权限给出明确操作指引,并自动用 open 命令打开对应的系统设置面板,等待用户确认后再继续。启动一次已构建的应用,使其出现在 TCC 权限列表中。
第 6 步:用冒烟测试验证。编写最小化的 XCUITest,验证应用能在无权限弹窗阻塞的情况下启动、且屏幕上没有阻塞的系统对话框。
第 7 步:报告。输出清晰的权限报告,逐项标记证书、构建、屏幕录制、麦克风、辅助功能、完全磁盘访问与冒烟测试的通过状态,并给出最终状态:READY FOR AUTOMATED TESTING 或 BLOCKED。
【规则】 绝不可跳过证书步骤,临时签名会导致每次重新构建时权限被撤销;绝不可尝试通过程序自动授予 TCC 权限,只有用户能在系统设置中完成;始终自动为用户打开相关系统设置面板;在要求用户授权前始终先启动一次应用;始终运行冒烟测试验证;若冒烟测试失败,先判断是权限问题还是构建问题;该技能会修改 project.yml 和/或构建设置,应提交这些更改以便团队受益。
【适用场景与限制】 适用于在 macOS 上以 XCUITest 进行自动化 UI 测试前的权限准备,尤其是需要屏幕录制、麦克风、辅助功能或完全磁盘访问等权限并希望无人值守运行测试的项目。其限制在于:权限授予必须由用户在系统设置中手动完成,无法自动化;具体支持与效果依赖项目自身配置。关于收费、价格等信息暂未提供。