Skip to main content
Autosana can test the complete push-notification journey on iOS Simulators and Android Emulators: your app registers for remote notifications, your backend or managed provider sends a real notification, and the flow verifies both delivery and deep-link behavior. Use this guide for visible notifications such as alerts, reminders, messages, and order updates.
Push-notification testing on physical iOS and Android devices requires an enterprise contract. Contact us for private-device availability and setup.

How a push test works

A typical test follows the same path as a real user:
  1. Autosana installs and opens your test build.
  2. The app requests notification permission and registers for remote notifications.
  3. The app associates the resulting token or provider subscription with the test user.
  4. The flow performs the action that schedules the notification, or runs a runtime hook that calls your existing test endpoint.
  5. The agent presses Home and waits for the notification.
  6. The agent verifies the notification, taps it, and checks the destination screen.
Autosana does not need your APNs key or Firebase service-account credentials. Your backend or managed provider remains responsible for sending the notification. If a runtime hook triggers the push, store only the test endpoint URL and its API key in Autosana. Keep the APNs .p8 file, Key ID, and Team ID—or the equivalent provider credentials—on the backend that sends the notification. Depending on the integration, your backend may store a raw APNs device token, an FCM or Expo registration token, or a managed-provider subscription.

Prepare your test environment

Before writing the flow:
  1. Choose a test account that can safely receive notifications in your development or staging environment.
  2. Register for remote notifications on every launch. After login, make the app send its latest device or registration token to your backend—or refresh its managed-provider subscription—even when the identifier has not changed.
  3. Make sure your backend or provider can confirm that this installation registered and associated its current push identifier with the test account after the run began. For direct APNs, also record the expected bundle ID and environment.
  4. Configure the build to use the same push provider and backend environment that the flow will exercise.
A dedicated account is not required for sequential tests; you can reuse an existing automation account. If push tests can overlap, give each run or worker a separate account or another unique targeting key. Reusing one account can cause a notification to reach the wrong run when registrations overwrite one another or multiple registrations remain associated with the same user.
Treat push registrations as temporary. Installing a new build, clearing app data, or resetting a virtual device can change the token or provider subscription. Refresh it during every run; do not copy one from an earlier run into the flow.
An automation-friendly notifications screen makes setup failures visible. Keep notification authorization and remote-registration status separate. When authorization is undetermined, offer the system permission prompt. After the user has made a choice, offer Open Settings, and re-check the authorization and registration state whenever the app returns to the foreground.

Platform requirements

Autosana supplies an iOS 16 or later Simulator runtime. Your app’s minimum deployment target can be lower than iOS 16.Every layer below must agree:The arm64 architecture is an Autosana worker requirement, not an APNs protocol requirement. Apple also supports remote notifications in compatible Simulators running on Intel Macs with a T2 processor, but Autosana’s fleet runs on Apple silicon.Configure the Push Notifications capability in Xcode by selecting the project and app target, opening Signing & Capabilities, clicking + Capability, and adding Push Notifications. With manual signing, also enable Push Notifications for the explicit App ID in Certificates, Identifiers & Profiles, then regenerate its development profile.Xcode adds aps-environment=development to the app target’s signed entitlements when you enable the capability and use development signing. It does not go in Info.plist. Do not disable code signing or strip the app’s signature when producing this build.In the app’s existing notification integration, request permission for user-visible notifications and make sure the app or SDK registers with APNs. Do not add a native registration call when the SDK already manages this step. Use the integration’s token or subscription callback to associate its current identifier with the signed-in test account on every launch or sign-in.

Registration APIs by integration

Native iOS

Request authorization with UNUserNotificationCenter, call registerForRemoteNotifications(), and send the APNs token received by the app delegate to your backend. Swift and Objective-C use the corresponding UIKit APIs.

React Native Firebase

