Test audio injection with Maestro on BrowserStack
Play an uploaded audio file into the device microphone during a Maestro test on BrowserStack App Automate.
Audio injection with Maestro is available on the Device Cloud Pro, Device Cloud Pro + Visual Cloud, and Enterprise Pro plans. Enabling audio injection adds about 20 seconds to session start time.
On BrowserStack App Automate, you can play an uploaded audio file into the microphone of a remote Android device during a Maestro test. Your app receives the audio as though someone spoke into the microphone. Use audio injection to automate flows such as voice search, voice commands, voice notes, and in-app recording.
You control when the audio plays from your flow. Inject the audio file, open the screen in your app that listens to the microphone, and then start playback.
Prerequisites
Before you start, make sure you have the following:
- Your BrowserStack username and access key, available in the Account & Profile section of your dashboard.
- An Android app as an
.apkfile. Audio injection doesn’t support iOS apps. - A Maestro test suite zipped inside a single parent folder, as described in Prepare your Maestro test suite.
- The audio file you want to play, in one of the supported formats listed in Upload your audio file to BrowserStack.
Supported devices
Audio injection runs on the Android devices in the following table:
| Supported devices | Android version |
|---|---|
| Samsung Galaxy S22 | 12 |
| Samsung Galaxy S22 Ultra | 12 |
| Samsung Galaxy S21 | 11 |
| Google Pixel 6 | 12 |
Run a Maestro test with audio injection
Complete the following steps to play an audio file into the device microphone during a Maestro test:
Upload your app and test suite
Upload your app and your zipped Maestro test suite, then note the app_url and test_suite_url that each response returns. You need both values to start a build. For the upload commands, see Execute Maestro tests.
Upload your audio file to BrowserStack
Upload the audio file you want to play using the following cURL command:
The response returns a media_url. This value is the media ID that you pass to your flow:
- Supported audio formats are
.mp3,.ogg,.aac, and.wav. - The maximum file size is 15 MB for
.mp3,.aac, and.oggfiles, and 100 MB for.wavfiles. - Uploaded files remain on BrowserStack servers for 30 days.
Add the BrowserStack executor script to your test suite
Maestro doesn’t use the WebDriver protocol, so Maestro flows have no JavaScript executor of the kind that Appium tests use. BrowserStack provides a script that your flow calls with the runScript command instead. If you already added this script for camera image injection, reuse the same file.
At the root of your test suite’s parent folder, create a folder named bstack and save the following script as browserstack_executor.js:
Your test suite now has the following structure:
sample_parent_folder/
├── bstack/
│ └── browserstack_executor.js
├── flow1.yaml
└── flow2.yaml
Don’t edit browserstack_executor.js. The script reads the values that BrowserStack sets on the test session. Everything that varies between calls comes from the env block in your flow.
Keep the bstack folder inside the parent folder that you zip, alongside your flow files. If the bstack folder sits outside the parent folder, the runScript step can’t resolve the path to the script. For the required layout, see Prepare your Maestro test suite.
Play the audio from your flow
Audio injection uses three actions: inject_audio, play_audio, and stop_audio. To play an audio file, your flow runs the following steps in order:
-
inject_audioloads your uploaded audio file onto the device. - Your flow opens the screen in your app that listens to the microphone.
-
play_audiostarts playing the audio into the microphone. - Your flow waits until your app processes the audio.
play_audio returns as soon as playback starts. It doesn’t wait for the audio to finish, so make sure your app is already listening before this step runs. Playback stops on its own at the end of the file, so you don’t need stop_audio to play the full clip.
The following flow shows each step:
The env block of each runScript step sets the following values:
-
BROWSERSTACK_EXECUTOR_ACTIONnames the action to run:inject_audio,play_audio, orstop_audio. -
MEDIA_IDis themedia_urlthat the media upload returns. Only theinject_audioaction takes aMEDIA_ID.
Before the play_audio step, add the steps that open the microphone in your app and accept any microphone permission prompt. For more information, see Handle permission popups.
To let your app hear the full clip, add an extendedWaitUntil step after play_audio that waits for an element your app shows after it processes the audio. Set timeout, in milliseconds, longer than the length of your audio file. Maestro has no fixed-duration wait.
To cut playback short while the audio is still playing, add a stop_audio step:
Run stop_audio only while the audio is still playing. If stop_audio runs after the audio has ended, the step fails with No audio is currently playing. and your flow stops.
To play a different audio file later in the same flow, add another inject_audio step with a different MEDIA_ID, followed by play_audio.
Run your test with audio injection
Set enableAudioInjection to true when you start the build:
The following table describes the audio injection parameter:
| Parameter | Type | Description |
|---|---|---|
enableAudioInjection |
Boolean | Set to true to allow your flow to play audio files on the device during the test session. Required for audio injection. |
Audio injection on Maestro has the following limitations:
- Audio injection runs on the Android real devices listed in Supported devices only, not on iOS devices or emulators.
- A session that doesn’t set
enableAudioInjectionrejects every audio action.
Check the injection result in your logs
Every call to browserstack_executor.js writes a status line to your Maestro logs. A successful call shows a line such as the following:
[EXECUTOR] action=play_audio status=200
A failed call adds a reason to the same line and stops the flow. The following reasons are the most common:
-
media_not_found: BrowserStack can’t find theMEDIA_IDin your flow. Check that the media ID matches themedia_urlthat the upload returned. -
executor_unreachable: the flow couldn’t reach the BrowserStack injection service. -
scope_denied: the build didn’t setenableAudioInjection, so the session doesn’t allow audio injection.
A stop_audio step that runs after the audio has ended fails with HTTP status 400 and the message No audio is currently playing.
To read these lines, see Maestro logs.
Frequently asked questions
Does audio injection work on iOS devices?
No. Audio injection with Maestro supports Android devices only.
Do I need to change my app code?
No. Audio injection doesn’t patch or re-sign your app.
Related topics
- Test camera image injection with Maestro
- Prepare your Maestro test suite
- Maestro builds API reference
We're sorry to hear that. Please share your feedback so we can do better
Contact our Support team for immediate help while we work on improving our docs.
We're continuously improving our docs. We'd love to know what you liked
We're sorry to hear that. Please share your feedback so we can do better
Contact our Support team for immediate help while we work on improving our docs.
We're continuously improving our docs. We'd love to know what you liked
Thank you for your valuable feedback!