🚨 Warning
This is not (Puppeteer or Selenium). It doesn't use the same API!
This module runs as a real Chrome extension, making it stealthy and hard to detect.
It uses a completely separate API to interact with the browser via WebSocket.
Introduction to pear3
pear3 is a powerful browser automation library for Node.js that provides direct control over Chrome/Chromium through WebSocket communication. Unlike traditional automation tools, pear3 operates as a Chrome extension, making it:
- Stealthy - Hard to detect by anti-bot systems
- Fast - Direct communication without protocol overhead
- Reliable - Real browser environment, not headless simulation
- Feature-rich - Full access to modern web APIs
Perfect for web scraping, automated testing, form automation, and browser behavior analysis.
Installation
Install pear3 using npm:
npm install pear3
Requirements:
pear3 requires Chrome or Chromium. It can automatically download Chromium or use your system's Chrome installation.
Getting Started
Basic usage example:
const Pear = require("pear3");
async function main() {
const browser = await Pear({
viewport: { width: 1280, height: 800 },
headless: false
});
const page = await browser.newPage();
await page.goto("https://google.com");
// Type in search box
await page.directType('textarea', 'Hello Pear!');
await page.keypress('Enter');
// Take screenshot
const screenshot = await page.screenshot();
await browser.close();
}
main().catch(console.error);
Browser API
Initialization Options
Configure pear3 with these options:
const browser = await Pear({
browserPath: "/path/to/chrome", // Custom Chrome executable path
profileDir: "./chrome-profile", // Chrome user data directory
args: ["--disable-gpu"], // Additional Chrome arguments
userAgent: "Custom User Agent", // Set custom user agent
viewport: { width: 1280, height: 720 }, // Default viewport size
incognito: false, // Use incognito mode
headless: false, // Run in headless mode
disableGpu: false, // Disable GPU acceleration
nosandbox: false, // Disable sandbox (Linux)
proxy: "http://proxy:8080", // Proxy server
muteaudio: false, // Mute audio
cookies: cookieArray // Pre-load cookies
});
Browser Methods
-
.newPage()
Creates a new page (tab) and returns a Page object for interaction.
-
.newTab()
Alias for
newPage()
. Creates a new tab. -
.close()
Closes the browser instance and all associated resources.
Page API
Core page navigation and content methods:
-
.goto(url)
Navigate to the specified URL.
await page.goto("https://example.com");
-
.url()
Get the current page URL.
const currentUrl = await page.url();
-
.reload()
Reload the current page.
await page.reload();
-
.content()
Get the full HTML content of the page.
const html = await page.content();
-
.close()
Close the current page/tab.
await page.close();
Mouse & Keyboard Events
Keyboard Events
Simulate keyboard interactions with precise control:
// Basic key press (keydown + keyup)
await page.keypress('Enter');
await page.keypress('Tab');
await page.keypress('Escape');
// Key down (hold key)
await page.keydown('Shift');
await page.keydown('Control');
// Key up (release key)
await page.keyup('Shift');
// Target specific element (optional)
await page.keypress('Enter', '#search-input');
// With options
await page.keypress('a', '#input', {
ctrlKey: true, // Ctrl+A
shiftKey: false
});
Mouse Events
Full mouse interaction support:
// Click types
await page.leftclick('#button'); // Left click
await page.rightclick('#menu-trigger'); // Right click (context menu)
await page.middleclick('#link'); // Middle click (new tab)
await page.dblclick('#file'); // Double click
// Mouse actions
await page.mousedown('#draggable'); // Mouse down
await page.mouseup('#draggable'); // Mouse up
await page.mousemove('#target'); // Move mouse to element
// With custom coordinates
await page.leftclick('#element', { x: 10, y: 20 });
// Scroll actions
await page.scroll(null, { x: 0, y: 500 }); // Scroll window
await page.scroll('#container', { y: -200 }); // Scroll element up
Text Input Methods
Two methods for text input with different behaviors:
-
.type(selector, text)
Simulates natural typing - fires keyboard events for each character. Slower but more realistic.
await page.type('#username', 'john_doe'); // Triggers keydown, input, keyup events for each character
-
.directType(selector, text)
Direct value assignment - faster but bypasses keyboard events. Good for large text blocks.
await page.directType('#message', 'This is a long message...'); // Sets value directly, fires single input event
When to use which?
type(): For forms that listen to keyboard events, character validation, or when you need realistic typing simulation.
directType(): For bulk text entry, textareas, or when speed is more important than event simulation.
Element API
Methods for interacting with page elements:
-
.getAttribute(selector, attribute)
Get an element's attribute value.
const href = await page.getAttribute('a#main-link', 'href'); const className = await page.getAttribute('.item', 'class');
-
.getText(selector)
Get an element's text content.
const buttonText = await page.getText('#submit-btn'); const headingText = await page.getText('h1');
Screenshots
Capture page screenshots as base64 or buffer:
// Get screenshot as buffer
const screenshotBuffer = await page.screenshot();
// Save to file
const fs = require('fs');
fs.writeFileSync('screenshot.png', screenshotBuffer);
File Upload
Upload files to file input elements:
// Upload single file (URL or local path)
await page.uploadFile('#file-input', 'https://example.com/image.jpg');
// Note: Local file paths must be accessible to the browser
// For local files, use file:// URLs or serve them via HTTP
File Path Requirements:
Files must be accessible via HTTP/HTTPS URLs. Local file:// paths have browser security restrictions. Consider serving local files through a local HTTP server.
Wait Methods
Wait for elements or conditions before proceeding:
-
.waitForSelector(selector, options)
Wait for an element to appear in the DOM.
// Basic usage await page.waitForSelector('.loading-complete'); // With timeout and check interval await page.waitForSelector('#dynamic-content', { timeout: 10000, // Wait max 10 seconds checkInterval: 200 // Check every 200ms }); // Disable timeout (wait indefinitely) await page.waitForSelector('.element', { timeout: 0 });
Complete Examples
Google Search Automation
const Pear = require("pear3");
async function googleSearch() {
const browser = await Pear({
viewport: { width: 1280, height: 800 }
});
const page = await browser.newPage();
await page.goto("https://google.com");
// Wait for search box and type query
await page.waitForSelector('textarea[name="q"]');
await page.type('textarea[name="q"]', 'pear browser automation');
await page.keypress('Enter');
// Wait for results and take screenshot
await page.waitForSelector('#search');
const screenshot = await page.screenshot();
require('fs').writeFileSync('search-results.png', screenshot);
console.log('Search completed and screenshot saved!');
await browser.close();
}
googleSearch().catch(console.error);
Form Automation
const Pear = require("pear3");
async function fillForm() {
const browser = await Pear();
const page = await browser.newPage();
await page.goto("https://example.com/contact-form");
// Fill form fields
await page.type('#name', 'John Doe');
await page.type('#email', 'john@example.com');
await page.directType('#message', `
This is a longer message that I'm typing
into the contact form using directType
for better performance.
`);
// Select dropdown option
await page.leftclick('#country');
await page.waitForSelector('#country option[value="US"]');
await page.leftclick('#country option[value="US"]');
// Upload file
await page.uploadFile('#attachment', 'https://example.com/document.pdf');
// Submit form
await page.leftclick('#submit-button');
// Wait for confirmation
await page.waitForSelector('.success-message');
console.log('Form submitted successfully!');
await browser.close();
}
fillForm().catch(console.error);
Web Scraping with Mouse Interactions
const Pear = require("pear3");
async function scrapeWithInteraction() {
const browser = await Pear({ headless: false });
const page = await browser.newPage();
await page.goto("https://example-spa.com");
// Wait for page to load
await page.waitForSelector('.content-loaded');
// Hover to reveal dropdown menu
await page.mousemove('.menu-trigger');
await page.waitForSelector('.dropdown-menu');
// Right-click to open context menu
await page.rightclick('.data-item');
await page.leftclick('.context-export');
// Scroll to load more content
for (let i = 0; i < 5; i++) {
await page.scroll(null, { y: 500 });
await page.waitForSelector(`.item-${i + 6}`, { timeout: 2000 });
}
// Extract all data
const content = await page.content();
// Process content...
await browser.close();
}
scrapeWithInteraction().catch(console.error);
Multi-tab Management
const Pear = require("pear3");
async function multiTabExample() {
const browser = await Pear();
// Open multiple tabs
const page1 = await browser.newPage();
const page2 = await browser.newPage();
const page3 = await browser.newPage();
// Work with different tabs simultaneously
await Promise.all([
page1.goto("https://site1.com"),
page2.goto("https://site2.com"),
page3.goto("https://site3.com")
]);
// Take screenshots of all tabs
const screenshots = await Promise.all([
page1.screenshot(),
page2.screenshot(),
page3.screenshot()
]);
// Save screenshots
const fs = require('fs');
screenshots.forEach((screenshot, index) => {
fs.writeFileSync(`tab-${index + 1}.png`, screenshot);
});
// Close specific tabs
await page2.close();
await page3.close();
// Continue working with page1
await page1.type('#search', 'final search');
await browser.close();
}
multiTabExample().catch(console.error);