Teach playwright new tricks through plugins.
npm install playwright-extra> A modular plugin framework for playwright to enable cool plugins through a clean interface.
``bash`
yarn add playwright playwright-extra- or -
npm install playwright playwright-extra
Changelog
> Please check the announcements channel in our discord server until we've automated readme updates. :)
- v4.3
- Rerelease due to versioning issues with previous beta packages
- v3.3
- Initial public release
`js
// playwright-extra is a drop-in replacement for playwright,
// it augments the installed playwright with plugin functionality
const { chromium } = require('playwright-extra')
// Load the stealth plugin and use defaults (all tricks to hide playwright usage)
// Note: playwright-extra is compatible with most puppeteer-extra plugins
const stealth = require('puppeteer-extra-plugin-stealth')()
// Add the plugin to playwright (any number of plugins can be added)
chromium.use(stealth)
// That's it, the rest is playwright usage as normal 😊
chromium.launch({ headless: true }).then(async browser => {
const page = await browser.newPage()
console.log('Testing the stealth plugin..')
await page.goto('https://bot.sannysoft.com', { waitUntil: 'networkidle' })
await page.screenshot({ path: 'stealth.png', fullPage: true })
console.log('All done, check the screenshot. ✨')
await browser.close()
})
`
The above example uses the compatible stealth plugin from puppeteer-extra, that plugin needs to be installed as well:
`bash`
yarn add puppeteer-extra-plugin-stealth- or -
npm install puppeteer-extra-plugin-stealth
If you'd like to see debug output just run your script like so:
`bashmacOS/Linux (Bash)
DEBUG=playwright-extra,puppeteer-extra node myscript.js
$3
TypeScript & ESM usage
playwright-extra and most plugins are written in TS, so you get perfect type support out of the box. :)`ts
// playwright-extra is a drop-in replacement for playwright,
// it augments the installed playwright with plugin functionality
import { chromium } from 'playwright-extra'// Load the stealth plugin and use defaults (all tricks to hide playwright usage)
// Note: playwright-extra is compatible with most puppeteer-extra plugins
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
// Add the plugin to playwright (any number of plugins can be added)
chromium.use(StealthPlugin())
// ...(the rest of the quickstart code example is the same)
chromium.launch({ headless: true }).then(async browser => {
const page = await browser.newPage()
console.log('Testing the stealth plugin..')
await page.goto('https://bot.sannysoft.com', { waitUntil: 'networkidle' })
await page.screenshot({ path: 'stealth.png', fullPage: true })
console.log('All done, check the screenshot. ✨')
await browser.close()
})
`New to Typescript? Here it is in 30 seconds or less 😄:
`bash
Optional: If you don't have yarn yet
npm i --global yarnOptional: Create new package.json if it's a new project
yarn init -yAdd basic typescript dependencies
yarn add --dev typescript @types/node esbuild esbuild-registerBootstrap a tsconfig.json
yarn tsc --init --target ES2020 --lib ES2020 --module commonjs --rootDir src --outDir distAdd dependencies used in the quick start example
yarn add playwright playwright-extra puppeteer-extra-plugin-stealthCreate source folder for the .ts files
mkdir srcNow place the example code above in
src/index.tsRun the typescript code without the need of compiling it first
node -r esbuild-register src/index.tsYou can now add Typescript to your CV 🎉
`
Using different browsers
`ts
// Any browser supported by playwright can be used with plugins
import { chromium, firefox, webkit } from 'playwright-extra'chromium.use(plugin)
firefox.use(plugin)
webkit.use(plugin)
`
Multiple instances with different plugins
Node.js imports are cached, therefore the default
chromium, firefox, webkit export from playwright-extra will always return the same playwright instance.`ts
// Use addExtra to create a fresh and independent instance
import playwright from 'playwright'
import { addExtra } from 'playwright-extra'const chromium1 = addExtra(playwright.chromium)
const chromium2 = addExtra(playwright.chromium)
chromium1.use(onePlugin)
chromium2.use(anotherPlugin)
// chromium1 and chromium2 are independent
`---
Plugins
We're currently in the process of making the existing puppeteer-extra plugins compatible with playwright-extra, the following plugins have been successfully tested already:
$3
- Applies various evasion techniques to make detection of an automated browser harder
- Compatible with Puppeteer & Playwright and chromium based browsers
Example: Using stealth in Playwright with custom options
`js
// The stealth plugin is optimized for chromium based browsers currently
import { chromium } from 'playwright-extra'import StealthPlugin from 'puppeteer-extra-plugin-stealth'
chromium.use(StealthPlugin())
// New way to overwrite the default options of stealth evasion plugins
// https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth/evasions
chromium.plugins.setDependencyDefaults('stealth/evasions/webgl.vendor', {
vendor: 'Bob',
renderer: 'Alice'
})
// That's it, the rest is playwright usage as normal 😊
chromium.launch({ headless: true }).then(async browser => {
const page = await browser.newPage()
console.log('Testing the webgl spoofing feature of the stealth plugin..')
await page.goto('https://webglreport.com', { waitUntil: 'networkidle' })
await page.screenshot({ path: 'webgl.png', fullPage: true })
console.log('All done, check the screenshot. ✨')
await browser.close()
})
`$3
- Solves reCAPTCHAs and hCaptchas automatically, using a single line of code:
page.solveRecaptchas()
- Compatible with Puppeteer & Playwright and all browsers (chromium, firefox, webkit)
Example: Solving captchas in Playwright & Firefox
`js
// Any browser (chromium, webkit, firefox) can be used
import { firefox } from 'playwright-extra'import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha'
firefox.use(
RecaptchaPlugin({
provider: {
id: '2captcha',
token: process.env.TWOCAPTCHA_TOKEN || 'YOUR_API_KEY'
}
})
)
// Works in headless as well, just so you can see it in action
firefox.launch({ headless: false }).then(async browser => {
const context = await browser.newContext()
const page = await context.newPage()
const url = 'https://www.google.com/recaptcha/api2/demo'
await page.goto(url, { waitUntil: 'networkidle' })
console.log('Solving captchas..')
await page.solveRecaptchas()
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle' }),
page.click(
#recaptcha-demo-submit)
]) const content = await page.content()
const isSuccess = content.includes('Verification Success')
console.log('Done', { isSuccess })
await browser.close()
})
`$3
- Use multiple proxies dynamically with flexible per-host routing and more
- Compatible with Puppeteer & Playwright and all browsers (chromium, firefox, webkit)
Notes
- If you're in need of adblocking use this package or block resources natively
- We're focussing on compatiblity with existing plugins at the moment, more documentation on how to write your own playwright-extra plugins will follow
---
Contributors
---
License
Copyright © 2018 - 2023, berstend̡̲̫̹̠̖͚͓̔̄̓̐̄͛̀͘. Released under the MIT License.
[playwright-extra]: https://github.com/berstend/puppeteer-extra/tree/master/packages/playwright-extra
[puppeteer-extra]: https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra
[
puppeteer-extra`]: https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra