Skip to main content
Geolocation Testing

Sep 22, 2026

Geolocation Testing With Proxies and Playwright: Country and City Checks

Build a Playwright geolocation test that verifies proxy country and city, configures locale and timezone, checks localized content, and saves evidence.

Geolocation Testing With Proxies and Playwright: Country and City Checks

Geolocation testing verifies what a website actually shows from a selected market. A useful test does more than open a page through a country-targeted proxy: it confirms the browser's public exit location, applies the intended locale and timezone, checks visible currency or regional content, and saves enough evidence to reproduce a failure.

This tutorial builds that workflow with Playwright and a residential proxy. It is designed for teams testing websites they own or are authorized to test. If you need the commercial overview rather than implementation code, see Proxies for localized testing.

Quick Answer

To run geolocation testing with Playwright, create one isolated BrowserContext for each market and give it five separate inputs:

  1. A proxy route for the expected country or city.
  2. A browser locale such as en-US or de-DE.
  3. An IANA timezone such as America/New_York or Europe/Berlin.
  4. Optional latitude and longitude for the browser Geolocation API.
  5. Target-specific assertions for currency, market labels, redirects, availability, or localized copy.
bash

The proxy controls the network route and public exit IP. It does not automatically change navigator.language, the browser timezone, GPS coordinates, cookies, account country, device type, or viewport. Playwright controls those browser signals separately.

Use a Sticky route for one coherent test so the exit does not intentionally rotate between the location check and target page. Use a fresh browser context and, when appropriate, a new route for the next independent market. Treat country as a strict assertion. Treat city as a warning by default unless the target, proxy supply, and chosen IP-location databases support a strict city requirement.

Key Takeaways

  • IP location, locale, timezone, and browser coordinates are different signals. Configure and verify each one separately.
  • Check the exit before testing the target. A dashboard setting proves the requested configuration, not what an external service or the target observed.
  • Use one Sticky route per coherent workflow. Rotating midway through a cart, login, redirect chain, or localization check changes the network variable.
  • Country checks are generally stronger than city checks. IP-location databases can map the same address to different nearby cities or regions.
  • Validate visible behavior, not only network metadata. A correct country code does not prove that the target displayed the correct currency, language, store, tax, or offer.
  • Keep browser state isolated by market. Reusing cookies or storage can override IP-based localization and produce misleading results.
  • Save reproducible evidence. Record the expected and observed signals, final URL, timestamp, assertion results, screenshot, and start/end exit checkpoints.
  • A proxy changes routing, not the device. Mobile-device emulation, viewport, user agent, and touch behavior remain separate Playwright settings.

What Does a Geolocation Test Actually Measure?

Websites can use several signals to decide which regional experience to show. A good test identifies who controls each signal instead of treating “location” as one setting.

SignalControlled byExampleHow to verify it
Public exit IP and inferred country/cityProxy route and IP-location dataUS, New YorkQuery an independent IP-location service inside the proxied browser context
Browser localePlaywright `locale``en-US`Read `navigator.language` and check the `Accept-Language` behavior where relevant
Browser timezonePlaywright `timezoneId``America/New_York`Read `Intl.DateTimeFormat().resolvedOptions().timeZone`
Browser coordinatesPlaywright `geolocation` plus permissionLatitude and longitudeRead `navigator.geolocation` on the authorized target origin
Website marketTarget application, URL, cookies, account, and IPUS storeAssert the visible market selector, final URL, or store label
Currency and formattingTarget application plus locale and market stateUSD and `$1,234.56`Assert the price element and, if needed, its structured data
Device and viewportPlaywright device emulationDesktop or mobile layoutInspect viewport, user agent, and the rendered result

The official Playwright Browser API documents proxy, locale, timezoneId, permissions, viewport, and other context options. The BrowserContext API documents geolocation and permission controls. These are separate because they represent separate parts of the environment.

A matching configuration is not the same as a passing test. The test passes only when the network and browser observations match the intended profile and the target produces the expected localized result.

Country Checks vs City Checks

Country and city assertions should not use identical confidence rules.

