macOS apps, through AX, the accessibility tree VoiceOver reads: native apps (AppKit, SwiftUI), web views (Tauri, Wails), Electron, Qt, Java and Flutter, as they ship.
macOS asks that the app running Axx be allowed to control the computer: the terminal, the IDE or the CI agent at the top of Axx’s process tree, in System Settings > Privacy & Security > Accessibility (Device Control & Data Access, on macOS 27), and Screen Recording for screenshots. axx doctor checks both, and names the app. Hosted macOS runners allow both already.
Each scenario has the desktop, and a clean app. Desktop scenarios take the Mac’s desktop in turns: while they run, the screen, the pointer and the keyboard are theirs, so leave the Mac be, or run them in CI. Before the app starts, its home (HOME and CFFIXED_USER_HOME, which Foundation follows; Java’s user.home) is emptied, and its preferences, which macOS keeps for the user whatever the home, are emptied too: the domain of the app’s bundle identifier, and the domains its registration names (preferences: Qt’s QSettings names its own, after the app’s organization). Your own are kept aside during the run and put back when it ends (or as the next run starts, after one that was stopped). Window restoration is off. The keychain is not reset: a sign-in an app keeps there outlives the scenario. An app’s ./ files are its home’s Library/Application Support.
Add it to a project with axx pack add desktop-macos; it builds on desktop-core, which comes with it.
desktop-macos.app
Section titled “desktop-macos.app”Given the {word} macos app with the following properties: | property | value |The table may start with the row naming its columns, as above, or go straight to its rows.
Register a macOS app. The app starts when a step launches it. On another OS, the registration does nothing, so a feature registers the app once for each OS it runs on.
| Parameter | Takes | For example |
|---|---|---|
{word} |
one word, with no spaces | parcels, PX-4101 |
| Property | Takes | Default |
|---|---|---|
app |
the app: a .app of the project, an installed app’s bundle identifier (com.apple.TextEdit), or an executable (a file of the project, or a command) |
required |
args |
the arguments it starts with, a quoted one with spaces; a file of the project is relative to axx.yaml | |
env.<name> |
an environment variable it starts with, like env.PARCELS_API |
|
preferences |
the preferences domains the app keeps its settings in beyond its bundle identifier’s, like com.parcels-example.Depot desk (Qt’s QSettings names its own), separated by commas: emptied before each scenario |
|
locale |
its language and region, like de-DE |
en-US |
timezone |
its time zone, like Europe/Berlin |
UTC |
owner |
system for an app the system runs already, like Finder (com.apple.finder): the scenario reads it as it runs, and never resets, launches or stops it; the windows it shows during the scenario are closed as the scenario ends |
Example:
Given the depot macos app with the following properties: | app | ../depot-desk/appkit/build/Depot desk.app |Since 0.2.0.