🚨 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.

Introduction to pear-browser

pear-browser is a powerful browser automation library for Node.js, similar to Puppeteer but with more direct control over Chrome/Chromium. pear-browser allows you to control the browser programmatically, making it perfect for:

  • Web scraping and data extraction
  • Automated testing of web applications
  • Capturing screenshots
  • Automating form submission
  • Browser behavior testing

pear-browser works by launching a Chrome instance and communicating with it via WebSocket, allowing fine-grained control over browser actions and page interactions.

Installation

Install pear-browser using npm:

npm install pear-browser

Note:

pear-browser requires a Chrome or Chromium installation. You can use your system's Chrome installation or let pear-browser download and use a bundled Chromium version.

Getting Started

Here's a simple example to get started with pear-browser:

const pearBrowser = require("pear-browser");

async function main() {
  const browser = await pearBrowser({
    useChromium: true
  });

  const page = await browser.newPage("https://www.google.com");

  await page.screenshot({ path: "search-results.png" });
  
  await browser.close();
}

main().catch(console.error);

Browser API

Initialization Options

When initializing pear-browser, you can provide the following options:

const browser = await pear-browser({
  browserPath: "path/to/chrome",  // Custom Chrome path
  profileDir: "./profile",        // Chrome profile directory
  args: ["--disable-gpu"],        // Additional Chrome arguments
  debug: false,                   // Enable debug logging
  useragent: "Custom User Agent", // Set a custom user agent
  viewport: { width: 1280, height: 720 }, // Default viewport
  port: 9876,                     // WebSocket port
  incognito: false,               // Use incognito mode
  autoclose: false,               // Close when WebSocket disconnects
  server: httpServer,             // Custom HTTP server
  proxy: "http://proxy:8080",     // Use proxy
  nosandbox: false,               // Disable sandbox
  muteaudio: false,               // Mute audio
  useChromium: false,             // Use bundled Chromium
});

Browser Methods

  • .newPage(url, options)

    Opens a new tab with the specified URL. Returns a Page object.

    Options:

    • dontwaitLoad: Don't wait for page to load
  • .close()

    Closes the browser instance and all open tabs.

  • .setUserAgent(userAgent)

    Sets the user agent for all pages.

  • .getCookies(domain)

    Gets cookies for the specified domain.

  • .getAllCookies()

    Gets all browser cookies.

  • .setCookies(cookies)

    Sets browser cookies.

Browser Events

pear-browser emits events you can listen to:

browser.on("tabcreated", (tab) => {
  console.log("New tab created:", tab);
});

Page API

The Page API provides methods to interact with web pages.

  • .evaluate(fn, ...args)

    Evaluates a function in the browser context and returns the result.

    const result = await page.evaluate((a, b) => {
      return a + b;
    }, 5, 10); // Returns 15
  • .click(selector, options)

    Clicks on an element matching the selector.

    await page.click("#submit-button");
  • .focus(selector)

    Focuses on an element matching the selector.

    await page.focus("input[name='username']");
  • .type(text) or .type(selector, text)

    Types text into the focused element or into an element matching the selector.

    await page.focus("input[name='username']");
    await page.type("johndoe");
    // Or
    await page.type("input[name='username']", "johndoe");
  • .waitForSelector(selector, options)

    Waits for an element matching the selector to appear in the page.

    await page.waitForSelector(".results", { timeout: 5000 });
  • .waitForNavigation(options)

    Waits for navigation to complete after actions like form submission or link clicks.

    await page.click("#submit-button");
    await page.waitForNavigation({ timeout: 5000 });
  • .waitForTimeout(milliseconds)

    Waits for the specified amount of time.

    await page.waitForTimeout(1000); // Wait for 1 second
  • .setViewport(dimensions)

    Sets the viewport dimensions.

    await page.setViewport({ width: 1280, height: 800 });
  • .getPageSource()

    Gets the HTML content of the page.

    const html = await page.getPageSource();
  • .close()

    Closes the page/tab.

    await page.close();

Mouse & Keyboard API

Mouse

The mouse object provides methods to simulate mouse actions:

// Wheel scroll
await page.mouse.wheel({ deltaY: -500 }); // Scroll up
await page.mouse.wheel({ deltaY: 500 });  // Scroll down

// Click at coordinates
await page.mouse.click(100, 200);

// Move mouse to coordinates
await page.mouse.move(300, 400);