Request permission through @react-native-firebase/messaging, then associate the FCM token returned by getToken() with the test account and update it through onTokenRefresh(). The SDK registers with APNs automatically by default; call registerDeviceForRemoteMessages() only if your project disables automatic registration.

Expo notifications

Request permission with requestPermissionsAsync(), retrieve the native APNs token with getDevicePushTokenAsync(), and handle changes with addPushTokenListener(). Use getExpoPushTokenAsync() instead only when your backend sends through the Expo Push Service.

Managed-provider SDKs

Let the provider SDK manage APNs registration, then use its user-identity or subscription API after sign-in. For example, OneSignal associates its automatically created mobile subscription when the app calls login() with the test user’s external ID. Do not also upload the raw APNs token unless the provider’s integration requires it.

Configure an Expo EAS build

EAS Build and the Expo Push Service are independent. EAS Build syncs the Apple capabilities declared by your project, but running eas build alone does not add the push entitlement.Create a dedicated Autosana Simulator profile in eas.json:
The ios.simulator setting controls the target artifact. You only need developmentClient: true if you also want Expo development-client tooling. The aps-environment=development entitlement below selects the APNs Sandbox environment for this artifact; it does not turn the app into an Expo development client.If the app uses the expo-notifications client library, add its config plugin:
The plugin adds the development APNs entitlement even when your backend sends directly through APNs, FCM, or another provider instead of the Expo Push Service.If the app does not use expo-notifications, declare the entitlement directly:
These app-config options apply through Expo Prebuild and Continuous Native Generation. If the repository contains a checked-in native ios/ directory, add Push Notifications to the app target in Xcode or run Prebuild and commit the generated native changes.Create a new EAS build after changing an entitlement; an over-the-air update cannot change the signed app. See Expo’s direct APNs and FCM guide for the complete configuration.

Verify the Simulator artifact

Run this preflight before compressing the .app. Set EXPECTED_BUNDLE_ID to the apns-topic used by your backend:
A successful check prints an architecture list containing arm64, aps-environment=development, and the bundle ID your backend uses as apns-topic. A failed codesign or entitlement check means the uploaded build cannot register with APNs.
iOS Simulator tokens only work with the APNs sandbox. If your backend connects to APNs directly, send these tokens to api.sandbox.push.apple.com. Do not send them to the production endpoint, api.push.apple.com; APNs will reject the token, commonly with a BadDeviceToken response.If you send through Firebase, Expo, OneSignal, or another push provider, you normally do not select the APNs hostname yourself. Make sure that provider is configured to deliver this development build through the APNs sandbox.

Configure your push provider

Your provider must preserve the Simulator token’s development environment all the way to APNs. Use the matching instructions below; if your provider is not listed, look for its development, sandbox, or APNs environment setting.

Direct APNs

Send the Simulator token to api.sandbox.push.apple.com and use the app’s Simulator bundle ID as the apns-topic. Authenticate with a Sandbox-enabled APNs key or certificate. Older team-scoped keys that support both Sandbox and Production continue to work, but a Production-only key fails against the Sandbox. Do not retry a BadDeviceToken response against the production endpoint.

Firebase Cloud Messaging

Continue sending the FCM registration token through the normal Firebase Admin SDK or FCM HTTP v1 endpoint. In the Firebase console, make sure the iOS app has a development APNs authentication key or certificate; FCM handles the connection to the APNs sandbox.

Expo

When using an ExpoPushToken, send to the Expo Push Service normally. Install expo-application so expo-notifications can detect the iOS push environment, or pass development: true to getExpoPushTokenAsync for the Simulator build. Do not force development to false. If you retrieve a native APNs token and send it yourself, follow the Direct APNs instructions above.

OneSignal

Configure the OneSignal app for the APNs development environment. If you provision it through the OneSignal API, set apns_env to development because the API defaults this field to production; use a .p8 key enabled for both Sandbox and Production.

Customer.io

In Workspace Settings > Push > iOS, enable Send all push notifications to sandbox. Customer.io recommends using a separate workspace for the sandbox environment, which also prevents Simulator registrations from mixing with production users.

