Skip to main content
No Result Found
Get your setup working faster. Join our Discord for optimisation tips from elite testers. Join our DiscordJoin our Discord

Test camera image injection with Maestro on BrowserStack

Replace the device camera feed with your own image during a Maestro test on BrowserStack App Automate.

This feature is available only under Device Cloud Pro, Device Cloud Pro + Visual Cloud, and Enterprise Pro plans. For more details, check out our pricing page.

On BrowserStack App Automate, you can replace the live camera feed in a Maestro test with an image that you upload. Your app reads the injected image as though the camera captured the image. Use camera image injection to automate flows that scan a QR code, read a barcode, or capture a document.

You choose which image to inject at each step. A single flow can scan several images in sequence, such as the front and the back of an identity document.

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 .apk file, or an iOS app as an .ipa file.
  • A Maestro test suite zipped inside a single parent folder, as described in Prepare your Maestro test suite.
  • The image you want to inject, as a JPG, JPEG, or PNG file of up to 10 MB.

How BrowserStack enables camera testing

BrowserStack uses Sensor Instrumentation to let your app interact with device sensors, such as the camera. When you enable camera image injection, BrowserStack adds a camera module to the app you upload. The camera module overrides the camera APIs that your app calls in the Android or iOS SDK, so your app receives the uploaded image instead of a live camera frame.

Your source code stays unchanged. BrowserStack modifies only the copy of the app that runs in the test session.

Camera or barcode image injection doesn’t support:

  • iOS apps signed with Enterprise certificates. These apps have the browserstack.resignApp capability set to false, but camera image injection requires this capability to be true.
  • Capturing media types other than images, such as video, from the camera.
  • Android apps that use code obfuscation tools like Proguard.

Supported APIs and OS versions

Camera image injection supports the camera APIs in the following table. Check with your app development team to confirm which camera APIs your app uses:

OS OS version Supported APIs
iOS iOS 13 and above - didFinishPickingMediaWithInfo API of UIImagePickerController iOS SDK class for capturing an image. For more information, see the Apple Documentation for UIImagePickerControllerDelegate.

- AVCapturePhoto iOS SDK class for receiving captured photos from AVCapturePhotoOutput API. For more information, see the Apple Documentation for AVCapturePhoto.

- jpegStillImageNSDataRepresentation of AVCaptureStillImageOutput iOS SDK class. For more information, see the Apple Documentation for AVCaptureStillImageOutput.
Android Android 6 and above - android.hardware.camera.PreviewCallback API for API level 1-20

- android.hardware.camera2.CameraManager, android.hardware.camera2.CameraDevice, android.hardware.camera2.CameraCharacteristics, android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.media.ImageReader APIs for API level >=21

- com.google.android.gms.mlkit.ACTION_SCAN_DOCUMENT for document scanning

- Camera Intent API

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 image to BrowserStack

Upload each image you want to inject using the following cURL command:

Terminal
Copy icon Copy

The response returns a media_url. This value is the media ID that you pass to your build and to your flow:

Copy icon Copy

A single build accepts up to five media IDs.

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.

At the root of your test suite’s parent folder, create a folder named bstack and save the following script as browserstack_executor.js:

bstack/browserstack_executor.js
Copy icon Copy

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.

Inject the image from your flow

Add a runScript step to your flow at the point where the uploaded image must become the camera’s next frame. Add the step before your app opens the camera, because the camera captures the image that was injected most recently:

flow1.yaml
Copy icon Copy

The env block sets the following two values:

  • BROWSERSTACK_EXECUTOR_ACTION names the action to run. Use inject_image for camera image injection.
  • MEDIA_ID is the media_url that the media upload returns. Pass a media ID that you also list in cameraInjectionMedia when you start the build.

To capture a second image later in the same flow, add another runScript step with a different MEDIA_ID. A flow can inject as often as your plan limits allow, as long as you list every MEDIA_ID in cameraInjectionMedia.

Run your test with camera image injection

Set enableCameraImageInjection to true and list your uploaded images in cameraInjectionMedia. Select the platform you test on:

Terminal
Copy icon Copy

The following table describes the camera image injection parameters:

Parameter Type Description
enableCameraImageInjection Boolean Set to true to add the camera module to your app for the test session. Required for camera image injection.
cameraInjectionMedia Array of strings Lists the media IDs that your flow can inject, as returned by the media upload. Accepts up to five media IDs. Required for camera image injection.

Camera image injection on Maestro has the following limitations:

  • Camera image injection runs on real devices only, not on emulators or simulators.
  • A build must set enableCameraImageInjection and cameraInjectionMedia together. BrowserStack rejects a build that sets one parameter without the other.
  • cameraInjectionMedia accepts up to five media IDs per build.

Check the injection result in your logs

Every call to browserstack_executor.js writes a status line to your Maestro logs. A successful injection shows the following line:

[EXECUTOR] action=inject_image status=200

A failed injection adds a reason to the same line and stops the flow. The following reasons are the most common:

  • media_not_found: the MEDIA_ID in your flow isn’t one of the media IDs listed in cameraInjectionMedia.
  • executor_unreachable: the flow couldn’t reach the BrowserStack injection service.
  • scope_denied: the build didn’t set enableCameraImageInjection, so the session doesn’t allow injection.

To read these lines, see Maestro logs.

Frequently asked questions

No. BrowserStack modifies the app you upload, so your source code stays unchanged.

Yes. Add a runScript step wherever the flow needs a new image. The camera captures the image that was injected most recently. As a result, a flow that scans both sides of a document injects once before each capture.

Camera image injection supports Android and iOS apps, including cross-platform apps. Your app must use a camera API listed in Supported APIs and OS versions.

Yes. Maestro also supports video injection, audio injection, biometric authentication, and setting the device timezone.
If you need help configuring your test suite, write to support@browserstack.com.

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

Is this page helping you?

Yes
No

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!

Talk to an Expert
Download Copy Check Circle