n8n-nodes-playwright-cdp
v1.0.1
Published
n8n node to execute Playwright code via CDP connection to running browsers
Maintainers
Readme
n8n-nodes-playwright-cdp
Execute Playwright code in n8n by connecting to browsers via Chrome DevTools Protocol (CDP).
Perfect for:
- Connecting to antidetect browsers (Dolphin Anty, AdsPower, GoLogin, etc.)
- Browser automation with existing browser sessions
- Web scraping with stealth capabilities
Installation
Community Nodes (Recommended)
- Go to Settings > Community Nodes
- Select Install
- Enter
@oneassasin/n8n-nodes-playwright-cdp - Agree to the risks and click Install
Manual Installation
npm install @oneassasin/n8n-nodes-playwright-cdpUsage
1. Get CDP Endpoint
Start your browser with remote debugging enabled or get the CDP URL from your antidetect browser:
Chrome/Chromium:
google-chrome --remote-debugging-port=9222Antidetect browsers:
- Dolphin Anty: Profile settings → Get CDP URL
- AdsPower: Local API → Get debug port
- GoLogin: Profile → Remote debugging
2. Configure Node
- CDP Endpoint URL: Your browser's CDP endpoint (e.g.,
ws://localhost:9222/devtools/browser/...) - JavaScript Code: Your Playwright automation code
- Emulate Human Behavior: Enable human-like mouse movements and typing
- Options: Connection/execution timeouts
3. Write Code
Available variables in your code:
| Variable | Description |
|----------|-------------|
| $playwright | Playwright library |
| $browser | Connected browser instance |
| $context | Browser context |
| $helpers | Helper functions (see below) |
| $input | Input data from previous node |
| $json | Shortcut for $input.item.json |
| $binary | Binary data from previous node |
| $humanized | true if human emulation enabled |
Helper Functions
Screenshot
const page = await $context.newPage();
await page.goto('https://example.com');
const screenshot = await $helpers.screenshot(page, {
fullPage: true,
type: 'png'
});
return { binary: { screenshot } };PDF Generation
const page = await $context.newPage();
await page.goto('https://example.com');
const pdf = await $helpers.pdf(page, {
format: 'A4',
printBackground: true
});
return { binary: { document: pdf } };Download File
// By URL
const file = await $helpers.download('https://example.com/file.pdf');
// By clicking element
const page = await $context.newPage();
await page.goto('https://example.com');
const file = await $helpers.download(page, {
clickSelector: '#download-btn'
});
return { binary: { file } };Upload File
const page = await $context.newPage();
await page.goto('https://example.com/upload');
// Get file from previous node
const file = await $helpers.binaryToFile('data');
// Upload to input[type="file"]
await $helpers.upload(page, file, {
selector: '#file-input'
});Request Interception
const page = await $context.newPage();
// Intercept and modify requests
await $helpers.interceptRequests(page, '**/api/**', async (route, request) => {
// Block request
// await route.abort();
// Modify and continue
await route.continue({
headers: { ...request.headers(), 'X-Custom': 'value' }
});
});
await page.goto('https://example.com');Page Snapshot
const page = await $context.newPage();
await page.goto('https://example.com');
// Get accessibility tree (like Playwright MCP)
const snapshot = await $helpers.snapshot(page);
return { snapshot };Output:
### Page
- URL: https://example.com
- Title: Example Domain
### Accessibility Tree
- heading "Example Domain"
- paragraph "This domain is for use in illustrative examples..."
- link "More information..."Human Emulation
When Emulate Human Behavior is enabled:
page.click()moves mouse along bezier curves to targetpage.type()/page.fill()types with random delays between keystrokes- Clicks target random points within elements, not center
// With human emulation enabled:
const page = await $context.newPage();
await page.goto('https://example.com');
// This click will have human-like mouse movement
await page.click('#login-button');
// This will type with realistic delays
await page.type('#username', '[email protected]');Examples
Basic Navigation
const page = await $context.newPage();
await page.goto('https://example.com');
const title = await page.title();
const content = await page.textContent('h1');
await page.close();
return { title, content };Form Submission
const page = await $context.newPage();
await page.goto('https://example.com/login');
await page.fill('#email', '[email protected]');
await page.fill('#password', 'secret');
await page.click('button[type="submit"]');
await page.waitForURL('**/dashboard');
const welcomeText = await page.textContent('.welcome');
await page.close();
return { welcomeText };Scraping with Multiple Pages
const results = [];
for (const url of $json.urls) {
const page = await $context.newPage();
await page.goto(url);
const data = await page.evaluate(() => ({
title: document.title,
description: document.querySelector('meta[name="description"]')?.content
}));
results.push(data);
await page.close();
}
return results.map(item => ({ json: item }));Compatibility
Tested with:
- Dolphin Anty
- AdsPower
- GoLogin
- Multilogin
- Regular Chrome/Chromium with
--remote-debugging-port
Troubleshooting
Connection Failed
- Verify browser is running and CDP port is accessible
- Check firewall settings
- For Docker: use
host.docker.internalinstead oflocalhost
Timeout Errors
- Increase timeouts in Options
- Check network connectivity to target sites
Human Emulation Not Working
- Ensure checkbox is enabled before execution
- Only affects pages created via
$context.newPage()
