Documentation Index
Fetch the complete documentation index at: https://docs.qawolf.com/llms.txt
Use this file to discover all available pages before exploring further.
Camera injection is only available for apps that QA Wolf resigns during installation. It is not available for system apps or Safari.
Example
Inject an image into the camera feed:
import { device } from "@qawolf/flows/ios";
const bundleId = process.env.BUNDLE_ID; // Bundle ID of app being tested
const storagePath = process.env.STORAGE_PATH; // QA Wolf remote storage
const imagePath = `${storagePath}/large.jpg`;
const cleanup = await device.injectCamera(driver, bundleId, {
data: imagePath,
type: "image", // optional — inferred from .jpg/.png/etc.
});
// ... run your assertions while the camera feed is mocked ...
await cleanup();
Once the config is pushed, the camera preview updates to the injected image and loops continuously.
When to use
- Your app captures photos or displays a camera preview and you want to test that flow without a physical camera setup
- You need to run the same scenario repeatedly with consistent inputs
Supported file types
Images: Any format supported by UIImage — JPG, PNG, HEIC, GIF, BMP, TIFF, WebP
Full sample test
import { flow, device, expect } from "@qawolf/flows/ios";
export default flow(
"iOS Media - Camera Photo Injection",
{
target: "iOS - iPhone 15 (iOS 26)",
launch: {
app: { env: "IOS_APP_STAGING" },
respectSystemAlerts: true,
autoAcceptAlerts: true,
},
},
async ({ driver, test }) => {
await test("iOS Media - Camera Photo Injection", async () => {
//--------------------------------
// Arrange:
//--------------------------------
// Install and Launch Trot app
const imageName = "large.jpg";
const baseDir = process.env.BASE_IMAGE_DIR
const imagePath = `${baseDir}/${imageName}`;
// Tap "Media"
await driver
.$(
`-ios predicate string:name == 'Media' AND type == 'XCUIElementTypeButton'`,
)
.waitForDisplayed();
await driver
.$(
`-ios predicate string:name == 'Media' AND type == 'XCUIElementTypeButton'`,
)
.click();
// Tap Video Recording
await driver
.$(
`-ios predicate string:name == 'Video Recording' AND type == 'XCUIElementTypeButton'`,
)
.waitForDisplayed();
await driver
.$(
`-ios predicate string:name == 'Video Recording' AND type == 'XCUIElementTypeButton'`,
)
.click();
// Tap AVCaptureMovieFileOutput
await driver
.$(
`-ios predicate string:name == 'AVCaptureMovieFileOutput' AND type == 'XCUIElementTypeButton'`,
)
.waitForDisplayed();
await driver
.$(
`-ios predicate string:name == 'AVCaptureMovieFileOutput' AND type == 'XCUIElementTypeButton'`,
)
.click();
// Observe "Start Recording" button
await driver
.$(
`-ios predicate string:name == 'Start Recording' AND type == 'XCUIElementTypeStaticText'`,
)
.waitForDisplayed({ timeout: 10000 });
//--------------------------------
// Act:
//--------------------------------
// Inject image as the camera feed
await device.injectCamera(driver, process.env.APP_ID, {
data: `${imagePath}`,
type: "image",
});
await driver.pause(3000);
//--------------------------------
// Assert:
//--------------------------------
// Assert Screenshot of Image File Displaying in Live Preview
const previewElement = driver.$(
`-ios predicate string:name == 'livePreview' AND type == 'XCUIElementTypeOther'`,
);
await previewElement.waitForDisplayed({ timeout: 5000 });
await expect(driver)
.toHaveScreenshot(
previewElement,
"video_recording_image_preview",
{ maxMisMatchPercentage: 5 },
);
});
},
);