Detect Maestro
Detect when your app is running under Astra Scout automation to enable test-specific behavior.
There are times when your application needs to behave differently during a test. Whether you want to bypass a 2FA screen, disable analytics to avoid polluting production data, or point to a mock server, detecting Maestro within your app's code is a common requirement.
Why detect Maestro?
Detecting when your app is under test is a way to handle scenarios that are otherwise difficult to automate:
- Bypassing 2FA: Modify authentication flows to use fixed codes, avoiding the need for a physical SIM card or email inbox.
- Controlling Content Persistence: Keep short-lived messages (like temporary banners) on the screen longer so Astra Scout has enough time to detect and interact with them.
- Environment Switching: Automatically point your app to a mock server or a staging database to keep production data clean.
- Disabling Custom Animations: If your app uses specialized animations that aren't caught by the
waitForAnimationToEnd, you can turn them off manually to prevent "ghost taps."
Mobile (iOS and Android)
The gold standard for detecting Maestro on mobile is using launchApp arguments. This approach is reliable and explicit.
Pass the argument in your Flow
In your flow, use the arguments parameter within the launchApp command to send a custom flag.
Launch arguments in Astra Scout
Astra Scout passes arguments to maestro-runner, which hands them to the app at launch. On iOS they arrive as -key value launch arguments, so ProcessInfo.processInfo.arguments contains -isMaestro. Verify the exact delivery on Android with a quick test before you rely on it.
- launchApp:
appId: "com.example.app"
arguments:
isMaestro: "true"Detect the argument in your code
Your application can then check for this flag during its initialization phase.
Android (Kotlin/Java)
val isMaestro = intent.getStringExtra("isMaestro") == "true"
if (isMaestro) {
// Disable analytics or use mock data
}iOS (Swift)
if ProcessInfo.processInfo.arguments.contains("isMaestro") {
// Apply test-only configurations
}React Native
For React Native, you can use a library like react-native-launch-arguments to retrieve the parameters passed during startup.
import { LaunchArguments } from 'react-native-launch-arguments';
if (LaunchArguments.value().isMaestro === "true") {
// Apply test-only configurations
}Flutter
For Flutter, the most straightforward approach is to use a package like flutter_launch_arguments to retrieve the parameters passed from the flow without having to manually set up platform channels:
import 'package:flutter_launch_arguments/flutter_launch_arguments.dart';
Future<void> getArguments() async {
final fla = FlutterLaunchArguments();
final foo = await fla.getString('foo');
final isFooEnabled = await fla.getBool('isFooEnabled');
final fooValue = await fla.getDouble('fooValue');
final fooInt = await fla.getInt('fooInt');
}Related content
launchApp: Full technical reference for passing launch arguments.
