Skip to main content

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: WAV

Full 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);

    });
  },
);
Last modified on May 13, 2026