Skip to content

Latest commit

 

History

History
121 lines (91 loc) · 3.38 KB

android-location-mocking.mdx

File metadata and controls

121 lines (91 loc) · 3.38 KB
title Mock device location (Android)
description Set a custom GPS location on the Android emulator to test location-aware features in your app.
sidebarTitle Android
tag Emulator only

Use device.setGeoLocation() to override the emulator's GPS coordinates during a flow. This lets you test location-aware features — such as store finders, delivery zones, or region-specific content — without physically moving a device.

Location mocking works on emulators only, not on real Android phones.

See the Android Device Controls for the full setGeoLocation API.

Examples

Set a GPS location

await device.setGeoLocation({
  latitude: 40.78222,
  longitude: -73.96528,
});

When to use

  • Your app shows location-aware content such as store finders, delivery zones, or regional pricing.
  • Your app restricts features by geography and you need to test from a specific location.
  • Your app uses GPS coordinates to personalize content and you need to assert on that behavior.
  • Your test needs to simulate a device in a different city or country.

Troubleshooting

Some apps don't immediately respond to a location change. Try one or more of the following.

Grant location permissions automatically

Pass autoGrantPermissions: true in your launch options.

const { driver } = await launch({
  appPackage: "com.example.app",
  autoGrantPermissions: true,
});

Toggle location services

await driver.toggleLocationServices();
await driver.toggleLocationServices();

Reload the session

await device.setGeoLocation({
  latitude: 40.78222,
  longitude: -73.96528,
});

await driver.reloadSession();

Prime location tracking via Google Maps

Some apps rely on the system location provider being active. Open Google Maps and trigger location tracking before your app reads the location, then reload the session.

await driver.activateApp("com.google.android.apps.maps");

const skipBtn = driver.$(`//android.widget.Button[@text='SKIP']`);
if (await skipBtn.isExisting()) {
  await skipBtn.click();
}

const locationBtn = driver.$(
  `//android.widget.FrameLayout[@resource-id='com.google.android.apps.maps:id/mylocation_button']`,
);
const contentDesc = await locationBtn.getAttribute("content-desc");
if (contentDesc.includes("Re-center")) {
  await locationBtn.click();
}

const permissionBtn = driver.$(
  `//android.widget.Button[@resource-id='com.android.permissioncontroller:id/permission_allow_foreground_only_button']`,
);
if (await permissionBtn.isExisting()) {
  await permissionBtn.click();
}

await driver.reloadSession();

Full sample test

import { device, flow, launch } from "@qawolf/flows/android";

export default flow(
  "Test location feature",
  { target: "Android - Any Phone (Latest | Emulator)", launch: true },
  async ({ driver, test }) => {
    await test("set location and verify location-based content", async () => {
      // Arrange
      await driver.$(`//*[@text='Find Stores']`).click();

      // Act
      await device.setGeoLocation({
        latitude: 40.78222,
        longitude: -73.96528,
      });

      // Assert
      await driver
        .$(`//*[@text='Stores near Central Park']`)
        .waitForDisplayed({ timeout: 10_000 });
    });
  },
);