Troupeby AliveDocsSign in

Start

How Troupe works

Troupe is one runtime that owns the devices, one contract that every client speaks, and tools built on that contract. This page walks through the parts in the order a test run meets them.

The parts

Output
 troupe test     troupe studio     your code (client)     a coding agent
      |               |                    |                     |
      +--------- REST and RPC -------------+-------- MCP --------+
                                |
                 the runtime, on 127.0.0.1
         sessions, devices, the live stream, traces
            |                 |                 |
      ios-simulator    android-emulator     catalyst

Nothing above the runtime talks to a device itself. The test framework, the studio, the client and an MCP agent all call the same procedures.

The runtime

The runtime is a daemon, one per user. troupe test, troupe studio, troupe install and troupe mcp start it when none answers, and troupe runtime start --detach starts it by hand. It listens on 127.0.0.1 only, on one port between 47000 and 47999, and writes its address and an owner token to runtime.json under ~/.troupe, where tools on the same machine find it. It exits by itself after 30 minutes with no session and no device.

The runtime owns every device it starts. It names them troupe-…, keeps a registry of them, and never touches a simulator or emulator it did not create. It also watches the host's memory and refuses a new device with CAPACITY_UNAVAILABLE when there is no room for one.

When CI is set, or with --no-daemon, troupe test runs the same runtime inside its own process and shuts its devices down at the end. See the runtime daemon.

Sessions

A session holds one device from the moment you ask for it until you release it or it expires.

  1. sessions.create takes a device spec (platform, and optionally deviceType, os, locale and more) and apps to install. It returns at once with a session that is starting, or ready when a warm device matched.
  2. sessions.wait waits until the session is ready: the device is booted, the driver has answered and the apps are installed.
  3. Device calls name the session: input.tap, ui.snapshot, media.screenshot, apps.launch.
  4. sessions.release ends it. A healthy released device stays warm for five minutes, so the next session with the same spec starts on it without a boot.

A session also ends by itself. A test worker's session ends 30 seconds after its last heartbeat. Any other session ends after 10 minutes without activity, or 60 minutes in total, unless you ask for other limits when you create it. See sessions and sessions.create.

Platforms and drivers

A platform is a kind of device. Each one brings a way to start devices, a driver that reads the accessibility tree and performs actions, and, where it has one, a media engine for the live stream.

PlatformDevicesDriverLive stream
ios-simulatoriOS Simulators, through simctlAn XCUITest runner, one per deviceH.264, with live touch and keys
android-emulatorAndroid Emulators, through Troupe's own adb clientAn instrumentation driver on the deviceH.264, with live touch and keys
catalystYour Catalyst app as a Mac app in a phone-sized windowA host library linked into the app, driving it in processnone

Each platform declares its capabilities: which app formats it installs, which input it takes, whether it can rotate. The runtime checks them before it touches the device, so a call the platform cannot serve fails at once with CAPABILITY_UNSUPPORTED. A test asks for a capability with test.requires and is skipped where it is missing. The platform pages list each platform's capabilities: iOS, Android, Catalyst.

One contract, three surfaces

Every runtime operation is a procedure with an id such as sessions.create or input.tap, a typed input and output, and a list of typed errors. There are 64 procedures in 14 groups: runtime, pairings, catalog, sessions, apps, ui, input, system, media, logs, streams, traces, files and runs. The runtime serves all of them the same way on three surfaces:

SurfacePathUsed by
REST/v1/<group>/<operation> with the operation in kebab case, such as POST /v1/input/tap or GET /v1/catalog/device-typesAnything that speaks HTTP, and the client
RPC/rpc/v2/<group>/<operation>oRPC clients
MCP/mcp, or stdio through troupe mcpCoding agents: 31 curated tools, named sessions_create, input_tap and so on

The live video and input stream is a WebSocket on the same listener, at /v1/stream.

An error is the same on every surface: a code from one registry (LOCATOR_NOT_FOUND, APP_CRASHED, DEVICE_LOST), a message and typed data. Each code is classed as the app's or test's fault, or as infrastructure, which is how a test ends failed or errored. The protocol reference lists every procedure and every error; calling the API directly shows the requests.

Where the test framework fits

troupe test is a client of the runtime like any other.

  • The main process loads troupe.config.ts, asks the runtime what its platforms can do and how many devices it may run, and plans the tests.
  • It creates a session per worker, with your app as an install, and waits for it before any test starts. That time is outside every test timeout.
  • Each worker is a child process that attaches to its session and sends a heartbeat every 10 seconds.
  • A locator is data. screen.getByRole('button', { name: 'Sign in' }) is sent whole with the action and resolved on the device.
  • An action is one input call. The runtime waits for the element to be actionable, acts, and answers.
  • An assertion polls ui.query until it holds or its timeout passes.
  • The trace is recorded by the runtime between traces.startChunk and traces.stopChunk, and joined with the runner's own steps into one zip.

See writing a test.

Where Troupe Cloud fits

Troupe Cloud serves the same contract at https://api.troupe.ali.ve, so the same client and the same MCP tools work against it with an API key or a sign-in in place of the local owner token. A device call goes to a device host that runs the same runtime. The live stream connects your browser to that host directly; video and input do not pass through the API.

The cloud adds what a hosted service needs: organizations, projects, API keys, usage limits, and builds of your app from a repository or an uploaded archive. See Troupe Cloud.

Next

esc

    Type to search every page, the protocol reference and the cloud API.