Skip to main content

Human Input (MFA & Verification Codes)

Some flows require short codes that the agent cannot retrieve on its own — TOTP one-time passwords, SMS codes, and emailed verification links. Testronaut supports these with a built-in human input pause that halts the agent, prompts you in the terminal, and resumes once you supply the code.


Writing a Mission That Prompts for a Code

In your mission string, instruct the agent in plain language to ask the user for the code. The agent translates that instruction into a request_human_input tool call automatically.

import { runMissions } from 'testronaut';

export const loginMFAMission = `
Visit ${process.env.URL}.
Fill the username field (#username) with ${process.env.USERNAME}.
Fill the password field (#password) with ${process.env.PASSWORD}.
Click the "Sign in" button.
There should be an MFA challenge. Prompt the user for an MFA code,
then fill the MFA code field (#mfa-code) with that code.
Click the "Verify" button.
Wait until a heading with "Dashboard" is visible.
Take a screenshot.
If the dashboard is visible, report SUCCESS. Otherwise, report FAILURE.
`;

export async function executeMission() {
return await runMissions({ mission: loginMFAMission }, "login MFA mission");
}

Effective prompt phrases

The agent responds to natural language — any phrase that describes waiting for or requesting a user-supplied code will trigger the tool:

ScenarioExample mission language
TOTP authenticator app"Prompt the user for a TOTP code from their authenticator app"
SMS one-time code"Ask the user for the SMS verification code they just received"
Emailed confirmation code"Request the email confirmation code from the user"
Generic verification code"Prompt the user for the verification code"

Terminal Experience

When the agent reaches a request_human_input call, the mission pauses and you see a prompt like:

👤 Enter your MFA code: 
  • Input is hidden — characters are not echoed to the terminal.
  • Press Enter to submit. The agent receives the code and continues immediately.
  • The code is redacted from all logs and reports (shown as •••••• (length)).
  • If no input is provided within the timeout window (default 60 seconds), the tool throws a timeout error and the mission fails.

Input requirements: alphanumeric characters, underscores, and hyphens only (A-Z a-z 0-9 _ -), maximum 64 characters. Whitespace is stripped automatically.


Disabling Human Input (Automated / CI Runs)

For headless CI environments where no one is at the terminal, disable the tool so missions fail fast instead of hanging on a prompt.

CLI flag

# Disable for this run
testronaut --no-human-input

# Explicitly enable (default)
testronaut --human-input=true

# Adjust the timeout
testronaut --human-input-timeout=120

Config file (testronaut.config.json)

{
"humanInput": {
"enabled": false,
"timeoutSeconds": 60
}
}

Environment variables

# Disable
TESTRONAUT_HUMAN_INPUT=false testronaut

# Adjust timeout (seconds)
TESTRONAUT_HUMAN_INPUT_TIMEOUT_SECONDS=120 testronaut

Environment variables take highest priority, followed by testronaut.config.json, then built-in defaults.

Priority order

PrioritySource
1 (highest)CLI flags (--no-human-input, --human-input-timeout)
2Environment variables (TESTRONAUT_HUMAN_INPUT, TESTRONAUT_HUMAN_INPUT_TIMEOUT_SECONDS)
3testronaut.config.json (humanInput.enabled, humanInput.timeoutSeconds)
4 (lowest)Built-in defaults (enabled: true, timeout: 60s)

Config Reference

OptionTypeDefaultDescription
humanInput.enabledbooleantrueAllow the agent to pause for user-supplied codes
humanInput.timeoutSecondsnumber60Seconds to wait before timing out (clamped to 5–300)

Accepted aliases in testronaut.config.json:

  • humanInput.enabled / humanInputEnabled / allowHumanInput
  • humanInput.timeoutSeconds / humanInput.timeout / humanInputTimeoutSeconds / humanInputTimeout