Hooks allow you to configure your test environment in two ways:
- cURL Requests: Backend API calls that run before or after your flows
- App Launch Configuration: Configure how your mobile app launches (feature flags, environment settings)
Perfect for creating test users, resetting databases, configuring backend settings, or controlling app behavior during tests.
Hook Types
cURL Requests
Backend API calls that execute before (setup) or after (teardown) a flow runs. Unlike flows which interact with your mobile app UI, hooks interact with your backend APIs to prepare or clean up test data.
Common use cases:
- Create test user accounts via your API
- Reset database state between flows
- Generate auth tokens or session data
- Configure backend feature flags
- Clean up test data after flows complete
App Launch Configuration
Configure values that are passed to your app when it launches. These values are available to your app code as environment variables (iOS) or intent extras (Android).
Common use cases:
- Override feature flag values for specific test scenarios
- Set test environment parameters (staging vs. production mode)
- Configure API timeouts or retry behavior
- Enable debug modes or verbose logging
- Set experiment variants for A/B testing
Creating a Hook
- Navigate to Hooks in the sidebar
- Click Create Hook
- Enter a hook name (e.g., “Create Test User” or “Enable Dark Mode”)
- Select hook type:
- cURL Request: For backend API calls
- App Launch Configuration: For mobile app settings
- Enter your configuration:
For cURL Requests:
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"TestPass123"}'
For App Launch Configuration:
{
"testEnvironment": "staging",
"featureFlags": {
"newCheckoutFlow": "enabled",
"darkMode": true
},
"apiTimeout": 30
}
- Click Create Hook
Setup hooks can return output (like JSON with credentials or tokens) that the agent automatically receives and can use during flow execution!
Using Hooks in Flows
Attaching Hooks
When creating a flow:
- Expand the Hooks section
- Select a Setup Hook (runs before flow)
- Optionally select a Teardown Hook (runs after flow)
When editing a flow:
- Click Edit on a flow
- Select hooks from the dropdowns
- Save the flow
Execution Order
1. Setup Hook executes (if configured)
2. Flow runs on mobile app
3. Teardown Hook executes (if configured)
Running Hooks Mid-Flow
You can execute hooks as actions during flow execution by using the syntax ${hooks:Hook Name} in any action description.
Example:
Tap the login button, then ${hooks:Create Test User}, then verify the user appears
When the agent encounters ${hooks:Hook Name}, it will:
- Look up the hook by name
- Execute the hook script (cURL request or launch args)
- Continue with the rest of the action
This is useful for:
- Creating data mid-flow (e.g., “add 5 items to cart, then
${hooks:Apply Discount Code}”)
- Triggering backend events at specific points
- Resetting state between actions
Mid-flow hooks execute synchronously - the flow waits for the hook to complete before continuing.
Environment Variables in Hooks
Reference environment variables in your curl commands using ${env:VARIABLE_NAME} syntax:
Hook with environment variables:
curl -X POST ${env:API_URL}/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"${env:TEST_EMAIL}","password":"${env:TEST_PASSWORD}"}'
Environment variables (in Settings → Environments):
API_URL = https://staging-api.example.com
TEST_EMAIL = [email protected]
TEST_PASSWORD = SecurePass123
Executed command:
curl -X POST https://staging-api.example.com/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"SecurePass123"}'
Learn more about environment variables →
Click Insert Environment Variable when creating/editing a hook to browse and select from your available environment variables.
Hook Examples
Create User Account
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${env:ADMIN_TOKEN}" \
-d '{
"email": "${env:TEST_EMAIL}",
"password": "${env:TEST_PASSWORD}",
"role": "tester"
}'
Reset Database
curl -X POST https://api.example.com/test/reset \
-H "Authorization: Bearer ${env:ADMIN_TOKEN}" \
-d '{"scope": "test_data"}'
Generate Auth Token
curl -X POST https://api.example.com/auth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "${env:CLIENT_ID}",
"client_secret": "${env:CLIENT_SECRET}"
}'
Delete Test Data (Teardown)
curl -X DELETE https://api.example.com/users/${env:TEST_USER_ID} \
-H "Authorization: Bearer ${env:ADMIN_TOKEN}"
Enable Feature Flag
curl -X PUT https://api.example.com/features/checkout-v2 \
-H "Authorization: Bearer ${env:ADMIN_TOKEN}" \
-d '{"enabled": true}'
App Launch Configuration
How It Works
App Launch Configuration hooks pass values to your mobile app when it launches. These values are set at app startup and are available throughout your test.
Important: Launch configuration is applied when the app starts. Within a suite, the launch configuration from the first flow will be used for all flows in that suite.
Accessing Values in Your App
iOS (Swift):
// Access simple values (converted to strings)
let environment = ProcessInfo.processInfo.environment
let testEnv = environment["testEnvironment"] // "staging"
let apiTimeout = environment["apiTimeout"] // "30" (as string)
// Nested objects are JSON strings - parse them
if let flagsJSON = environment["featureFlags"],
let flagsData = flagsJSON.data(using: .utf8) {
do {
if let flags = try JSONSerialization.jsonObject(with: flagsData) as? [String: Any] {
let darkMode = flags["darkMode"] as? Bool // true
let checkoutFlow = flags["newCheckoutFlow"] as? String // "enabled"
}
} catch {
print("Failed to parse feature flags: \(error)")
}
}
Android (Kotlin):
import org.json.JSONObject
// Access simple values (type-aware)
val testEnv = intent.extras?.getString("testEnvironment") // "staging"
val apiTimeout = intent.extras?.getInt("apiTimeout") // 30 (as int)
// Nested objects are JSON strings - parse them
val flagsJSON = intent.extras?.getString("featureFlags")
if (flagsJSON != null) {
try {
val flags = JSONObject(flagsJSON)
val darkMode = flags.getBoolean("darkMode") // true
val checkoutFlow = flags.getString("newCheckoutFlow") // "enabled"
} catch (e: Exception) {
Log.e("LaunchArgs", "Failed to parse feature flags", e)
}
}
React Native:
import { LaunchArguments } from "react-native-launch-arguments";
const args = LaunchArguments.value();
// Simple values
console.log(args.testEnvironment); // "staging"
console.log(args.apiTimeout); // "30" (string on iOS, number on Android)
// Nested objects come as JSON strings - parse them
if (args.featureFlags) {
const flags = JSON.parse(args.featureFlags);
console.log(flags.darkMode); // true
console.log(flags.newCheckoutFlow); // "enabled"
}
Launch Configuration Examples
Override Feature Flags
{
"featureFlags": {
"newCheckoutFlow": "treatment_a",
"paymentMethodV2": "enabled",
"showPromotion": false
}
}
Set Environment and Timeouts
{
"testEnvironment": "staging",
"apiBaseUrl": "https://staging-api.example.com",
"requestTimeout": 30,
"retryAttempts": 3
}
A/B Testing Configuration
{
"experiments": {
"checkoutExperiment": "variant_b",
"pricingExperiment": "control"
},
"userId": "test_user_123"
}
Debug Mode Settings
{
"enableDebugMode": true,
"logLevel": "verbose",
"showPerformanceMetrics": true,
"mockPaymentProvider": true
}
When to Use Launch Configuration
Use App Launch Configuration when you need to:
- Test different feature flag combinations
- Override experiment variants for specific test scenarios
- Set environment-specific settings (staging vs. production)
- Enable debug modes or verbose logging for troubleshooting
- Configure API endpoints or timeout values
Use cURL Requests when you need to:
- Create or modify backend data (users, orders, etc.)
- Call external APIs or webhooks
- Reset database state
- Generate auth tokens or session data
Setup Hooks & Agent Context
Pro Tip: When a setup hook returns output (like JSON), the agent automatically receives this data and can use it during flow execution.
Example setup hook:
curl -X POST https://api.example.com/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"${env:TEST_EMAIL}","password":"${env:TEST_PASSWORD}"}'
Hook returns:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"userId": "12345"
}
The agent receives this data and can reference it if needed during the flow execution.
Best Practices
Use Descriptive NamesName hooks after what they do: “Create Premium Test User” instead of “Hook 1”
Store Secrets in Environment VariablesNever hardcode API keys or passwords in hooks. Use environment variables like ${env:API_KEY}.
Test Hooks IndependentlyVerify your curl commands work correctly before attaching them to flows. Test them in your terminal first.
Use Teardown Hooks for CleanupAlways clean up test data created by setup hooks to avoid polluting your backend.
Keep Hooks SimpleEach hook should do one thing. Create separate hooks for different setup tasks.
Hooks vs Suite Auth Instructions
| Feature | Hooks | Suite Auth Instructions |
|---|
| Type | Executed before/after flow | Executed by agent |
| Purpose | Setup/cleanup backend state | Navigate app to starting point |
| Execution | Before/after each flow | Once at suite start |
| Reusability | Can be used across many flows | Specific to one suite |
Use hooks when: You need to configure backend state, create test data, or call APIs
Use suite auth instructions when: You need to start the suite from a specific state (e.g., logged in with a certain test account)
Troubleshooting
cURL Request Issues
Hook fails to execute
- Verify the curl command works in your terminal first
- Check that environment variables are defined
- Ensure API endpoints are accessible from Autosana’s infrastructure
Environment variables not replacing
- Syntax must be
${env:VARIABLE_NAME} (not {{VARIABLE_NAME}})
- Variable names are case-sensitive
- Variables must exist in Settings → Environments
App Launch Configuration Issues
Configuration not appearing in app
- Verify JSON is valid (use a JSON validator)
- Check you’re accessing values correctly for your platform (ProcessInfo for iOS, intent.extras for Android)
- Ensure the hook is attached as a setup hook (launch configuration doesn’t work in teardown)
Values have wrong type
- On iOS, all values become strings (including numbers and booleans)
- On Android, primitives keep their types (int, float, boolean, string)
- Nested objects are JSON-serialized as strings on both platforms
- Use the examples in this guide to parse nested structures correctly
Next Steps