// Mouse down/up actions
await page.mouse.down(); // Left button by default
await page.mouse.down({ button: 2 }); // Right button
await page.mouse.up();

Keyboard

The keyboard object provides methods to simulate keyboard actions:

// Press a key (down and up)
await page.keyboard.press("Enter");

// Key down
await page.keyboard.down("Shift");

// Key up
await page.keyboard.up("Shift");

Select API

pear-browser provides a specialized API for working with select elements:

// Get all options in a select
const options = await page.select.getOptions("#dropdown");
console.log("Available options:", options);

// Get selected option
const selected = await page.select.getSelected("#dropdown");
console.log("Selected option:", selected);

// Select by value
await page.select.selectByValue("#dropdown", "option2");

// Select by text
await page.select.selectByText("#dropdown", "Option 3");

// Select by index (0-based)
await page.select.selectByIndex("#dropdown", 1);

Screenshots

Capture screenshots of the current page:

// Save screenshot to a file
await page.screenshot({ path: "screenshot.png" });

// Specify format and quality
await page.screenshot({ 
  path: "screenshot.jpg",
  type: "jpeg",
  quality: 80
});

// Get screenshot as buffer (don't save to file)
const screenshotBuffer = await page.screenshot();

File Upload

pear-browser supports file uploads and drag-and-drop file operations:

// Upload a file using a file input
await page.uploadFile("#fileInput", "/path/to/file.jpg");
// Multiple files
await page.uploadFile("#fileInput", ["/path/to/file1.jpg", "/path/to/file2.jpg"]);

// Drag and drop a file onto a target
await page.dragAndDropFile("/path/to/file.jpg", "#dropzone");

Cookies

Get and set browser cookies:

// Get cookies for a specific domain
const cookies = await browser.getCookies("example.com");

// Get all cookies
const allCookies = await browser.getAllCookies();

// Set cookies
await browser.setCookies([
  {
    name: "sessionId",
    value: "abc123",
    domain: "example.com",
    path: "/",
    secure: true,
    httpOnly: false,
    expirationDate: (Date.now() / 1000) + 3600
  }
]);

Examples

Basic Navigation

const pearBrowser = require("pear-browser");

async function main() {
  const browser = await pearBrowser({ useChromium: true });
  const page = await browser.newPage("https://example.com");
  
  // Wait for a specific element
  await page.waitForSelector("h1");
  
  // Get page title using evaluate
  const title = await page.evaluate(() => document.title);
  console.log("Page title:", title);
  
  await browser.close();
}

main().catch(console.error);

Form Submission

const pearBrowser = require("pear-browser");

async function main() {
  const browser = await pearBrowser({ useChromium: true });
  const page = await browser.newPage("https://example.com/login");
  
  // Fill out form
  await page.type("input[name='username']", "user123");
  await page.type("input[name='password']", "password123");
  await page.click("#login-button");
  
  // Wait for navigation to complete
  await page.waitForSelector(".dashboard");
  console.log("Login successful!");
  
  await browser.close();
}

main().catch(console.error);

Web Scraping

const pearBrowser = require("pear-browser");
const fs = require("fs");

async function main() {
  const browser = await pearBrowser({ useChromium: true });
  const page = await browser.newPage("https://news-site.com");
  
  // Extract article data
  const articles = await page.evaluate(() => {
    return Array.from(document.querySelectorAll(".article")).map(article => ({
      title: article.querySelector(".title").innerText,
      summary: article.querySelector(".summary").innerText,
      url: article.querySelector("a").href
    }));
  });
  
  // Save results to file
  fs.writeFileSync("articles.json", JSON.stringify(articles, null, 2));
  console.log(`Scraped ${articles.length} articles`);
  
  await browser.close();
}

main().catch(console.error);

With Express Server Integration

const pearBrowser = require("pear-browser");
const express = require("express");
const http = require("http");

async function main() {
  const app = express();
  const server = http.createServer(app);
  
  app.get('/', (req, res) => {
    res.send('pear-browser Browser API Server');
  });
  
  server.listen(3000, () => {
    console.log(`Server running on port 3000`);
  });
  
  const browser = await pearBrowser({
    server: server,
    port: 3000,
    debug: true
  });
  
  // Now browser is integrated with your Express server
  const page = await browser.newPage("https://example.com");
  // ...
}

main().catch(console.error);