To test a website as different users and regions see it, give each test persona its own saved browser profile: its own signed-in test account, its own cookies, and its own exit, timezone and languages. Then drive those profiles from your existing test runner instead of clearing cookies and faking locales by hand between runs.
This post covers the states that make QA hard, how to design personas, how to test regions properly, how to automate personas with Playwright, and how to check two accounts side by side.
Why QA needs separate browser states
Most bugs that reach production are not in the code path the developer clicked through. They are in a state nobody had loaded:
- Signed in vs signed out, and signed in as which role: admin, editor, free user, paying customer, a user whose trial just ended.
- Experiment buckets. A/B tests assign a variant by cookie. Clear cookies and you land in a new bucket; keep them and you can only ever see one.
- Region and language. Prices, currency, tax, shipping, consent banners, date formats and translated copy all change with location. Some come from the IP address, some from the browser's timezone and languages, some from the account's settings.
- Accumulated history. A returning visitor with a full cart, saved preferences and dismissed banners sees a different page from a first-time visitor.
Recreating these by hand for every run is slow and error-prone. Developer tools can override a locale or timezone for one tab, but the IP address still says where you are, and the override is gone when the tab closes.
Design personas, not test accounts
A persona is a test account plus everything around it: role, region, language, device size and history. Write them down before you build them.
| Persona | Account | Region | Timezone | Languages | Screen |
|---|---|---|---|---|---|
| Tokyo buyer | Paying customer | Japan | Asia/Tokyo | ja-JP, ja, en | 1440 × 900 |
| Berlin editor | Editor role | Germany | Europe/Berlin | de-DE, de, en | 1920 × 1080 |
| São Paulo trial | Trial ending today | Brazil | America/Sao_Paulo | pt-BR, pt, en | 1366 × 768 |
| Sydney guest | Signed out | Australia | Australia/Sydney | en-AU, en | 1512 × 982 |
Each row becomes one profile. Keep the profiles signed in between runs so the state accumulates the way a real user's would, and reset a profile deliberately when a test needs a first visit.
Use test accounts your own product issues, or accounts a third-party site's terms allow for testing. For third-party services, many provide sandbox accounts for exactly this.
Testing regions properly
Region-dependent behaviour usually reads one of three things, and a realistic test sets all three the same way:
- The IP address, mapped to a country by the server or a CDN. Only a network exit in that country changes it.
- The timezone and languages the browser reports, read by JavaScript and the
Accept-Languageheader. - The account's own settings, such as a saved country or currency.
If the IP says Germany and the browser says New York time, you are testing a user who does not exist, and you may chase a bug real users never see. Give each regional persona an exit in its country and let the timezone and languages follow that exit. We cover the matching in detail in match a profile's timezone and location to its proxy.
Check every exit before a run. A proxy labelled "Japan" that exits in another country produces confident, wrong test results.
Keep test traffic out of your analytics
QA sessions inflate analytics, trigger marketing pixels and pollute experiment results. Block your analytics and advertising hosts in QA profiles, so test runs never reach them. Do it per profile, so a persona that needs to test the consent banner itself can still load it.
How Browz fits a QA workflow
Browz gives each test persona its own saved profile, exit, timezone and languages, and lets you drive them from Playwright, Puppeteer or Selenium (Browz for QA and web testing).
- Personas that persist. Each profile keeps its own cookies, local storage and IndexedDB between sessions, so a signed-in persona stays signed in, in the same experiment bucket.
- Locale, timezone and screen per profile. Set them yourself, or let timezone and languages follow the profile's measured exit.
- An exit per country. One proxy per profile, checked through a real tunnel with the exit IP, country and city measured over HTTPS. Turn on Refuse if the exit country changed so a run never starts from the wrong country (proxies).
- Per-profile website blocklists refuse chosen hosts, such as analytics, before a connection is made.
- Automation with the tools you use. Start a profile from the Local API or CLI and attach your test runner over CDP. Driving a profile with Playwright does not change the fingerprint it presents.
Step by step: build the personas
browz create "Persona – Tokyo buyer" --proxy "Tokyo static 1" --group "QA"
browz create "Persona – Berlin editor" --proxy "Frankfurt ISP 1" --group "QA"
browz update "Persona – Berlin editor" --languages "de-DE,de,en" --tags qa,editor
browz fingerprint "Persona – Berlin editor"browz fingerprint lists each value the profile presents and where it came from, so you can confirm the timezone came from the exit before the first run. Then start each persona once in the app, sign in to its test account, and stop it. The session is saved.
Step by step: drive a persona from Playwright
Install the packages. Browz provides the browser, so playwright-core is enough:
npm install playwright-core @browz/sdkStart the persona's profile and attach to it, using the profile's own context so its cookies are there:
import { chromium } from 'playwright-core';
import { Browz, localCredentials } from '@browz/sdk';
const browz = new Browz(await localCredentials());
const id = '<persona-profile-id>'; // from `browz --json list`
const session = await browz.browser.start(id);
const browser = await chromium.connectOverCDP(session.wsEndpoint ?? session.cdpEndpoint);
try {
const context = browser.contexts()[0]; // the persona's saved session
const page = context.pages()[0] ?? (await context.newPage());
await page.goto('https://staging.example.com/pricing');
console.log(await page.locator('[data-test=price]').first().textContent());
} finally {
await browser.close(); // detaches; Browz keeps the browser
await browz.browser.stop(id); // saves the persona's state
}Two rules: attach to the browser Browz started, never call chromium.launch(), and use browser.contexts()[0], not newContext(), which would open a blank session. The full guide is Playwright with Browz.
Two accounts side by side
Some bugs only appear between users: a message that should reach the other side, a shared document, a permission change. The "Two accounts, side by side, kept apart" recipe in our recipes starts two profiles, signs each in to its own account at the same time, and checks that each still sees only its own account. It uses the Local API's page model (snapshot and act) with no script in the page, and each profile can take its own proxy.
A QA checklist
- One profile per persona, named for its role and region.
- An exit in each persona's country, checked before the run.
- Timezone and languages follow the exit unless the test needs otherwise.
- Analytics and ad hosts blocked in QA profiles.
- Personas signed in once and kept; reset on purpose, not by accident.
- Tests attach to the profile's own context over CDP.
- Test accounts your product issues, or that the site's terms allow.
Frequently asked questions
How do I test my website as a different user?
Create a separate browser profile for each test user and sign in once in each. Every profile keeps its own cookies and storage, so you can switch between users instantly, or run them at the same time, without signing out or clearing data.
How do I test a website from another country?
Use a browser profile with a proxy that exits in that country, and set the profile's timezone and languages to match. The IP address changes what the server sees; the timezone and languages change what the page's scripts see. Checking only one of them can show you a version of the site no real visitor gets.
Can I run Browz in CI?
Browz is a desktop app for Mac, Windows and Linux. Tests running on the same computer drive it through the Local API on that computer, so a dedicated test machine with Browz installed works well as a runner.
Does automating a profile with Playwright change what the site sees?
Not in Browz: driving a profile with Playwright, Puppeteer or MCP does not change the device or network fingerprint it presents. Attach to the browser Browz started rather than letting the library launch its own, which would be a stock browser with none of the profile's settings.