Country-level IP classification is appropriate for a strict first gate in most localization tests. If a test requests a German route but an independent service reports a US exit, stop before using the target result as evidence for Germany.

City-level classification is more approximate. IP-location products commonly expose an accuracy radius or a confidence field because an IP address does not provide GPS-level precision. The MaxMind IP geolocation data model is one example: its city data can include both a confidence score and an accuracy radius.

Use one of these policies:

City policyBehaviorAppropriate when
WarningRecord a mismatch but continue to target assertionsCity is useful context, but country and visible content determine the decision
StrictFail if the normalized city label does not matchThe application rule truly depends on the named city and the locator has been validated for the selected pool
Multi-sourceCompare two independent location databases before failingA city classification has material release or compliance impact
Target-evidenceValidate a store, delivery area, branch, or city-specific page instead of relying only on an IP databaseThe website's own behavior is the outcome that matters

The code below makes country strict and city optional. Set strictCity to true only when an exact city-label match is a justified test requirement.

Prerequisites

You need:

  • Node.js in a version supported by your installed Playwright release.
  • Playwright and its Chromium browser binary.
  • A residential proxy access point configured for the required country and, if needed, city.
  • Sticky session behavior for each coherent test run.
  • A public page or application that you own or are authorized to test.
  • Stable selectors and expected values for the localized result.
  • A secrets workflow that can provide the proxy server, username, and password at runtime.

Install the current Playwright test package and Chromium:

bash

Each Playwright release needs compatible browser binaries, so rerun the browser-install command after upgrading. The official Playwright browser documentation describes that version relationship.

In Proxidize, create a Residential Proxy access point for the required country and city, then select Sticky session behavior. The current residential product supports country, city, and ISP targeting with rotating or Sticky sessions. The residential proxy setup guide explains how to generate credentials and choose the session mode.

Do not paste proxy credentials into the source file, a committed .env file, screenshots, build logs, or a public report. Load PROXY_SERVER, PROXY_USERNAME, and PROXY_PASSWORD through your existing secrets manager, CI secret store, or protected runtime environment.

Step 1: Create a Market Profile

Keep non-secret test inputs in a JSON profile. This makes the same runner reusable for New York, London, Berlin, or any other approved market without mixing credentials into the configuration.

Save this as profiles/us-new-york.json and replace the target URL, selectors, and expected text with values from the application you are authorized to test:

json

The example uses ipapi.co's documented JSON endpoint for a convenient independent observation. Public diagnostic services have their own limits, terms, databases, and availability. For production, use an approved service and do not make one third-party database your only evidence for a material city-level decision.

The latitude and longitude in this file configure the browser Geolocation API. They do not change the proxy exit. When coordinates are present, the runner requires the page to read them successfully and compares the returned point with the configured point using coordinateToleranceMeters. Omit both fields if the target does not use browser coordinates.

Step 2: Run the Playwright Geolocation Test

Save the following as geolocation-check.mjs. It does seven things:

  1. Loads the non-secret market profile.
  2. Creates a browser context with the proxy, locale, timezone, and optional coordinates.
  3. Verifies the public exit before visiting the target.
  4. Stops before target navigation if the country—or a strict city check—does not match.
  5. Uses retrying assertions for browser and target-visible signals.
  6. Checks the exit again after the target workflow.
  7. Writes a full-page screenshot and structured JSON report, including on runtime failure when possible.
javascript

Run it after your secrets workflow has populated the three proxy variables:

bash

The script intentionally does not print the proxy server, username, or password. It does record the observed exit IP because that is useful internal test evidence. Redact or hash that value before publishing a report if your security policy treats exit addresses as sensitive.

Step 3: Read the Report Correctly

A passing report should answer three separate questions.

1. Did the network route match the requested market?

The network.country check records the independent service's classification of the browser's exit. The network.city check records the exact normalized city-label comparison and whether that result was required. A country failure—or a required city failure—stops the run before the target receives a request.

