Ir al contenido

Variables de entorno

lynkeus lee del entorno lo que no conviene escribir en un archivo: los secretos, y lo que cambia de una máquina a otra o de una ejecución a otra. Esta página lista cada variable, quién la lee y qué efecto tiene.

Hay tres lectores posibles. El CLI es el proceso lynkeus que ejecutas en la terminal o en CI. El host sin pantalla (headless) es la app corriendo en Node, que arranca lynkeus headless start. La app es tu build de depuración en un simulador, un emulador o un dispositivo.

Variable Quién la lee Para qué
LYNKEUS_TOKEN CLI, host sin pantalla, app El secreto compartido entre la app y su driver.
LYNKEUS_PORT CLI, host sin pantalla El puerto donde se encuentran el driver y la app.
LYNKEUS_HOST host sin pantalla Dónde escucha el driver, cuando no está en la misma máquina.
LYNKEUS_DEVICE CLI Qué simulador usar.
LYNKEUS_APP_ID CLI El identificador de la app.
LYNKEUS_ATTACH_TIMEOUT_MS CLI Cuánto esperar a que la app se conecte.
LYNKEUS_CONFIG CLI Un segundo archivo de configuración.
LYNKEUS_SEED CLI Vuelve repetibles los valores al azar de los casos.
LYNKEUS_RECORD_SCREENS CLI Graba la estructura de cada pantalla que se lee.
LYNKEUS_REPORTS_URL CLI La dirección del servicio de reportes.
LYNKEUS_REPORTS_KEY CLI La clave de API de la organización.

Cuando un valor se puede dar por varios caminos, la opción de la línea de comandos gana sobre la variable de entorno, y la variable de entorno gana sobre lynkeus.config.json.

El secreto que comparten la app y su driver. Cuando la app se monta con un token, solo atiende al driver que lo presenta; así, ningún otro proceso de la máquina puede manejarla.

La leen tres partes, y las tres tienen que ver el mismo valor:

Quién Cómo la usa
El CLI La presenta a la app en su primer mensaje, en cada comando que se conecta.
lynkeus headless start La exige: sin ella se niega a arrancar. Se la pasa a la app alojada como su token.
Tu app La lee donde montas el agente: auto({ token: process.env.LYNKEUS_TOKEN }).
Metro, en una app de React Native El plugin lynkeus-agent/babel lee la variable del entorno de Metro y escribe su valor en el bundle de desarrollo, donde la app lo encuentra.
Ventana de terminal
export LYNKEUS_TOKEN=un-secreto-por-maquina
npx lynkeus screen

En la app, la situación es distinta de la del CLI. React Native no le da a la app ningún entorno: dentro de un bundle, process.env.LYNKEUS_TOKEN vale undefined mientras nada escriba ahí el valor. De eso se encarga lynkeus-agent/babel, un plugin de Babel que viene con el agente y que lynkeus init agrega a babel.config.js:

babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['lynkeus-agent/babel'],
};

Con el plugin puesto, lo que cuenta es el entorno de Metro:

Ventana de terminal
# La terminal de Metro: el valor que la app va a recibir
LYNKEUS_TOKEN=un-secreto-por-maquina npx react-native start --reset-cache
  • Arranca Metro con LYNKEUS_TOKEN definida, con el mismo valor que lee el CLI.
  • Después de cambiar el valor, arranca Metro una vez con --reset-cache. Metro guarda lo que ya transformó, y sin eso la app sigue con el valor anterior.
  • El plugin solo escribe en un bundle de desarrollo. En un bundle de producción el token nunca se escribe.

Si la app pasa un token y le llega vacío, el agente queda apagado, y la app lo dice en su log con una línea que empieza con lynkeus: the app passed a token and it is empty. No pasa a atender sin token. Una app que llama a auto() sin la clave token es otro caso: ahí el agente atiende a cualquier driver, sin exigir ninguno.

Si los valores no coinciden, la app rechaza al driver y el CLI termina con No app attached on …. Ese síntoma está en Solución de problemas.

El puerto donde escucha el driver y al que se conecta la app. Por defecto es 8123. Reemplaza a port de lynkeus.config.json.

La leen el CLI, para saber dónde escuchar, y lynkeus headless start, que escribe ese puerto en el host que arranca. Con la misma variable en los dos, el par queda apuntando al mismo puerto.

Sirve para tener varios pares funcionando en una misma máquina, por ejemplo al ejecutar casos en paralelo:

Ventana de terminal
# Terminal 1: un host y su driver en 8124
LYNKEUS_PORT=8124 LYNKEUS_TOKEN=secreto npx lynkeus headless start
# Terminal 2
LYNKEUS_PORT=8124 LYNKEUS_TOKEN=secreto npx lynkeus screen

Si el puerto ya está en uso, el CLI falla con Port 8123 is already taken: another lynkeus run is probably still driving the app there. Stop it, or use another port (LYNKEUS_PORT, --ports).

Dónde escucha el driver. La lee solo el host sin pantalla, y hace falta cuando el host y su driver no están en el mismo lugar: un contenedor que tiene que conectarse hacia afuera, por ejemplo.

Ventana de terminal
LYNKEUS_HOST=<dirección-del-driver> LYNKEUS_TOKEN=secreto npx lynkeus headless start

Sin ella, el host busca al driver en la misma máquina.

