Table of contents

How can I perform multi-tab testing using Playwright?

Multi-tab testing in Playwright allows you to simulate complex user workflows that span across multiple browser tabs. This is essential for testing applications with pop-ups, external links, or multi-step processes.

How Multi-Tab Testing Works

In Playwright, each tab is represented by a Page object. You create new tabs using context.newPage() and manage them independently. Unlike switching between tabs, you directly interact with specific page objects.

Basic Multi-Tab Example

JavaScript

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();

  // Create first tab
  const page1 = await context.newPage();
  await page1.goto('https://example.com');
  await page1.fill('#search', 'playwright');

  // Create second tab
  const page2 = await context.newPage();
  await page2.goto('https://github.com');
  await page2.click('text="Sign in"');

  // Work with both tabs simultaneously
  const title1 = await page1.title();
  const title2 = await page2.title();

  console.log(`Tab 1: ${title1}`);
  console.log(`Tab 2: ${title2}`);

  await browser.close();
})();

Python

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context()

    # Create first tab
    page1 = context.new_page()
    page1.goto('https://example.com')
    page1.fill('#search', 'playwright')

    # Create second tab
    page2 = context.new_page()
    page2.goto('https://github.com')
    page2.click('text="Sign in"')

    # Work with both tabs simultaneously
    title1 = page1.title()
    title2 = page2.title()

    print(f"Tab 1: {title1}")
    print(f"Tab 2: {title2}")

    browser.close()

Advanced Multi-Tab Scenarios

Handling Pop-up Windows

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  const mainPage = await context.newPage();

  await mainPage.goto('https://example.com');

  // Listen for new pages (pop-ups)
  const newPagePromise = context.waitForEvent('page');
  await mainPage.click('text="Open in new tab"'); // Trigger pop-up
  const popupPage = await newPagePromise;

  // Wait for popup to load
  await popupPage.waitForLoadState();

  // Interact with both pages
  await mainPage.fill('#email', 'user@example.com');
  await popupPage.fill('#password', 'secretpass');

  await browser.close();
})();

Managing Multiple Tabs with Arrays

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();

  const urls = [
    'https://example.com',
    'https://github.com',
    'https://stackoverflow.com'
  ];

  // Create multiple tabs
  const pages = await Promise.all(
    urls.map(url => context.newPage().then(page => {
      page.goto(url);
      return page;
    }))
  );

  // Perform actions on all tabs
  const titles = await Promise.all(
    pages.map(page => page.title())
  );

  titles.forEach((title, index) => {
    console.log(`Tab ${index + 1}: ${title}`);
  });

  // Close all pages
  await Promise.all(pages.map(page => page.close()));
  await browser.close();
})();

Cross-Tab Data Sharing

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();

  // Login in first tab
  const loginPage = await context.newPage();
  await loginPage.goto('https://example.com/login');
  await loginPage.fill('#username', 'testuser');
  await loginPage.fill('#password', 'testpass');
  await loginPage.click('button[type="submit"]');

  // Use session in second tab
  const dashboardPage = await context.newPage();
  await dashboardPage.goto('https://example.com/dashboard');

  // Session cookies are shared between tabs in the same context
  const isLoggedIn = await dashboardPage.isVisible('.user-menu');
  console.log('User is logged in:', isLoggedIn);

  await browser.close();
})();

Best Practices

1. Proper Resource Management

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();

  try {
    const pages = [];

    // Create tabs
    for (let i = 0; i < 3; i++) {
      const page = await context.newPage();
      pages.push(page);
      await page.goto(`https://example.com/page${i}`);
    }

    // Your testing logic here

  } catch (error) {
    console.error('Test failed:', error);
  } finally {
    // Always clean up
    await browser.close();
  }
})();

2. Waiting for Tab Operations

// Wait for all tabs to finish loading
await Promise.all(pages.map(page => 
  page.waitForLoadState('networkidle')
));

// Wait for specific elements in each tab
await Promise.all([
  page1.waitForSelector('.search-results'),
  page2.waitForSelector('.user-profile'),
  page3.waitForSelector('.product-list')
]);

3. Error Handling

const handleTabOperation = async (page, operation) => {
  try {
    await operation(page);
  } catch (error) {
    console.error(`Tab operation failed: ${error.message}`);
    // Continue with other tabs
  }
};

// Use with multiple tabs
await Promise.allSettled([
  handleTabOperation(page1, page => page.click('.submit-btn')),
  handleTabOperation(page2, page => page.fill('.input-field', 'data')),
  handleTabOperation(page3, page => page.screenshot({ path: 'tab3.png' }))
]);

Common Use Cases

  • E-commerce: Testing checkout flow with product comparison in multiple tabs
  • Social Media: Managing multiple accounts or cross-posting content
  • Documentation: Verifying links open correctly in new tabs
  • Multi-step Workflows: Testing processes that span multiple pages
  • Performance Testing: Simulating multiple concurrent user sessions

Multi-tab testing with Playwright provides powerful capabilities for testing complex web applications that require interaction across multiple browser contexts.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon