> ## 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.

# Native mobile screenshots

> Use toHaveScreenshot to catch visual regressions in native iOS and Android apps.

Use `expect(driver).toHaveScreenshot()` to compare a screenshot of the current native app screen against a stored baseline. This works for both iOS and Android.

For web and mobile web visual diffing, see [Web & Mobile web screenshots](/qawolf/visual-diffing).

```typescript theme={null}
expect(driver).toHaveScreenshot(name, options)
```

* `name` — string used to identify and store the baseline image
* `options` — optional object controlling comparison behavior, see Key options below

## Examples

**iOS**

```typescript theme={null}
await expect(driver).toHaveScreenshot(
  "home-screen",
  { maxMisMatchPercentage: 1 }
);
```

**Android**

```typescript theme={null}
await expect(driver).toHaveScreenshot(
  "home-screen",
  { maxMisMatchPercentage: 1 }
);
```

**Assert a specific element**

Pass a WebdriverIO element instead of `driver` to scope the screenshot to a specific UI component:

```typescript theme={null}
await expect(
  driver.$(`//android.widget.ImageView[@resource-id="com.example.app:id/hero_image"]`)
).toHaveScreenshot(
  "hero-image",
  { maxMisMatchPercentage: 1 }
);
```

<Warning>
  Omitting a name and `maxMisMatchPercentage` makes the baseline hard to identify and causes minor rendering differences to fail the test.

  ```typescript theme={null}
  // Avoid
  await expect(driver).toHaveScreenshot();
  ```
</Warning>

## When to use

* Your app has a rendering-heavy screen like a chart or map that can't be asserted with selectors.
* Your app has pixel-perfect design requirements and you want automated enforcement.
* Your app has gone through a redesign and you need to catch layout regressions.
* Your test needs to verify a visual state that no functional assertion can cover.

Avoid `toHaveScreenshot` when the screen contains timestamps, live data, animations, or other frequently-changing content — these cause false failures. Use a functional assertion instead.

## Key options

| Option                  | Description                                    | Recommended |
| ----------------------- | ---------------------------------------------- | ----------- |
| `maxMisMatchPercentage` | Percentage of pixels allowed to differ (0–100) | `1`         |
| `skipDiffUI`            | Skip the visual diff UI in the editor          | `false`     |

<Note>
  `maxMisMatchPercentage` is a 0–100 percentage, unlike the web API's `maxDiffPixelRatio` which is a 0–1 ratio.
</Note>

## Notes

* On the first run, no baseline exists yet — the screenshot is saved automatically as the expected image. Review it before relying on the test.
* To inspect a visual diff result in the editor, collapse the test block — an icon will appear in the right gutter of that line. Click it to open the Image Diff panel, where you can view the **Diff**, **Expected**, **Actual**, and **Compare** tabs for each named snapshot.
* On subsequent runs, a new screenshot is compared pixel-by-pixel to the baseline. If the difference exceeds the threshold, the test fails and a diff image is saved showing exactly which pixels changed.
* If a UI change is intentional, promote the new screenshot as the updated baseline in the QA Wolf editor. Future runs will compare against the new image.
* On iOS, baselines are named by device screen size (e.g. `home-screen-ios-390×844-expected.png`) — a baseline captured on an iPhone 15 will not match an iPhone 15 Plus.
* Baselines are stored in team storage under `_screenshots_` and are shared across all flows in the same team.

## Full sample test

```typescript theme={null}
import { expect, flow } from "@qawolf/flows/ios";

export default flow(
  "Visual regression — home screen",
  { target: "iOS - iPhone 15 (iOS 26)", launch: true },
  async ({ driver, test }) => {
    await test("assert home screen appearance", async () => {
      await expect(driver).toHaveScreenshot(
        "home-screen",
        { maxMisMatchPercentage: 1 }
      );
    });
  },
);
```
