# Test React Native and Expo Image Pickers on iOS and Android With Your AI Agent

> Seed images and videos into the photo library on iOS and Android, so your AI agent can test profile picture updates, uploads, attachments, and other flows through the media picker.

- Author: Ike Studios LLC
- Published: 2026-10-08
- Canonical: https://ceraph.dev/blog/test-image-picker-photo-library-react-native

---

Open the photo picker on a fresh iOS Simulator and the only photos are Apple's stock samples; an Android Emulator's gallery starts empty. Neither has your test fixtures: no HEIC from a real iPhone, no large panorama, no image with known content. That's a problem for every flow that starts with "choose a photo": a profile avatar, a listing with images, a chat attachment, a video upload, a document from the library. When an AI coding agent changes one of those screens, it can open the image picker and then has nothing to select.

The media picker needs known media in the device's photo library, and the test has to go through the real picker, because that's the path your users take. Ceraph does both. It's an [MCP](https://modelcontextprotocol.io) server that lets your AI coding agent drive and test a React Native or Expo app end-to-end. One tool call puts a specific image or video into the runtime's system photo library, and the agent then opens your app's real native picker and selects it like a person would. That works on iOS Simulators, physical iPhones, and Android emulators and phones.

## Adding photos to the iOS Simulator and Android Emulator by hand

If you want to seed a library yourself, the platform tools do it:

- **iOS Simulator:** `xcrun simctl addmedia booted photo.jpg` imports files into the booted Simulator's Photos library. You can also drag a file from Finder onto the Simulator window. Apple's forums have [reports of `addmedia` failing](https://developer.apple.com/forums/thread/714471) after a Simulator's media folder was deleted by hand.
- **Android Emulator:** push the file to shared storage with `adb push photo.jpg /sdcard/Pictures/`, then ask the media scanner to index it with `adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/Pictures/photo.jpg`. The scan step is where this usually breaks. Depending on the Android version and path, the file may not show up in the gallery until something rescans storage.

## How Ceraph seeds the photo library

`ceraph_add_media` adds one image or video to the selected runtime's system photo library. Your agent calls it before it opens the picker, then drives the app's real image or video picker UI.

- **Images:** JPEG, PNG, WebP, or HEIC, up to 5 MB.
- **Videos:** MP4, MOV, or M4V, up to 25 MB.
- **Runtimes:** iOS Simulators and physical iPhones, plus Android emulators and devices.

Added media stays in the library until it's deleted. Erasing a Simulator or emulator removes it along with everything else.

Because Ceraph puts the media in the system library and the agent uses the system picker, nothing in your app changes for the test. Any picker that reads the system photo library shows the media Ceraph added. `expo-image-picker`'s `launchImageLibraryAsync` and `react-native-image-picker` both open the system picker UI.

## Driving the real picker

The system picker isn't your app's React Native UI. It's iOS's or Android's own screen, presented over your app. The agent works it the way it works any screen: it reads what's showing with `ceraph_snapshot`, looks at the thumbnails with `screen_screenshot`, taps the seeded item with `screen_tap`, and confirms the selection. Then it's back in your app, checking what your code did with the file.

That last part is the point of the test. Picking is the easy half; the bugs live in what happens next: the crop screen that gets the aspect ratio wrong, the HEIC file your upload endpoint rejects, the video your compression step chokes on, the preview that never renders. With a known file going in, the agent can check each of those against a known expected result.

## Walkthrough: a profile photo flow

Say your Expo app lets users pick a profile photo, crop it to a square, and upload it. You've changed the upload code to resize images first, and you ask your agent to test the flow on the iOS Simulator.

1. **Seed the library.** The agent calls `ceraph_add_media` with `avatar.jpg`, a portrait photo with a known size.
2. **Bring the app up.** `ceraph_start` gets the development build running on the Simulator and ready to test.
3. **Open the picker.** The agent navigates to Edit Profile, with taps or `screen_open_url`, and taps **Choose photo**. Your app calls `launchImageLibraryAsync`, and the system picker opens.
4. **Pick the photo.** The agent finds the seeded image in the real picker and taps it, then confirms the crop.
5. **Verify the result.** Back in the app, `ceraph_snapshot` and `screen_screenshot` show whether the new avatar rendered on the profile screen.
6. **Read the errors.** If the resize threw or the upload returned a 500, `rn_get_errors` puts the error in the conversation. The agent reports the real failure and doesn't call the flow passed.

Swap the fixture and the same steps cover the edge cases worth testing: a HEIC from an iPhone, a large panorama, a video for an attachment field. Seed a second image and the agent can test multi-select too.

## Picker or camera?

Choosing from the library and capturing in the app are two different flows. If your screen captures through Expo Camera's `takePictureAsync` or `recordAsync`, Ceraph returns a registered test image or video right from the camera call. That's covered in [testing camera features on the iOS Simulator and Android Emulator](/blog/test-camera-ios-simulator-android-emulator). Many apps offer both on the same screen ("Take photo" or "Choose from library"), and the agent can test both paths in one session.

Try it on your picker flow: [get started](/docs/get-started).
