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.
Audio injection is only available for apps that QA Wolf resigns during installation. It is not available for system apps or Safari.
Example
import { device } from "@qawolf/flows/ios";
// Inject Audio
const bundleId = process.env.BUNDLE_ID; // Bundle ID of app being tested
const storagePath = process.env.STORAGE_PATH; // QA Wolf remote storage
const audioPath = `${storagePath}/sample_audio_input.wav`;
const cleanup = await device.injectAudio(driver, bundleId, {
data: audioPath,
});
// ... run your assertions while audio is being injected ...
await cleanup();
// Then trigger microphone input in your test
When to use
- Your app records audio or processes microphone input and you need to test that flow with known audio data.
- You need to run the same scenario repeatedly with consistent inputs.
Supported file types
Audio: WAVFull sample test
import { flow, device } from "@qawolf/flows/ios";
export default flow(
"iOS Media - Audio Injection",
{
target: "iOS - iPhone 15 (iOS 26)",
launch: {
app: { env: "IPA_BUILD_LOCATION" },
respectSystemAlerts: true,
autoAcceptAlerts: true,
},
},
async ({ driver, test }) => {
await test("iOS Media - Start App and Inject Audio to microphone", async () => {
//--------------------------------
// Arrange:
//--------------------------------
// Install and Launch Trot app
// Inject Audio
const fsPromises = await import("node:fs/promises");
const bundleId = process.env.BUNDLE_ID;
await device.injectAudio(driver, bundleId, {
data: "/home/wolf/team-storage/ios-trot/sample_audio_input.wav",
});
// 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 Audio Recording
await driver
.$(
`-ios predicate string:name == 'Audio Recording' AND type == 'XCUIElementTypeButton'`,
)
.waitForDisplayed();
await driver
.$(
`-ios predicate string:name == 'Audio Recording' AND type == 'XCUIElementTypeButton'`,
)
.click();
// Tap to start recording
await driver
.$(
`-ios predicate string:name == 'recordingIcon' AND type == 'XCUIElementTypeImage'`,
)
.waitForDisplayed();
await driver
.$(
`-ios predicate string:name == 'recordingIcon' AND type == 'XCUIElementTypeImage'`,
)
.click();
await driver.pause(15000);
// Tap to stop recording
await driver
.$(
`-ios predicate string:name == 'recordingIcon' AND type == 'XCUIElementTypeImage'`,
)
.waitForDisplayed();
await driver
.$(
`-ios predicate string:name == 'recordingIcon' AND type == 'XCUIElementTypeImage'`,
)
.click();
// Get the file name
await driver
.$(
`-ios predicate string:name BEGINSWITH 'AudioRecording_' AND type == 'XCUIElementTypeStaticText'`,
)
.waitForDisplayed();
const fileName = await driver
.$(
`-ios predicate string:name BEGINSWITH 'AudioRecording_' AND type == 'XCUIElementTypeStaticText'`,
)
.getValue();
// Pull file from the phone
const targetBaseDir = process.env.TARGET_STORAGE_BASE_DIR
const storageDir = process.env.STORAGE_DIR
const recordingAsBase64 = await driver.execute("mobile: pullFile", {
remotePath: `@${bundleId}:${targetBaseDir}/${fileName}`,
});
// write into a file
const m4aRecording = Buffer.from(recordingAsBase64, "base64");
const recordingSavingPath = `${storageDir}/${fileName}`;
await fsPromises.writeFile(recordingSavingPath, m4aRecording);
});
},
);