Skip to content

Instantly share code, notes, and snippets.

@JosefJezek
Last active February 2, 2023 11:45
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JosefJezek/4cd9f2845acd095a9a55b79c0e358088 to your computer and use it in GitHub Desktop.
Save JosefJezek/4cd9f2845acd095a9a55b79c0e358088 to your computer and use it in GitHub Desktop.
Playwright Tips

Playwright Tips

Base Scripts

import {chromium, firefox, webkit} from 'playwright';

for (const browserType of [chromium, firefox, webkit]) {
  const browser = await browserType.launch();
  const page = await browser.newPage();
  await page.goto('https://playwright.dev');
  await page.screenshot({path: `image-${browserType.name()}.png`});
  await browser.close();
}

Browser Contexts

❌ Never Restart a Browser

  • Slow instantiation (>100ms)
  • Huge memory overhead

✔️ Always create Browser Contexts

  • Full isolation
  • Fast instantiation (~1ms)
  • Low overhead
import {webkit, chromium, firefox} from 'playwright';

const browser = await chromium.launch();

for (let i = 0; i < 10; ++i) {
  // Fast, simple, configurable!
  const context = await browser.newContext()
  const page = await context.newPage();
  await page.goto('https://playwright.dev');
  await context.close();
}

Auto-waiting

// Non-Playwright Pseudo-Code
await page.goto('https://form.example.com');
// Shall we wait for fields to be enabled?..
await page.fill('#email', 'aslushnikov@gmail.com');
await page.fill('#password', 'mypassword');
// Wait for button to get enabled and click submit
setTimeout(async () => {
  await page.click('#submit');
}, 1000); // <- Time Does Not Exist in the Cloud!
// ✨ Playwright auto-waiting by default!
await page.goto('https://form.example.com');
await page.fill('#email', 'aslushnikov@gmail.com');
await page.fill('#password', 'mypassword');
await page.click('#submit');

Device Emulation

import {webkit, devices} from 'playwright';

const browser = await webkit.launch();
const context = await browser.newContext({
  ...devices['iPhone 12 Pro'],
});
const page = await context.newPage();
await page.goto('https://playwright.dev');
await browser.close();

Geolocation & Permissions

import {chromium, firefox, webkit} from 'playwright';

const browser = await firefox.launch();
const context = await browser.newContext({
  geolocation: { longitude: 48.858455, latitude: 2.294474 },
  permissions: ['geolocation']
});
const page = await context.newPage();
await page.goto('https://playwright.dev');
await context.setGeolocation({
  longitude: 29.97, latitude: 31.13
});

Videos

import {webkit, chromium, firefox} from 'playwright';

const browser = await chromium.launch();
const context = await browser.newContext({
  recordVideo: {
    dir: 'videos/',
    size: { width: 800, height: 600 },
  },
});
const page = await context.newPage();
await page.goto('https://playwright.dev');
await page.close();

Network & WebSockets

import {webkit, chromium, firefox} from 'playwright';

const browser = await webkit.launch();
const page = await browser.newPage();
page.on('request', r => console.log(r.method(), r.url()));
page.on('websocket', ws => console.log(ws.url()));
await page.goto('https://playwright.dev');
await browser.close();

Page Request Interception

import {webkit, chromium, firefox} from 'playwright';

const browser = await firefox.launch();
const page = await browser.newPage();
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());
await page.goto('https://playwright.dev');
await browser.close();

Downloads

import {webkit, chromium, firefox} from 'playwright';

const browser = await webkit.launch();
const page = await browser.newPage();
await page.goto('https://playwright.dev');
const [ download ] = await Promise.all([
  page.waitForEvent('download'),
  page.click('button#delayed-download')
]);
console.log(await download.path());
await browser.close();

Smart Selectors

import {webkit, chromium, firefox} from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://playwright.dev');
await page.click('button'); // CSS selector
await page.click('xpath=//button'); // XPath selector
await page.click('text=Log in'); // Text selector
await page.click(':nth-match(:text("Buy"), 3)'); // N-th match
await page.click('div:right-of(:text("Name"))'); // Layout 😱
await page.click(`xpath=//form >> text=Submit`); // Composite

Assertions

// text content
const content = await page.textContent('nav:first-child');
expect(content).toBe('home');
// Attributes
const alt = await page.getAttribute('input', 'alt');
expect(alt).toBe('Text');
// Checkbox state
const checked = await page.isChecked('input');
expect(checked).toBeTruthy();
// Visibility
const visible = await page.isVisible('input');
expect(visible).toBeTruthy();

Microsoft Edge

import {chromium} from 'playwright';

const browser = await chromium.launch({
  // Can be 'chrome', 'chrome-beta', 'msedge-beta', 'msedge-dev'
  channel: 'msedge',
});
const page = await context.newPage();
await page.goto('https://playwright.dev');
await browser.close();

Experimental: Android

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

(async () => {
 const [device] = await _android.devices();
 await device.shell('am force-stop com.android.chrome');
 const context = await device.launchBrowser();
 const page = await context.newPage();
 await page.goto('https://playwright.dev/');
 await page.screenshot({ path: 'page.png' });
 await context.close();
 await device.close();
})();

Code Generation

npx playwright codegen --output out.js

# Built-In Inspector
PWDEBUG=1 node out.js

# Logging
DEBUG=pw:api node out.js

Re-use Storage State

npx playwright open --save-storage=auth.json web.dev
npx playwright codegen --load-storage=auth.json web.dev

Run Webkit Browser on Ubuntu 🎉

npx playwright wk

Devtools Console Integration

playwright.$

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment