Environment variables
lynkeus reads a small number of environment variables. Most of them carry what differs between machines and should not be committed: a secret, a port, a key. This page lists each one, says which part of lynkeus reads it, and what it does.
Three parts can read the environment, and it matters which:
- The CLI: the
lynkeuscommand, on your machine or in CI. - The headless host: the app running in Node, started by
lynkeus headless start. - Your app: the agent itself reads no environment variable. It receives its options from your code (
auto({ token, port })), and your code decides where those values come from. React Native gives the app no environment at all, so a variable reaches the app only if something writes its value into the bundle when the bundle is made. For the token, thelynkeus-agent/babelplugin does that.
Summary
Section titled “Summary”| Variable | Read by | Purpose |
|---|---|---|
LYNKEUS_TOKEN |
CLI, headless host, Metro through lynkeus-agent/babel |
The shared secret between the app and its driver. |
LYNKEUS_PORT |
CLI, headless host | The port the driver listens on. |
LYNKEUS_HOST |
headless host | Where the driver is listening. |
LYNKEUS_DEVICE |
CLI | The simulator to use. |
LYNKEUS_APP_ID |
CLI | The app’s bundle id. |
LYNKEUS_ATTACH_TIMEOUT_MS |
CLI | How long to wait for the app to attach. |
LYNKEUS_CONFIG |
CLI | A second configuration file. |
LYNKEUS_SEED |
CLI | Makes random values in cases repeatable. |
LYNKEUS_RECORD_SCREENS |
CLI | Records the structure of every screen read. |
LYNKEUS_REPORTS_URL |
CLI | The address of the hosted report service. |
LYNKEUS_REPORTS_KEY |
CLI | The organization’s API key for that service. |
Where a value can also be given as a flag or in lynkeus.config.json, flags win over the environment, and the environment wins over the file.
Connection
Section titled “Connection”LYNKEUS_TOKEN
Section titled “LYNKEUS_TOKEN”The shared secret between the app and its driver. When the app was mounted with a token, it serves only a driver that presents the same one.
- The CLI reads it and presents it to the app when the app attaches.
lynkeus headless startrequires it and refuses to start without it. The hosted app uses its value as the agent’s token.- Your app gets the token from your code. The common form is
auto({ token: process.env.LYNKEUS_TOKEN }). Inside a React Native bundle that expression isundefinedunless something writes the value there. - Metro, when
babel.config.jslists thelynkeus-agent/babelplugin, reads it while it transforms your code and writes its value wherever the app readsprocess.env.LYNKEUS_TOKEN. It does so in a development bundle only, never a release one.lynkeus initadds the plugin. Since 0.3.0.
export LYNKEUS_TOKEN=$(openssl rand -hex 16)Set it in the shell that starts Metro as well as in the one that runs the CLI. Metro keeps what it has transformed, so after the value changes, start Metro once with --reset-cache.
Both ends must hold the same value. When they do not, the app never attaches. See Security for what the token protects.
LYNKEUS_PORT
Section titled “LYNKEUS_PORT”The port the driver listens on and the app dials. Default: port in lynkeus.config.json, else 8123.
- The CLI listens on it.
lynkeus headless startwrites it into the host it starts, so the host and its driver move together.- Your app on a simulator or an emulator dials the
portyou pass toauto()or<Lynkeus>. To move it, change that option too.
Use it to run several app and driver pairs on one machine: each pair gets its own port.
LYNKEUS_PORT=8124 LYNKEUS_TOKEN=secret lynkeus headless startLYNKEUS_PORT=8124 LYNKEUS_TOKEN=secret lynkeus screenLYNKEUS_HOST
Section titled “LYNKEUS_HOST”Read by the headless host. It says where the driver is listening, for a host that does not run in the same place as its driver, such as a container dialing out. Without it, the host dials the agent’s default address.
LYNKEUS_DEVICE
Section titled “LYNKEUS_DEVICE”Read by the CLI. The simulator to use, by udid or by name. The same as --device and as device in lynkeus.config.json. Without any of them, the CLI takes the first booted simulator.
LYNKEUS_APP_ID
Section titled “LYNKEUS_APP_ID”Read by the CLI. The app’s bundle id (iOS) or application id (Android), used to launch the app and by the simulator commands. The same as --app and as app in lynkeus.config.json.
LYNKEUS_ATTACH_TIMEOUT_MS
Section titled “LYNKEUS_ATTACH_TIMEOUT_MS”Read by the CLI. How long, in milliseconds, a command waits for the app to attach before it gives up. The same as --attach-timeout and as attachTimeout in lynkeus.config.json. Default: 15000.
Configuration and cases
Section titled “Configuration and cases”LYNKEUS_CONFIG
Section titled “LYNKEUS_CONFIG”Read by the CLI. The path of a second configuration file, read after the app’s own lynkeus.config.json. Each top-level key it defines replaces the app’s key of the same name, and the paths under its cases are relative to it.
Use it when tests and fixtures live in a repository of their own:
LYNKEUS_CONFIG=../myapp-tests/lynkeus.config.json lynkeus case runSee Configuration.
LYNKEUS_SEED
Section titled “LYNKEUS_SEED”Read by the CLI when it runs cases. With it set to anything, {{random.letters}} and {{random.digits}} give the same values on every run of a case. Each case still draws different values from the case beside it. Without it, the values are new on every run.
Use it when you compare the screens of two runs: the names and numbers on them are then the same.
LYNKEUS_SEED=1 lynkeus case run --out run --screenshotsLYNKEUS_RECORD_SCREENS
Section titled “LYNKEUS_RECORD_SCREENS”Read by the CLI. Set to 1, every lynkeus screen read keeps the screen’s structure under .lynkeus/screens/ and reports what changed since the last read, as lynkeus screen --record does. lynkeus map changes reads what was kept.
Any value other than 1 leaves it off.
Hosted reports
Section titled “Hosted reports”LYNKEUS_REPORTS_URL and LYNKEUS_REPORTS_KEY
Section titled “LYNKEUS_REPORTS_URL and LYNKEUS_REPORTS_KEY”Read by the CLI, for lynkeus case run --push and every lynkeus report command. LYNKEUS_REPORTS_URL is the address of the report service. LYNKEUS_REPORTS_KEY is your organization’s API key.
Both are required. Without them, those commands stop with:
set LYNKEUS_REPORTS_URL and LYNKEUS_REPORTS_KEY (the organisation’s API key)export LYNKEUS_REPORTS_URL=https://lynkeus.ioexport LYNKEUS_REPORTS_KEY=lk_…lynkeus case run --out run --screenshots --pushThe key is a secret: in CI, keep it in the CI’s secret store. See Reports.
Variables that are not lynkeus’s own
Section titled “Variables that are not lynkeus’s own”lynkeus reads or sets a few variables that belong to other tools.
| Variable | Read or set by | What happens |
|---|---|---|
GITHUB_HEAD_REF, GITHUB_REF_NAME |
CLI, case run --out |
The branch written into run.json, in that order of preference. Outside GitHub Actions, the branch comes from git. |
NODE_OPTIONS |
CLI, headless start |
The CLI appends --dns-result-order=ipv4first for the host it starts, because Node resolves localhost to IPv6 first and local backends usually listen on IPv4 only. What you set is kept. |
CI |
CLI, headless start |
Set to 1 for the jest process that hosts the app. |
The variable named by apiEnv (default API_URL) |
The generated headless entry | The entry refuses to start unless this variable points at localhost, 127.0.0.1 or 10.0.2.2. |
OTEL_EXPORTER_OTLP_ENDPOINT |
Your backend | Not read by lynkeus. With case run --traces, point your backend’s exporter at http://localhost:4318 (or the port given with --traces-port). |
EXPO_PUBLIC_LYNKEUS_TOKEN |
Your Expo app | Not read by lynkeus. It is how an Expo app receives the token: Expo inlines it, with no Babel plugin. Start the development server with it set to the value of LYNKEUS_TOKEN. |
Three more places hand the environment through:
{{env.NAME}}in a case reads any variable of the process runninglynkeus case run.- The fixtures command and
execsteps inherit the CLI’s environment.cases.fixtures.envinlynkeus.config.jsonadds to it for the fixtures command. - The headless host inherits the CLI’s environment, so the variables your app reads are the ones you exported before
lynkeus headless start.