Skip to content

Permissions ​

Configure app permissions on launch or mid-flow for iOS and Android testing.

Managing system permissions is a common challenge in mobile test automation. Since OS prompts (like "Allow Camera Access") typically only appear once, your test journey can become inconsistent if the app state isn't reset.

Flows solve this by allowing you to explicitly configure permissions either at launch or during the Flow, ensuring a predictable environment every time.

Configure permissions on launch ​

The easiest way to manage permissions is during the launchApp command. By default, Astra Scout grants all permissions, but you can override this behavior to test specific scenarios.

To customize launch permissions, you need to specify them when calling launchApp. The following example denies all permissions but explicitly allows the camera and location:

yaml
- launchApp:
    permissions:
      all: deny
      camera: allow
      location: allow

Changing permissions mid-flow ​

Sometimes you need to change permissions while the app is running, for example, to test how your app handles a permission denial or to prepare for a specific feature flow like scanning a QR code. Use the setPermissions command for this purpose.

yaml
- setPermissions:
    permissions:
      notifications: allow

Available permissions ​

Astra Scout uses standardized names to make your Flows cross-platform. For example, using bluetooth on Android targets both BLUETOOTH_CONNECT and BLUETOOTH_SCAN automatically.

The following table list all permissions available in iOS and Android.

PermissioniOSAndroid
bluetooth❌✅
calendar✅✅
camera✅✅
contacts✅✅
health❌❌
homekit✅❌
location✅✅
medialibrary✅✅
microphone✅✅
motion✅❌
notifications✅✅
phone❌✅
photos✅❌
reminders✅❌
siri✅❌
sms❌✅
speech✅❌
storage❌✅
usertracking✅❌

TIP

To grant all available permissions, use all: allow to represent all the permissions that the app can request.

Android custom permissions ​

If a specific Android permission isn't listed above, you can use the full Android Permission ID. The following example adds the ADD_VOICEMAIL permission:

yaml
- setPermissions:
    permissions:
      com.android.voicemail.permission.ADD_VOICEMAIL: allow

INFO

Note that all: allow also covers custom permissions, so you don't need to specify them individually unless you want to deny everything else.

Android special permissions ​

Not all permissions are prompted for in the app, like location is. Some require the user to leave the app and grant the permission within the Settings app.

android.permission.MANAGE_EXTERNAL_STORAGE permission has been required since Android 12 if an app wished to access files that weren't its own (e.g. file browsers, virus scanners).

Astra Scout can manage this like other permissions without additional user interaction, acting like an app's "second use" rather than first use. If it's declared in the app's AndroidManifest.xml then it'll be set automatically. If you want fine grained control, do as with custom permissions:

yaml
- launchApp:
    clearState: true
    permissions:
      android.permission.MANAGE_EXTERNAL_STORAGE: deny

Permission values ​

You can set permissions to one of the following states:

ValueDescription
allowGrants the permission. On iOS, this also automatically dismisses the system prompt.
denyDenies the permission. Android will request permission during the Flow execution if the app requires access to a specific feature.
unsetResets the permission state, causing the system to prompt permission requests when running the Flow.

Permission values can come from a variable or a JavaScript expression instead of being hard-coded:

yaml
appId: com.example.app
env:
  CAMERA_PERMISSION_STATE: deny
---
- launchApp:
    permissions:
      camera: ${CAMERA_PERMISSION_STATE}

This lets one Flow cover both the granted and the denied journey, driven by an Astra Scout environment variable or by the env block of the calling Flow.

Push notifications on iOS

Unlike other permissions, iOS does not grant notification permissions silently. When the app requests permissions, the system prompt appears, and Astra Scout automatically taps Allow.

On Android, the permission is granted silently without a prompt.

iOS-specific values ​

iOS supports additional granular values for certain permissions.

PermissionValueDescription
locationalwaysGrants Always Allow location access.
inuseGrants While Using the App location access.
neverSame as deny.
photoslimitedGrants Limited Access to the photo library.

Answering iOS prompts in the Flow ​

Some prompts are not covered by permissions: Local Network access, or App Tracking Transparency when the Flow must decline it while allowing others. Launch with all: unset so nothing answers them for you, then answer each one by its text. While a system alert is in front of the app, visible, assertVisible, extendedWaitUntil and when conditions match its title, message and button labels, and tapOn presses the button with that label. Only plain text selectors reach the alert: id, index, relative and state selectors look at the app alone.

yaml
- launchApp:
    permissions: { all: unset }
- extendedWaitUntil:
    visible: ".*Would Like to Send You Notifications"
    timeout: 15000
- tapOn: "Don’t Allow"

When two prompts can come in either order, answer them in a loop:

yaml
- repeat:
    times: 3
    while:
      visible: ".*to find devices on local networks\\?|.*to track your activity.*"
      timeout: 5000
    commands:
      - runFlow:
          when: { visible: ".*to find devices on local networks\\?" }
          commands:
            - tapOn: "Allow"
      - runFlow:
          when: { visible: ".*to track your activity.*" }
          commands:
            - tapOn: "Ask App Not to Track"

Button labels use the typographic apostrophe of iOS (Don’t Allow). Only tapOn presses an alert's button: a long press, a double tap or a tap on a point acts on the app alone. A launchApp whose permissions answer prompts another way than the previous launch (all: allow allows them, all: deny denies them, anything else leaves them to the Flow) starts a new automation session, so the previous Flow's way does not carry over.

Usage examples ​

Deny all permissions ​

To ensure your app handles permission denied states, start your Flow by denying everything. This forces you to handle the edge cases where a user declines a system permission prompt.

yaml
- launchApp:
    permissions:
        all: deny

Deny all but allow specific ones ​

This is a common pattern for testing specific features in isolation.

yaml
- launchApp:
    permissions:
        all: deny
        medialibrary: allow
  • launchApp: See the full reference for launching apps.
  • setPermissions: Command for altering permissions configuration mid-flow.