network.sameExitAtCheckpoints means only that the two checkpoints saw the same address. It does not prove that every intervening subrequest used that exit. A HAR is useful for request and response debugging, but its server address describes the destination and does not prove which public proxy exit reached the target. For that evidence, use target-side request logs on an application you control or an approved endpoint that records the client address it observed.

2. Did the browser environment match the profile?

The browser.locale and browser.timezone checks verify the values visible through the browser APIs. When coordinates are configured, browser.coordinates is required: the page must read a position successfully, and the returned point must fall within coordinateToleranceMeters of the configured point.

These checks do not establish the network location. A browser can report Europe/Berlin while using a US exit, or report en-US while using a German exit. That inconsistency is precisely why each signal is verified independently.

3. Did the target show the intended regional experience?

The target checks use Playwright's auto-retrying toContainText assertion, so they wait for the expected result instead of reading a value once immediately after visibility. Every target check is recorded as passed, failed, or skipped. An omitted expectation is skipped rather than treated as successful, and the profile must configure at least one target-content assertion. For price tests, use a market assertion plus an explicit currency code or a known localized price; a bare $ symbol is ambiguous.

The final URL, HTTP status, screenshot, expected text, and observed text make a failure easier to reproduce. If an exception interrupts the run, the global error handler still writes a failure report and attempts a screenshot before closing an open target page.

Do not treat a 200 OK response as a successful localization test. A page can return 200 while showing the wrong country, default currency, unavailable-product message, consent banner, or fallback language.

Configure Locale, Timezone, and Coordinates Separately

The profile aligns several browser signals, but each setting does a different job.

Locale

Playwright's locale setting affects navigator.language, the Accept-Language request header, and browser-side number and date formatting. It does not force the application to use that language; the target may prioritize a URL segment, saved cookie, account setting, or explicit language selector.

javascript

Timezone

timezoneId changes the timezone exposed by the browser context. Use an IANA identifier and assert the resolved value.

javascript

Timezone matters for date labels, booking cutoffs, delivery estimates, trading hours, event availability, and campaigns that begin or end at local midnight. It does not change the IP address.

Browser coordinates

Playwright can provide coordinates to pages that request the browser Geolocation API. The page also needs geolocation permission.

javascript

Coordinates are useful when an authorized application explicitly asks for browser location. They do not move the proxy exit, change the account region, or reproduce a physical device's complete sensor environment.

Device emulation

A proxy also does not turn desktop Chromium into a phone. Use Playwright device and viewport options when the test covers mobile layout or browser behavior. Keep that dimension separate in the test matrix so a network failure is not confused with a responsive-layout failure.

Verify Currency and Localized Content

Currency is a result, not a reliable standalone location detector. A website may select it from the URL, a market picker, account profile, cookie, payment country, shipping address, or IP location.

For each market, define explicit assertions for the parts of the user experience that matter:

Result to validateStrong evidenceWeak evidence on its own
Market selectionVisible country/store label and final URLExit country alone
CurrencyPrice element with expected ISO code or symbol and correct amountBrowser number formatting only
LanguageVisible target copy plus document language where meaningful`navigator.language` alone
AvailabilityProduct or service availability messagePage loaded with HTTP 200
ShippingDestination-specific delivery text or eligible methodsGeneric footer country selector
RedirectExpected final URL with required query parameters preservedOne intermediate response
Legal or consent contentMarket-specific visible noticeScreenshot without machine-readable assertion

Use stable attributes such as data-testid on applications you control. Avoid brittle selectors based only on layout or generated class names. If the site exposes structured product data, compare it with the visible result instead of trusting either source independently.

Currency symbols can be ambiguous: $ may mean USD, CAD, AUD, or another dollar-denominated currency. Prefer an ISO code or pair the symbol with the selected market and a known localized price.

Test Multiple Markets Without Mixing State

Create a separate profile and browser context for each market. Do not reuse one context across countries unless the purpose of the test is to measure how an existing user behaves after changing location.

Test profileProxy targetLocaleTimezoneExample output checks
US New YorkUnited States, New York`en-US``America/New_York`US store, USD, local availability
UK LondonUnited Kingdom, London`en-GB``Europe/London`UK store, GBP, UK shipping
Germany BerlinGermany, Berlin`de-DE``Europe/Berlin`German content, EUR, German notice

