Primeros pasos
Playwright vs Puppeteer with Cloud Browsers: Which to Choose
Compare Playwright and Puppeteer for cloud browser automation. Understand API differences, multi-browser support, and practical trade-offs.
Introduction
Playwright and Puppeteer are the two dominant browser automation libraries. Both work with cloud browsers via WebSocket connections, but they differ in API design, multi-browser support, and feature sets. This guide helps you choose the right tool for your workflow.
Quick Comparison
| Feature | Puppeteer | Playwright |
|---|---|---|
| Maintainer | Microsoft | |
| Language support | JavaScript/TypeScript | JS/TS, Python, Java, C# |
| Browser support | Chrome/Chromium | Chrome, Firefox, WebKit |
| Auto-wait | Manual | Built-in |
| Network interception | setRequestInterception | route() |
| Selectors | CSS, XPath | CSS, XPath, text, role |
| Parallel contexts | Manual | Built-in browser.newContext() |
| Test runner | None (use Jest/Mocha) | Built-in @playwright/test |
Connecting to BotCloud
Puppeteer
const puppeteer = require('puppeteer-core');
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://bots.win/ws?apiKey=YOUR_API_KEY',
});
const page = await browser.newPage();
await page.goto('https://example.com');
await page.waitForSelector('.content');
const text = await page.$eval('.content', el => el.textContent);
await browser.close();
Playwright
const { chromium } = require('playwright');
const browser = await chromium.connectOverCDP('wss://bots.win/ws?apiKey=YOUR_API_KEY');
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com');
const text = await page.textContent('.content'); // Auto-waits
await browser.close();
Key Differences
Auto-Wait
Playwright automatically waits for elements to be visible and actionable:
// Puppeteer - manual wait required
await page.waitForSelector('#submit');
await page.click('#submit');
// Playwright - auto-waits for element to be clickable
await page.click('#submit');
Selectors
Playwright supports additional selector engines:
// Text selector
await page.click('text=Sign In');
// Role selector
await page.click('role=button[name="Submit"]');
// Chained selectors
await page.click('.form >> text=Submit');
Network Interception
// Puppeteer
await page.setRequestInterception(true);
page.on('request', req => {
if (req.resourceType() === 'image') req.abort();
else req.continue();
});
// Playwright
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());
await page.route('**/api/**', route => {
route.fulfill({ body: JSON.stringify({ mock: true }) });
});
Multi-Context
// Playwright - built-in context isolation
const context1 = await browser.newContext();
const context2 = await browser.newContext();
// Each context has independent cookies, storage, and settings
// Puppeteer - use separate browser connections for full isolation
const browser1 = await puppeteer.connect({ browserWSEndpoint: ws1 });
const browser2 = await puppeteer.connect({ browserWSEndpoint: ws2 });
When to Choose Puppeteer
- You are already using Puppeteer and it works
- Your team only uses JavaScript
- You need the most direct Chrome DevTools Protocol access
- You are building simple, single-browser automation
- Broad ecosystem of existing Puppeteer scripts and examples
When to Choose Playwright
- You need Python, Java, or C# support
- Auto-wait behavior reduces flaky tests
- You want built-in test running and reporting
- You need advanced selector engines (text, role)
- You want simpler network interception with
route()
Migration Between Them
Most Puppeteer code can be converted to Playwright with minimal changes:
| Puppeteer | Playwright |
|---|---|
page.$eval(sel, fn) | page.locator(sel).evaluate(fn) |
page.waitForSelector(sel) | page.locator(sel).waitFor() |
page.type(sel, text) | page.fill(sel, text) |
page.click(sel) | page.click(sel) (same) |
page.goto(url) | page.goto(url) (same) |
page.evaluate(fn) | page.evaluate(fn) (same) |
Best Practices
- Choose one library and stick with it - Mixing both adds complexity without benefit
- Use Playwright for new projects - Auto-wait and better selectors reduce flaky automation
- Use Puppeteer if you have existing code - Migration cost may not be worth it
- Both work equally well with cloud browsers - The connection mechanism is nearly identical
- Use TypeScript with either library for better IDE support and type safety
#playwright#puppeteer#comparison#automation