[2026-10-12] eagle: personal/tech/legacy-xctest-runner.md

This commit is contained in:
Alexey Martemyanov committed 2026-10-12 18:25:26 +06:00
1 parent 0e585cc750
commit 631dd4537c
1 file changed
+76
+76
View File
@@ -0,0 +1,76 @@
---
title: Legacy XCTest runner (run new-Xcode UI tests on macOS 12)
namespace: personal
updated: '2026-10-12'
tags:
- xctest
- ui-tests
- macos
- duckduckgo
- virfield
---
# Legacy XCTest runner
Runs DDG macOS UI tests built with the current Xcode (27.x) on a Mac that can only
run an old Xcode, e.g. the MBP 2014 node (Monterey 12.6.8, Intel, Xcode 13.4.1).
Location: `~/Developer/legacy-xctest-runner/` (not committed anywhere).
## Why it is needed
- New Xcode's `XCTest.framework` and `UI Tests-Runner.app` require macOS 14+.
- The test bundle itself targets the app's deployment target (12.3), so it can run
if hosted by the old Xcode's runner.
- The bundle imports 2 Swift symbols missing from Xcode 13 XCTest:
`XCUIElement.typeKey(_:modifierFlags:)` (mangled under `XCUIAutomation`) and
`XCTIssue.init(…severity:)`. `XCTestCompat.swift` forwards them.
## How it works
- `package.sh <derived-data> <out.tgz>` — collects `DuckDuckGo Review.app`,
`tests-server`, `UI Tests.xctest` + runner files.
- `run.sh [--gui] <TestClass[/testMethod]> [result-name]` on the target Mac:
- builds `XCTestCompat.framework` (re-exports old XCTest + libXCTestSwiftSupport, adds forwarders);
- hosts the bundle in Xcode 13's `XCTRunner.app`, `install_name_tool` repoints the
bundle's XCTest/libXCTestSwiftSupport imports at XCTestCompat;
- repeats `macOS UI Tests CI` scheme pre-actions (clean-app review, suppress
Move-to-Applications, start tests-server);
- `xcodebuild test-without-building` with `UITests.xctestrun` (FormatVersion 1),
then kills tests-server and the app (old XCTest doesn't terminate it).
- `--gui`: over SSH xcodebuild can't reach the runner; relaunches itself via a
Terminal `.command` in the console session, waits, closes finished windows.
Build on the host (spell flags out — zsh doesn't word-split `$var`):
```bash
xcodebuild build-for-testing -workspace DuckDuckGo.xcworkspace -scheme "macOS UI Tests CI" -destination "platform=macOS,arch=x86_64" -derivedDataPath <dd> ONLY_ACTIVE_ARCH=YES -skipPackagePluginValidation -skipMacroValidation
xcodebuild build -workspace DuckDuckGo.xcworkspace -scheme "macOS Browser" -configuration Review -destination "platform=macOS,arch=x86_64" -derivedDataPath <dd> ONLY_ACTIVE_ARCH=YES -skipPackagePluginValidation -skipMacroValidation
```
## Target Mac prerequisites (once per boot volume, needs sudo)
```bash
sudo DevToolsSecurity -enable
sudo automationmodetool enable-automationmode-without-authentication
```
Without them testmanagerd shows an admin-password prompt on the display
("Timed out while enabling automation mode"). Virfield's node probe now reports
`ui_testing` (`ready` / `devtools_disabled` / `automation_mode_requires_auth` /
`no_console_session`); setup script `virfield-v3/deploy/node-ui-testing.sh`.
## Gotchas found
- Repo `Logger` (`macOS/UITests/Common/UITests.swift`) calls private
`-[XCTContext _recordActivityMessageWithFormat:]`; old XCTest lacks it → guard
with `responds(to:)` (done on branch `alex/fix-save-credentials-tooltip-crash-macos12`).
- Remote shell is zsh: `log` is a builtin — use `/usr/bin/log show`.
- MBP has a different SSH host key per boot volume; use the Virfield lease's
generated `ssh-config` (pins the booted volume's key).
- Hover tracking in the app uses `.activeInKeyWindow`; popovers that open without
focus don't get hover events.
First used: 2026-10-12, reproducing Sentry crash
`NSInternalInconsistencyException SaveCredentialsViewController.loadView`
(`isfinite(newOrigin.x)` on macOS 12) — reproduced before fix on the MBP.
See also [[virfield]].