Skip to main content
Understanding the browser hierarchy is key to effective automation.

Hierarchy

Session
└── Browser
    └── Context (isolated environment)
        └── Page (tab)
            └── Frame (iframe)

Pages

A page is a browser tab. Each session starts with one default page.
const session = await playwright.connect({ apiKey: '...' });

// Default page
const page = session.page;
await page.goto('https://example.com');

// Create additional pages
const page2 = await session.context.newPage();
await page2.goto('https://other-site.com');

Working with Multiple Pages

// Open links in new tab
await page.locator('a[target="_blank"]').click();

// Get all pages in context
const pages = session.context.pages();

// Switch between pages
const [page1, page2] = pages;
await page1.bringToFront();

Page Methods

Common page operations:
// Navigation
await page.goto(url);
await page.goBack();
await page.goForward();
await page.reload();

// Info
const url = page.url();
const title = await page.title();
const content = await page.content();

// Actions
await page.click(selector);
await page.fill(selector, text);
await page.locator(selector).click();

// Screenshots
await page.screenshot({ path: 'shot.png' });

// Close
await page.close();

Contexts

A context is an isolated browser environment. Each context has separate:
  • Cookies
  • LocalStorage
  • SessionStorage
  • Cache
  • Permissions

Why Use Contexts?

Multi-Account

Run multiple logged-in accounts simultaneously

Isolation

Test without affecting other sessions

Clean Slate

Start fresh without clearing the whole browser

Parallel Testing

Independent test environments

Creating Contexts

const session = await playwright.connect({ apiKey: '...' });

// Default context
const defaultContext = session.context;

// Create new isolated context
const context2 = await session.browser.newContext();
const page2 = await context2.newPage();

// Each context is completely isolated
await defaultContext.addCookies([{ name: 'user', value: 'alice', domain: '.example.com' }]);
await context2.addCookies([{ name: 'user', value: 'bob', domain: '.example.com' }]);

// Alice and Bob are logged in separately
const context = session.context;

// Add cookies
await context.addCookies([
  {
    name: 'session',
    value: 'abc123',
    domain: '.example.com',
    path: '/',
    httpOnly: true,
    secure: true
  }
]);

// Get cookies
const cookies = await context.cookies();
const exampleCookies = await context.cookies('https://example.com');

// Clear cookies
await context.clearCookies();

Storage State

Save and restore entire context state:
// Save state (cookies + localStorage)
const state = await context.storageState();
// state = { cookies: [...], origins: [{ localStorage: [...] }] }

// Save to file
await context.storageState({ path: 'state.json' });

// Restore in new session (via pre-configured profile)
// Or apply cookies manually

Driver Differences

Different drivers have different context support:
DriverContextsMultiple Pages
PlaywrightFull supportYes
PuppeteerLimitedYes
SeleniumNoLimited
StagehandLimitedYes
// Full context support
const context = await session.browser.newContext();
const page = await context.newPage();
await context.addCookies([...]);

Puppeteer

// Pages supported, limited context isolation
const page = session.page;
const page2 = await session.browser.newPage();

Selenium

// Single driver, window-based navigation
const driver = session.driver;
await driver.get('https://example.com');
// Use driver.switchTo().window() for multiple windows

Common Patterns

Multi-Account Automation

const session = await playwright.connect({ apiKey: '...' });

// Account 1
const ctx1 = await session.browser.newContext();
const page1 = await ctx1.newPage();
await page1.goto('https://app.com/login');
await page1.fill('#email', '[email protected]');
// ... login

// Account 2
const ctx2 = await session.browser.newContext();
const page2 = await ctx2.newPage();
await page2.goto('https://app.com/login');
await page2.fill('#email', '[email protected]');
// ... login

// Both accounts active simultaneously

Handle Popups

// Listen for new pages (popups)
session.context.on('page', async (newPage) => {
  console.log('New page opened:', newPage.url());
  await newPage.waitForLoadState();
  // Handle popup
});

// Click something that opens popup
await page.click('button.open-popup');

Transfer Data Between Pages

const page1 = session.page;
const page2 = await session.context.newPage();

// Get data from page1
const data = await page1.evaluate(() => {
  return localStorage.getItem('token');
});

// Use in page2 (same context = shared storage)
// Or pass via evaluate:
await page2.evaluate((token) => {
  localStorage.setItem('token', token);
}, data);

Best Practices

const page = await context.newPage();
try {
  // Use page
} finally {
  await page.close();
}
Don’t share contexts between unrelated tasks or accounts.
If you need multiple contexts or complex page management, use Playwright driver.