El UDID o el nombre del simulador que usa el CLI. Reemplaza a device de la configuración, y la opción --device la reemplaza a ella. Acepta un nombre parcial.

Sin ningún valor, el CLI usa el primer simulador encendido. Si nombras uno que no está encendido, falla con No booted simulator matching "<nombre>".

El bundle id o application id de la app. Reemplaza a app de la configuración, y la opción --app la reemplaza a ella. Lo usan lynkeus launch, la opción --launch y los comandos que actúan sobre el simulador.

Cuánto espera el CLI a que la app se conecte, en milisegundos. Por defecto 15000. Reemplaza a attachTimeout de la configuración, y la opción --attach-timeout la reemplaza a ella.

Conviene subirla en CI, donde una app puede tardar más en arrancar:

Ventana de terminal
LYNKEUS_ATTACH_TIMEOUT_MS=60000 npx lynkeus case run

La ruta de un segundo archivo de configuración, que se lee encima del lynkeus.config.json de la app. Existe porque los casos y los fixtures suelen vivir en un repositorio propio.

Ventana de terminal
LYNKEUS_CONFIG=../qa-suite/lynkeus.config.json npx lynkeus case run

Las claves de primer nivel del segundo archivo reemplazan enteras a las del primero, y las rutas bajo su clave cases son relativas a ese archivo. Los detalles están en Configuración.

Hace que las referencias {{random.letters}} y {{random.digits}} de un caso den los mismos valores en cada ejecución.

Sin la variable, esos valores son nuevos cada vez. Con ella definida con cualquier valor, cada caso obtiene siempre los mismos, y distintos de los del caso de al lado. Es lo que hace falta para comparar las pantallas de dos ejecuciones: si el nombre del usuario cambia cada vez, todas las capturas difieren.

Ventana de terminal
LYNKEUS_SEED=1 npx lynkeus case run --out run --screenshots

Los valores dependen de la semilla y del id del caso. Cambiar el valor de la semilla cambia todos los valores.

Con el valor 1, cada lynkeus screen guarda la estructura de la pantalla en .lynkeus/screens/ y avisa de lo que cambió desde la última lectura. Es lo mismo que pasar --record en cada llamada.

Ventana de terminal
LYNKEUS_RECORD_SCREENS=1 npx lynkeus screen

Solo el valor exacto 1 la activa. Lo grabado es lo que después lee lynkeus map changes.

La dirección del servicio de reportes y la clave de API de la organización. Las leen lynkeus case run --push y todos los comandos lynkeus report. Hacen falta las dos.

Ventana de terminal
export LYNKEUS_REPORTS_URL=https://lynkeus.io
export LYNKEUS_REPORTS_KEY=lk_…
npx lynkeus case run --out run --screenshots --push

Si falta alguna, el comando termina con set LYNKEUS_REPORTS_URL and LYNKEUS_REPORTS_KEY (the organisation’s API key).

La clave se crea en el servicio, en la sección de claves de API, y se muestra una sola vez. Es un secreto: en CI va en los secretos del repositorio, nunca en el archivo del workflow.

- run: npx lynkeus case run --out run --screenshots --video --push
env:
LYNKEUS_REPORTS_URL: https://lynkeus.io
LYNKEUS_REPORTS_KEY: ${{ secrets.LYNKEUS_REPORTS_KEY }}

La guía de Reportes cubre el recorrido completo.

Estas variables no son de lynkeus, pero influyen en lo que hace.

Variable Quién la lee Qué pasa
GITHUB_HEAD_REF, GITHUB_REF_NAME CLI case run --out anota en run.json la rama desde la que se hizo la ejecución. En GitHub Actions la toma de estas variables, en ese orden; fuera de ahí, se la pregunta a git.
NODE_OPTIONS headless start Le agrega --dns-result-order=ipv4first antes de arrancar jest, y conserva lo que ya tuviera. Node resuelve localhost primero como IPv6, y un backend local suele escuchar solo en IPv4.
CI headless start La define como 1 para el proceso de jest que aloja la app.
la que nombre apiEnv (por defecto API_URL) host sin pantalla La entrada que genera headless init comprueba que apunte a un backend local antes de renderizar la app. Si no, se detiene con lynkeus headless only drives a local backend; API_URL is "…".
EXPO_PUBLIC_LYNKEUS_TOKEN tu app en Expo El token, con el prefijo que Expo exige para incorporarlo al bundle. Si llega vacío, el agente queda apagado.
OTEL_EXPORTER_OTLP_ENDPOINT tu backend No la lee lynkeus. Es la variable estándar de OpenTelemetry con la que tu backend sabe adónde exportar sus trazas. Con case run --traces, apúntala a http://localhost:4318, o al puerto de --traces-port. Ver Trazas del backend.

Además de las anteriores, hay dos lugares donde el entorno entra en una ejecución por decisión tuya:

  • {{env.NOMBRE}} en un caso. Cualquier paso puede leer una variable de entorno del proceso del CLI. Si la variable no está definida, el paso falla con {{env.NOMBRE}} is empty.
  • cases.fixtures.env en la configuración. Variables adicionales para el comando de fixtures. Se suman al entorno del CLI, que el comando hereda completo.
steps:
- app.type: { text: "{{env.QA_PASSWORD}}", target: "#password-input" }