For each profile:

  1. Create or select the corresponding proxy access point.
  2. Start a fresh browser context.
  3. Verify the exit inside that context.
  4. Visit the target without importing unrelated cookies or storage.
  5. Run the market-specific assertions.
  6. Save a report and screenshot.
  7. Close the context before starting the next market.

Cookies and account state can legitimately override location. If returning-user behavior matters, maintain a deliberate state fixture for that scenario and label the result accordingly. Do not silently reuse state from the previous market.

For independent large-scale checks, rotate between completed profiles or tasks. For multi-page workflows, keep one Sticky route for the complete unit of work. The Playwright rotating proxy guide explains why a browser context is the practical rotation boundary.

Troubleshooting Geolocation Tests

SymptomLikely causeWhat to check
Exit country is wrongWrong access point, wrong targeting selector, direct connection, or locator disagreementConfirm the generated credential, remove unintended proxy bypass rules, and compare an approved second locator
Country matches but city does notCity-level database variance, nearby network registration, or supply changeTreat the result as a warning, inspect accuracy/confidence data, and validate target-visible city behavior
Exit changes during one testRotating route, expired Sticky assignment, shared credential policy, or reconnect behaviorUse a Sticky access point for the work unit and record start/end checkpoints
`navigator.language` is wrongLocale was not set on the context that created the pageSet `locale` in `browser.newContext()` before creating the page
Browser timezone is wrongInvalid or unintended timezone identifierUse an IANA timezone and read the resolved value inside the page
Browser geolocation is deniedPermission was not granted, coordinates were omitted, or the page context does not permit the requestSet coordinates and geolocation permission before navigation; test on an appropriate secure origin
Correct exit but wrong currencyCookie, account, URL, store selector, shipping country, or application rule overrides IPStart with fresh state and inspect the target's market-selection logic
Correct currency but wrong languageCurrency and language are controlled independentlyAssert both and check URL, cookie, account, and `Accept-Language` precedence
Target shows stale regional contentCDN, service worker, application cache, or reused browser stateUse a fresh context, inspect response headers, and compare with application-side logs
Proxy authentication returns 407Missing, expired, or incorrectly separated credentialsVerify the server, username, and password generated by the provider
Test passes locally but fails in CIDifferent secrets, egress rules, browser version, timezone defaults, or selectorsPin Playwright, install the matching browser, and compare sanitized reports from both environments
Target assertion fails after delayed renderingContent changed after initial navigation or the selector is wrongUse retrying assertions, stable selectors, and a timeout appropriate to the authorized application
Failure report has no screenshotThe run failed before a target page existed, or screenshot capture also failedCheck `failurePhase`, `error`, and `evidence.screenshotError`; preflight failures should still have a JSON report

When debugging a general Playwright proxy connection, start with the Playwright proxy guide for Python and Node.js. It covers authentication, browser and context scope, HTTP and SOCKS5 behavior, IP checks, Docker, and common proxy errors.

Residential or Mobile Proxies for Geolocation Testing?

Residential proxies are the default for broad country and city testing. Proxidize Residential Proxies cover 195+ countries and support country, city, and ISP targeting, so they fit international price, content, search, availability, and localization checks.

Use US Mobile Proxies when the test specifically requires a US mobile-network route. A mobile proxy can help validate network-sensitive mobile web behavior, but it does not reproduce a phone's browser fingerprint, operating system, viewport, touch support, GPS position, app state, or physical radio conditions. Configure device emulation and browser coordinates separately when those variables belong in the test.

RequirementRecommended starting point
Global country or city checksResidential proxy
Country-specific pricing or contentResidential proxy
US mobile-network web pathUS mobile proxy
Mobile layout without a mobile-network requirementResidential proxy plus Playwright device emulation
GPS-dependent application behaviorAppropriate proxy plus Playwright geolocation permission and coordinates
Long multi-step regional flowSticky route with one isolated browser context

