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.

Helpers for platform differences

For platform-specific implementation differences that don’t fit neatly into a Page Object — such as log capture, where iOS uses "safariConsole" and parses JSON while Android uses "browser" with logging preferences — write a helper function that handles the difference internally. The flow calls the helper and stays linear.
// /src/helpers/console-logs-ios.ts
export async function getConsoleLogs(driver: WebdriverIO.Browser) {
  const raw = await driver.getLogs("safariConsole");
  return raw.map((entry) => JSON.parse(entry.message));
}

//helpers/console-logs-android.ts
export async function getConsoleLogs(driver: WebdriverIO.Browser) {
  const raw = await driver.getLogs("browser");
  return raw.map((entry) => entry.message);
}
Module-level code should be limited to imports, constants, and pure helper functions. Runtime APIs like launch(), expect, device, and platform.target only work inside the flow callback — calling them at the module level will throw.

Use platform-specific entry points

Rather than writing one flow that handles multiple platforms, write separate flows using the entry point for each platform. The device API surface is consistent across platforms, so the flows look similar even though they run on different infrastructure.
// /src/flows/set-location-android.ts
import { device, flow } from "@qawolf/flows/android";

export default flow(
  "Set location",
  { target: "Android - Pixel 9", launch: true },
  async ({ driver, test }) => {
    await test("set device location", async () => {
      await device.setGeoLocation({ latitude: 37.7749, longitude: -122.4194 });
    });
  },
);
// /src/flows/set-location-ios.ts
import { device, flow } from "@qawolf/flows/ios";

export default flow(
  "Set location",
  { target: "iOS - iPhone 15 (iOS 26)", launch: true },
  async ({ driver, test }) => {
    await test("set device location", async () => {
      await device.setGeoLocation({ latitude: 37.7749, longitude: -122.4194 });
    });
  },
);

Use environment variables to parameterize flows

Environment variables let the same flow run against different environments without code changes. Reference them with process.env.VAR_NAME.
await page.goto(process.env.BASE_URL);
See Environment setup for how to configure environment variables in QA Wolf.

Pass data between flows

Use inputs and setOutput to share data between flows in the same run — for example, passing a user ID created in one flow to another flow that needs to log in as that user. See Passing data between flows for the full model.

platform.target for edge cases

For rare cases where a single flow genuinely needs to branch on the active platform at runtime, use platform.target from the top-level @qawolf/flows package.
import { platform } from "@qawolf/flows";

if (platform.target.startsWith("iOS - ")) {
  // iOS-specific step
}
Use this sparingly. If you find yourself branching on platform.target frequently, consider splitting into platform-specific flows instead. See the Top-Level Reference for the full platform API.
Last modified on May 6, 2026