Braze

Use a separate Braze App or App Group for the development build and configure it with the development APNs credential. Braze allows only one active .p12 certificate per app, so do not replace a live app’s production certificate just to test a Simulator build.

Airship

Initialize the Simulator build with the Airship development/test app key and secret. Let the current Airship SDK infer the APNs environment from the build, or set inProduction to false when your integration selects it explicitly.

AWS SNS

Create an SNS platform application whose platform is APNS_SANDBOX, register the Simulator token against that application’s ARN, and send through the resulting endpoint. Do not register the token under an APNS production platform application.

Azure Notification Hubs

Use a separate notification hub configured under Apple (APNS) in Sandbox mode. Do not switch a shared production hub to sandbox because registrations are tied to the APNs environment.

Iterable

Configure the Iterable app for APNS_SANDBOX and target the token generated by the Simulator build. A production registration or production push credential cannot be used with that token.Each Simulator and host Mac combination receives its own token, and the token’s length can vary. Store the token as an opaque string without assuming a fixed size or format. Register on every app launch and send the returned token or provider subscription to your backend even when its value matches the previous launch.If you use Firebase Cloud Messaging on iOS, use Firebase Apple SDK 10.3.0 or later and configure an APNs authentication key in the matching Firebase project. If Firebase method swizzling is disabled, pass the APNs token to Firebase Messaging in your app code.
See Building Your Mobile App for Our Cloud for artifact and architecture requirements.

Create the flow

Trigger the notification from the app

Use the normal application workflow whenever an in-app action schedules the notification. For example:
The scheduling action and delay belong to your application. Autosana only needs instructions that describe when to press Home, how long to wait, what notification to expect, and what should happen after it is tapped.

Trigger the notification with a runtime hook

Use a runtime hook when the application has no convenient in-app trigger. The hook should call a narrow test endpoint that tells your backend to send a named notification to the dedicated test user.
  1. Add these values to the app’s Autosana environment:
    • PUSH_TEST_URL
    • PUSH_TEST_API_KEY as a secret
    • PUSH_TEST_USER_ID
  2. Create a cURL hook named Trigger Test Push:
  1. Reference the hook at the correct point in the flow:
Runtime hooks run synchronously, so the agent waits for the endpoint response before continuing. A successful endpoint response confirms only that your backend accepted the request; the notification appearing on the virtual device is the end-to-end assertion.
Have the test endpoint return a distinct error when the test user has no registration confirmed after the current run began. For direct APNs, return the APNs status, reason, apns-id, gateway/environment, and apns-topic while showing only a redacted device token. This makes registration, authentication, routing, and delivery failures easier to distinguish.

Test the important app states

Create separate flows when your application handles notifications differently in each state:
  • Background: press Home before sending, then verify and tap the notification.
  • Foreground: keep the app open and verify the app’s foreground presentation or in-app handling.
  • Cold start: terminate or fully close the app through your normal test workflow, send the notification, and verify the deep-linked destination after tapping it.
  • Notification service extension: verify any modified title, body, attachment, or category produced by the extension.
Background or silent data delivery is controlled by the operating system and is not guaranteed to run immediately. Use bounded waits, avoid sending notifications repeatedly in a tight loop, and retain physical-device coverage for business-critical background processing.

Testing notifications on real devices

For device selection, run behavior, and availability, see Real Device Testing. For supported artifacts and standard physical-device build instructions, see Real device builds. Physical push-notification testing uses private devices so the app’s original signing and notification entitlements can be preserved. It requires an enterprise contract; contact us for availability and onboarding.

Troubleshooting

Direct APNs responses

APNs returns an HTTP status, an apns-id response header, and—for errors—a JSON reason. Preserve all three in your backend logs and test-endpoint response. See Apple’s APNs response reference for the complete status and reason list.

Common problems

Provider references