E2E Testing Development for Websites (Puppeteer)
Puppeteer is a Node.js library for controlling Chrome/Chromium via Chrome DevTools Protocol. It is not a full-featured testing framework, but works great for scraping, PDF generation, screenshots, and automating specific browser tasks.
Installation
npm install -D puppeteer jest-puppeteer
# puppeteer includes Chromium automatically
# To use system Chrome:
npm install -D puppeteer-core
Basic Tests
// tests/login.test.ts
import puppeteer, { Browser, Page } from 'puppeteer';
describe('Login flow', () => {
let browser: Browser;
let page: Page;
beforeAll(async () => {
browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox'],
});
});
beforeEach(async () => {
page = await browser.newPage();
await page.setViewport({ width: 1280, height: 900 });
});
afterEach(async () => await page.close());
afterAll(async () => await browser.close());
test('successful login', async () => {
await page.goto('https://example.com/login');
await page.type('#email', '[email protected]');
await page.type('#password', 'password123');
await page.click('[type="submit"]');
await page.waitForNavigation({ waitUntil: 'networkidle2' });
expect(page.url()).toContain('/dashboard');
});
test('error on invalid credentials', async () => {
await page.goto('https://example.com/login');
await page.type('#email', '[email protected]');
await page.type('#password', 'wrong');
await page.click('[type="submit"]');
await page.waitForSelector('.error-message');
const errorText = await page.$eval('.error-message', el => el.textContent);
expect(errorText).toContain('Invalid');
});
});
Request Interception
// Mock API
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url().includes('/api/products')) {
request.respond({
status: 200,
contentType: 'application/json',
body: JSON.stringify([{ id: 1, name: 'MacBook' }]),
});
} else {
request.continue();
}
});
Screenshots and PDF
// Screenshot for visual testing
await page.screenshot({
path: 'screenshots/homepage.png',
fullPage: true,
clip: { x: 0, y: 0, width: 1280, height: 900 },
});
// PDF generation
await page.goto('https://example.com/invoice/123');
await page.pdf({
path: 'invoice.pdf',
format: 'A4',
printBackground: true,
margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' },
});
Device Emulation
import { KnownDevices } from 'puppeteer';
const iPhone = KnownDevices['iPhone 14'];
await page.emulate(iPhone);
await page.goto('https://example.com');
await page.screenshot({ path: 'mobile.png' });
Performance: When to Prefer Playwright
Puppeteer is good for: scraping, PDF/screenshot generation, automating a single browser.
Playwright is better for E2E testing: multi-browser support out of the box, better DX, more stable waits, built-in fixtures.
Implementation Timeline
Puppeteer setup + 20–30 scenarios: 3–5 days.







