Skip to content

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.

yaml
- 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)

kotlin
val isMaestro = intent.getStringExtra("isMaestro") == "true"
if (isMaestro) {
    // Disable analytics or use mock data
}

iOS (Swift)

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.

javascript
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:

dart
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');
}
  • launchApp: Full technical reference for passing launch arguments.