Browser Contexts, Pages, and Emulation
By Syncfusion®, Inc. · Last updated
The browser, context and page hierarchy, how contexts isolate tests, creating contexts for multi-user tests, working with several pages, popups and new windows, setting the viewport and emulating devices, locale, timezone, geolocation and permissions, colour scheme, reduced motion, user agent and disabling JavaScript.
Browser Contexts, Pages, and Emulation
- So far, each test had one page in one browser context. Real apps need more.
- A chat needs two users at once. A link opens a new tab. A shop must work on a phone and in other countries.
- In this lesson, you will create contexts and pages yourself, and make the browser pretend to be other devices and places.
Simple lesson: contexts give you separate users, pages give you tabs, emulation gives you other devices and places.
A Real-World Example
- The Practice Shop has a support chat. Asha writes, and Ben, the support agent, must see her message.
- One browser context per person, like two different computers. Both open the chat.
- Open the Browser tab after the run. Each page has its own tab at the top.
What You Will Learn
- The browser, context and page hierarchy.
- How contexts keep tests apart, and how to make more contexts.
- Working with several pages, popups and new windows.
- Viewports and device emulation.
- Locale, time zone, geolocation and permissions.
- Colour scheme, reduced motion, user agent and JavaScript.
Browser Contexts
Browser, Context and Page Hierarchy
- Browser: one running browser program.
- Context: a private, separate session inside it, like an incognito window.
- Page: one tab inside a context.
How Playwright Isolates Tests with Contexts
- Each test gets a new context. Cookies, local storage and logins from one test never reach another.
- New contexts are cheap. Playwright makes thousands of them while starting the browser only once per worker.
Animation: a cookie and a cart item are saved in context A. Context B stays empty, because each context has its own storage
Browser (Chromium)
Context A (Asha)Context B (Ben)
cookies:cookies: (empty) localStorage:localStorage: (empty) sid=asha cart=[Yoga Mat]
✓ nothing leaks across
Two contexts in one browser share nothing: not cookies, not storage, not logins.
Creating Contexts with browser.newContext()
- Ask for the
browserfixture, then callbrowser.newContext(). - Pass options to it:
browser.newContext({ locale: 'fr-FR' }). - In Playwright Test, new contexts also get the
useoptions from your config, such asbaseURL. - Close contexts you create yourself with
context.close().
Multiple Contexts for Multi-User Tests
- Use one context per user: a buyer and a seller, an admin and a customer, two chat users.
Simple lesson: one context per user. Contexts never share cookies or storage.
Pages and Tabs
Creating Pages with context.newPage()
context.newPage()opens a new tab in a context. Tabs in the same context share cookies and storage.
Working with Multiple Pages
context.pages()lists all open tabs. Use each page object to act in that tab.
Popups and New Windows
- A link with
target="_blank"opens a popup. Wait for it withpage.waitForEvent('popup'). - Start waiting before the click, then await the promise after it:
const popupPromise = page.waitForEvent('popup');
await page.getByRole('link', { name: 'Size guide' }).click();
const popup = await popupPromise;
context.waitForEvent('page')catches any new tab in the context, not only popups from one page.
bringToFront() and Closing Pages
page.bringToFront()makes a tab the active one, like clicking it.page.close()closes a tab. Closing the context closes all its tabs.
Start waitForEvent() before the click. If you start it after, the popup may already be open, and the wait times out.
Simple lesson: wait for a popup with waitForEvent('popup'), started before the click.
Viewport and Devices
Setting the Viewport
- The viewport is the visible area of the page, in pixels.
- Set it in the config or
test.use({ viewport: { width: 390, height: 700 } }), or change it during a test withpage.setViewportSize().
Device Descriptors and Device Projects
devices['iPhone 13']is a device descriptor: viewport, user agent, scale and touch, all set like a real iPhone 13.- Since Playwright 1.64, a descriptor also sets the
screensize, sowindow.screenand media queries match the device. Setscreen: undefinedto turn that off. - Spread it into a project to run every test on that device:
projects: [
{ name: 'Mobile Chrome', use: { ...devices['Pixel 7'] } },
{ name: 'Mobile Safari', use: { ...devices['iPhone 13'] } },
],
Mobile Emulation
| Option | Effect |
|---|---|
isMobile | Uses the mobile viewport rules (Chromium) |
hasTouch | Turns on touch events. Needed for tap() |
deviceScaleFactor | Pixels per CSS pixel (2 or 3 on phones) |
- Emulation changes size, user agent and touch. It is not a real phone. Check important flows on real devices too.
Simple lesson: devices[...] gives a ready-made phone or tablet setup. setViewportSize() resizes on the fly.
Locale and Region
Locale and Timezone
locale: 'de-DE'makes the browser report German as its language and format numbers and dates the German way.timezoneId: 'Asia/Kolkata'sets the time zone. Dates shown on the page change with it.
Geolocation and Permissions
geolocation: { latitude: 19.08, longitude: 72.88 }sets where the browser thinks it is.- The page must also be allowed to read it:
permissions: ['geolocation'], orcontext.grantPermissions(['geolocation']). context.setGeolocation()moves the location during a test.
Simple lesson: locale, timezoneId and geolocation move the browser to another place. Permissions decide what the page may use.
Display Preferences
Color Scheme and Reduced Motion
colorScheme: 'dark'makes the page think the user prefers dark mode.reducedMotion: 'reduce'makes it think the user wants fewer animations.page.emulateMedia({ colorScheme: 'dark' })changes them during a test.
User Agent and Disabling JavaScript
userAgentchanges the browser's identity string, which some sites read to choose a layout.javaScriptEnabled: falseloads the page with no JavaScript, to test what users with scripts off see.
In the lab, emulation is done by the practice pages' own browser features in your browser. In a real project, Playwright sets these options inside Chromium, Firefox and WebKit directly.
Run your main tests in a dark-mode project too. Many visual bugs only show up in dark mode.
Simple lesson: emulate dark mode, reduced motion, user agents and no-JavaScript to test what different users see.
Try It in Your Project
- These steps take the lesson from the lab to your own app.
- Write one test with two contexts for a flow that involves two users, like chat or approvals.
- Add a mobile project with
devices['Pixel 7']and see which tests break. - Test one page in another locale and time zone if your app is used abroad.
Simple lesson: use one idea from this lesson on your own app this week.
TL;DR
- Browser holds contexts. Contexts hold pages. Each test gets its own context.
browser.newContext()makes another isolated user. Close it when done.page.waitForEvent('popup'), started before the click, catches new tabs.devices[...],viewportandsetViewportSize()emulate screens and phones.locale,timezoneId,geolocationandpermissionsemulate places.colorScheme,reducedMotion,userAgentandjavaScriptEnabledemulate preferences.
Common mistakes
| Mistake | What happens | Fix |
|---|---|---|
| Two users in two pages of one context | They share cookies, so both are the same user | Use one context per user |
| Waiting for the popup after the click | The wait can miss the popup and time out | Start waitForEvent() before the click |
Setting geolocation without permission | The page gets "permission denied" | Add permissions: ['geolocation'] |
Forgetting context.close() on extra contexts | Pages keep running until the test ends | Close every context you create |
| Trusting emulation alone for mobile | Some real-device bugs are missed | Also check key flows on real devices |
Check Yourself
Exercises
What to Remember
- One context per user. Contexts share nothing.
- Wait for popups before the click that opens them.
- Devices, viewports, locales, time zones and locations are just options.
- Permissions decide what the page may use.
- Emulation is fast and good, but not the same as a real device.
Next: Handling Complex Page Elements