2.5 KiB
mock-geolocation
Purpose
mockGeolocation pins a Playwright page to a fixed { latitude, longitude } so tests that exercise location-aware features (maps, "find nearest store", distance calculations) see deterministic input regardless of the host machine's actual location or whether the CI runner has a geolocation permission at all. It wraps Playwright's context.grantPermissions(["geolocation"]) + context.setGeolocation(...) into a single call that also deals with the context-vs-page ambiguity.
Features
- Grants
geolocationpermission on the enclosing browser context - Sets a fixed coordinate pair
- Accepts an optional
accuracyfor the emulated reading (meters) - Safe to call multiple times — later calls replace earlier coordinates
Usage: Basic Example
import { mockGeolocation } from "@suaveplan/testing-e2e/helpers";
await mockGeolocation(page, { latitude: 51.5074, longitude: -0.1278 });
await page.goto("/map");
Usage: Advanced Example
import { mockGeolocation } from "@suaveplan/testing-e2e/helpers";
import { expect } from "@playwright/test";
test("distance widget uses my location", async ({ page }) => {
await mockGeolocation(
page,
{ latitude: 40.7128, longitude: -74.0060, accuracy: 5 }
);
await page.goto("/stores");
await expect(page.getByRole("heading", { name: /nearest store/i }))
.toBeVisible();
await expect(page.getByTestId("distance")).toContainText("mi");
// Re-pin for a different test scenario.
await mockGeolocation(page, { latitude: 34.0522, longitude: -118.2437 });
await page.reload();
await expect(page.getByTestId("distance")).toContainText("mi");
});
API Reference
mockGeolocation(page, coords): Promise<void>
page: Pagecoords.latitude: numbercoords.longitude: numbercoords.accuracy?: number— default 10 (meters)- Returns
Promise<void>once the permission grant + coordinate set both resolve
Implementation Notes
Playwright distinguishes context-level and page-level geolocation; the helper works against the context behind the supplied page so the permission grant covers every page in the same context. That matters for tests that open popups or child windows — without context-level granting, the child windows see the stock "permission denied" behaviour. The accuracy default of 10 meters matches the order of magnitude returned by a real GPS fix and is specific enough to distinguish "pinned by a test" from "real device" if the app logs it.