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:
| Scenario | Example 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
| Priority | Source |
|---|---|
| 1 (highest) | CLI flags (--no-human-input, --human-input-timeout) |
| 2 | Environment variables (TESTRONAUT_HUMAN_INPUT, TESTRONAUT_HUMAN_INPUT_TIMEOUT_SECONDS) |
| 3 | testronaut.config.json (humanInput.enabled, humanInput.timeoutSeconds) |
| 4 (lowest) | Built-in defaults (enabled: true, timeout: 60s) |
Config Reference
| Option | Type | Default | Description |
|---|---|---|---|
humanInput.enabled | boolean | true | Allow the agent to pause for user-supplied codes |
humanInput.timeoutSeconds | number | 60 | Seconds to wait before timing out (clamped to 5–300) |
Accepted aliases in testronaut.config.json:
humanInput.enabled/humanInputEnabled/allowHumanInputhumanInput.timeoutSeconds/humanInput.timeout/humanInputTimeoutSeconds/humanInputTimeout