Skip to main content

Test driver shims

sim-remote install-shims [--shell posix|fish] [--dir <DIR>]

install-shims writes the stand-in tools, called shims, that Maestro and Appium call. The command prints the shell code that puts them on PATH. The command runs without a session. The scripts are embedded in the sim-remote binary, and the command rewrites them on every run.

Options

OptionDescription
--shell posix|fishThe dialect of the printed code. Without it, sim-remote reads $SHELL and selects fish only for fish
--dir <DIR>The directory for the shims. Without it, sim-remote uses $SIM_REMOTE_SHIM_DIR, then $XDG_CACHE_HOME/sim-remote/shims, then ~/.cache/sim-remote/shims

Apply the printed code in your shell:

eval "$(sim-remote install-shims)"              # sh, bash, zsh
sim-remote install-shims --shell fish | source  # fish

In fish, eval applies nothing and prints no error. Use source.

Files and exports

The command writes these files: xcrun, xcodebuild, plutil, applesimutils, xcode-select, open, appium-host.cjs and a stand-in Xcode.app.

The printed code:

  • exports SIM_REMOTE_SHIM_DIR and SIM_REMOTE_BIN,
  • adds the directory to the front of PATH one time,
  • on Linux, adds --require <DIR>/appium-host.cjs to NODE_OPTIONS. This preload tells the Appium driver that it runs on macOS. It applies to Appium entry points only.

The shims call the binary in SIM_REMOTE_BIN, so they cannot drift from the binary that wrote them.

What each shim does

ShimBehaviour
xcrunSends simctl ... to sim-remote simctl. Answers devicectl list devices with an empty list. Answers --show-sdk-version with the newest iOS runtime on the machine
xcodebuildInstalls the XCTest runner on the simulator, launches it, finds its port, and opens a forward tunnel to the local port that the driver polls. Build and inspect calls succeed and do nothing
plutilUses plistutil from libplist. Falls back to /usr/bin/plutil on a Mac
applesimutilsMaps --setPermissions to simctl privacy
xcode-selectPoints at the stand-in Xcode.app
openDoes nothing. simctl boot boots the simulator

Environment variables

VariableDefaultPurpose
SIM_REMOTE_SHIM_DIRSee --dirThe shim directory. The printed code also exports it
SIM_REMOTE_BINSet by the printed codeThe absolute path of the sim-remote binary that the shims call
SIM_REMOTE_SHIM_XCODE_VERSION26.0The Xcode version that the stand-in Xcode.app reports to Appium
SIM_REMOTE_FORCE_RUNNER_INSTALLUnsetSet to 1 to install the test runner on every run

Known limits

  • The xcodebuild shim reads the runner port from a log line. If the runner never logs a port, the shim reports it.
  • The runner install, the launch, the port discovery and the tunnel must fit in the driver timeout.
  • The xcodebuild shim installs the runner one time per session. A Maestro upgrade in the middle of a session keeps the old runner. Pin the Maestro version.
  • Each log stream that the shim starts leaves a log process in the simulator until the simulator shuts down.