The choice is about the network identity required by the test. It is not a substitute for the rest of the browser and application test environment.

What Proxidize Handles—and What Your Test Handles

Proxidize supplies the proxy network route, location targeting, credentials, and rotating or Sticky session behavior. Playwright and your test code supply the browser, state isolation, device settings, selectors, assertions, screenshots, and reports.

bash

That boundary matters. A proxy can put the request on the intended network path, but only a target-aware test can decide whether the correct experience appeared.

Use this workflow only for applications and public pages you are authorized to test. Respect applicable laws, third-party terms, access controls, privacy requirements, and reasonable request rates. Location targeting changes the test route; it does not grant permission to access restricted data or systems.

Validation Notes for This Guide

This guide was reviewed on September 22, 2026 against the current Playwright and Proxidize documentation. Playwright 1.63.0 was the current npm release at review time.

The JavaScript example was extracted from the article and syntax-checked with Node.js 24.15.0. A mocked control-flow harness then checked five paths: success, wrong-country preflight, coordinate-read failure, target assertion timeout, and unexpected page-evaluation failure. The wrong-country case stopped before target navigation; the other failure cases produced a failed JSON report and, whenever a target page existed, a screenshot. These were simulated control-flow checks—not a live browser, proxy, location, or target test.

The code has not been run against live Proxidize credentials or a production target. It is therefore a validated implementation pattern, not a measured claim about location accuracy, latency, target behavior, or proxy performance.

Before using it in CI, run a controlled pilot against an application you own, replace the example selectors, confirm the location service and target are approved dependencies, and define which city mismatches are warnings versus failures.

Build a Repeatable Geo-Testing Workflow

Start with one authorized page and one market. Create a Sticky country/city access point, align the browser locale and timezone, verify the exit, assert the visible market and currency, and save a report and screenshot. Once that profile is stable, add markets as separate configurations rather than adding hidden conditionals to one test.

Explore Proxidize Residential Proxies or read the localized-testing use case to plan country, city, and session coverage for your QA workflow.

Frequently asked questions

Geolocation testing checks how a website or application behaves for a defined market. A complete test can include the public IP location, browser locale, timezone, optional browser coordinates, final URL, language, currency, price, availability, shipping, redirects, legal content, and screenshots.

No. A proxy changes the browser's network route and public exit IP. Playwright's browser coordinates are configured separately with geolocation, and the page needs geolocation permission to read them. Locale, timezone, viewport, user agent, cookies, and account state are also separate.

Playwright does not have one universal country switch. Use a country- or city-targeted proxy for the network route, locale for language and formatting signals, timezoneId for browser time, and optional coordinates for the browser Geolocation API. Then assert the target's visible regional result.

Websites may choose currency from the URL, a cookie, an account profile, a saved store, shipping country, payment region, or explicit selector instead of—or before—using IP location. Start with a clean context, record the final URL, and assert both the selected market and the visible price.

City results are approximate and can differ between IP-location databases. Use country as the strict first gate, treat city as a warning by default, and validate the website behavior that matters. If an exact city classification is material, compare approved sources and document the confidence or accuracy radius.

Use a Sticky route for one coherent test so the location check, navigation, redirects, and assertions use a consistent network identity. Rotate between independent tasks or market profiles when IP diversity is useful. Do not intentionally rotate midway through a stateful workflow.

Residential proxies are usually the starting point for global country and city checks. US mobile proxies are appropriate when a US mobile-network route is part of the requirement. Neither proxy type replaces device emulation, browser coordinates, locale, timezone, or application assertions.

Save the timestamp, requested and final URLs, expected profile, start and end exit observations, browser locale and timezone, optional browser coordinates, target-visible text, assertion results, HTTP status, and screenshot. Redact credentials and review whether observed exit IPs should be removed before sharing the report externally.

Not necessarily. Closing the context clears that browser context's pages, cookies, storage, and connections, but the provider's Sticky assignment has its own lifecycle. Create or renew the proxy session according to the provider's controls when the next task requires a different exit.

Ready to launch?

Proxies built for real operations.

For teams that depend on stability, not luck.