Developer reference ยท User Scripts

Write Puppeteer Code with JavaScript Only

Automate the current Social Browser tab from a trusted User Script without installing Node.js, Puppeteer, or a separate automation server. Use the JavaScript-only page helpers for common actions, or call trusted real Puppeteer code in the Main Process when you need it.

await SOCIALBROWSER.page.type("#email", "name@example.com", { clear: true });
await SOCIALBROWSER.page.click('button[type="submit"]');

What this page covers

Trusted Social Browser User Scripts receive the global SOCIALBROWSER object. Its page helpers provide a JavaScript-only, Puppeteer-inspired way to work with the exact current tab. They are useful for selectors, DOM elements, input, scrolling, visible cursor movement, waiting, and common mouse, keyboard, and touch actions.

This is not a claim that the helper API replaces every Puppeteer feature. When a trusted script needs actual Puppeteer code, SOCIALBROWSER.page.runPuppeteer() runs it in the Main Process against the current Social Browser workspace/tab.

How User Scripts Work

SOCIALBROWSER is made available automatically inside trusted Social Browser User Scripts. Targets can be CSS selectors or real DOM elements:

await SOCIALBROWSER.page.click("#save");
await SOCIALBROWSER.page.click(document.querySelector("#save"));

Keep scripts scoped to the intended profile, workspace, and page. Review scripts before trusting them, and test changes on a low-risk page first.

Quick Start

Wait for the form, guard the result, enter placeholder data, submit it, and wait for a success state:

const page = SOCIALBROWSER.page;

const email = await page.waitForSelector("#email", {
  visible: true,
  timeout: 10000,
});

if (!email) return null;

await page.type("#email", "name@example.com", { clear: true });
await page.type("#password", "secure-password", { clear: true });
await page.click('button[type="submit"]');

return await page.waitForSelector(".dashboard, .success-message", {
  visible: true,
  timeout: 15000,
});

Core Page Actions

These helpers operate on a selector or DOM element. Options vary by action; use the options supported by the current Social Browser build.

HelperPurposeExample
page.click(target, options)Click a target.await page.click("#save");
page.dblclick(target, options)Double-click a target.await page.dblclick(".row");
page.rightClick(target, options)Open a target's context action.await page.rightClick(".file");
page.hover(target, options)Move over a target.await page.hover(".menu");
page.focus(target, options)Focus a target.await page.focus("#search");
page.clickOnPoint(x, y, options)Click at page coordinates.await page.clickOnPoint(420, 280);
page.scroll(x, y, options)Scroll by the supplied offset.await page.scroll(0, 500);
page.scrollTo(x, y, options)Scroll to coordinates.await page.scrollTo(0, 0);
page.scrollToElement(target, options)Bring a target into view.await page.scrollToElement("#results");
page.scrollHuman(x, y, options)Scroll with visible humanized motion.await page.scrollHuman(0, 700);
page.type(target, text, options)Type text into a target.await page.type("#name", "Sam", { clear: true });
page.setValue(target, value, options)Set a target's value.await page.setValue("#country", "EG");
page.clear(target, options)Clear a target's value.await page.clear("#search");
page.key(target, key, options)Send a key to a target.await page.key("#search", "Escape");
page.pressEnter(target, options)Press Enter on a target.await page.pressEnter("#search");
page.selectOption(target, valueOrText, options)Select an option.await page.selectOption("#country", "Egypt");
page.check(target, checked, options)Set a checkbox state.await page.check("#terms", true);

Human-Like Visible Actions

Humanized behavior is enabled by default for the relevant visible actions. Typing uses varying delays between characters; spaces and punctuation can add a short pause; and the visible black cursor follows a curved path with acceleration and deceleration. click, hover, and focus can move to the target before acting.

These are visible interaction effects, not a guarantee of human detection outcomes. They do not bypass CAPTCHA, access controls, or website policies, and they do not guarantee that a website will treat automation as human activity.

const page = SOCIALBROWSER.page;

await page.type("#message", "Hello! I would like more information.", {
  clear: true,
});

await page.cursor.move("#send-button");
await page.cursor.click("#send-button");
await page.scrollHuman(0, 700);

Advanced timing

await SOCIALBROWSER.page.type("#search", "Social Browser", {
  clear: true,
  delayMin: 45,
  delayMax: 130,
  pauseChance: 0.15,
});

await SOCIALBROWSER.page.cursor.move("#search-button", {
  durationMin: 300,
  durationMax: 900,
});

Fast mode

await SOCIALBROWSER.page.type("#search", "fast mode", {
  clear: true,
  human: false,
});

await SOCIALBROWSER.page.click("#search-button", { human: false });

Mouse, Keyboard, Cursor, and Touch APIs

Use the lower-level device helpers when a selector-based page action is not the right fit:

APIExample
page.mouse.move(x, y, options)await page.mouse.move(300, 180);
page.mouse.click(x, y, options)await page.mouse.click(300, 180);
page.mouse.down(options) / up(options)await page.mouse.down(); await page.mouse.up();
page.mouse.wheel(options)await page.mouse.wheel({ deltaY: 500 });
page.keyboard.type(text, options)await page.keyboard.type("site search");
page.keyboard.press(key, options)await page.keyboard.press("Enter");
page.keyboard.down(key, options) / up(key, options)await page.keyboard.down("Shift"); await page.keyboard.up("Shift");
page.touchscreen.tap(x, y, options)await page.touchscreen.tap(240, 460);
page.cursor.show() / hide()await page.cursor.show(); await page.cursor.hide();
page.cursor.move(), click(), dblclick(), rightClick()await page.cursor.move(".menu"); await page.cursor.click(".menu");
page.cursor.position()const point = await page.cursor.position();

Useful combinations

// Menu hover
await page.hover("#account-menu");
await page.waitForSelector("#account-menu .dropdown", { visible: true });

// Keyboard search
await page.focus("#search");
await page.keyboard.type("Social Browser");
await page.keyboard.press("Enter");

// Coordinate click and visible cursor control
await page.mouse.click(420, 280);
await page.cursor.show();
await page.cursor.move("#next");
await page.cursor.click("#next");

Finding and Waiting for Elements

Use selectors, evaluation helpers, and waits to keep a script synchronized with the current page:

APIPractical use
page.$() / page.$$()Find one element or a list of elements.
page.$eval() / page.$$eval()Read or transform data from matched elements.
page.waitForSelector()Wait for a selector, optionally requiring visibility.
page.waitForFunction()Wait until a page condition returns true.
page.waitForTimeout()Pause for a defined duration.
page.waitForGone()Wait for a target to disappear.
page.findDeep() / page.findAll()Find targets through the supported deep lookup helpers.
page.isVisible() / isEnabled() / inViewport()Check target state before acting.

Extract result-card titles

const titles = await page.$$eval(".result-card", (cards) =>
  cards.map((card) => card.querySelector("h2")?.textContent?.trim()).filter(Boolean)
);

return titles;

Shadow DOM lookup

const button = await page.findDeep("site-shell", "button.save");
if (button && await page.isEnabled(button)) {
  await page.click(button);
}

Wait for a loading overlay to disappear

await page.waitForSelector(".loading-overlay", { visible: true });
await page.waitForGone(".loading-overlay", { timeout: 15000 });

Locator API

The Puppeteer-inspired locator helper keeps a target together while you wait, hover, click, fill, focus, or retrieve its element handle.

const submit = SOCIALBROWSER.page.locator('button[type="submit"]');

await submit.wait({ visible: true });
await submit.hover();
await submit.click();

Locators also support fill(), focus(), and elementHandle():

const search = page.locator("#search");
await search.fill("Social Browser");
await search.focus();
const handle = await search.elementHandle();

Run Real Puppeteer Code When You Need It

SOCIALBROWSER.page.runPuppeteer() is intended for trusted Social Browser User Scripts. It runs trusted, real Puppeteer code in the Main Process against the exact current Social Browser workspace/tab.

const result = await SOCIALBROWSER.page.runPuppeteer(
  async (browser, page, args) => {
    await page.screenshot({ path: args.path });

    return {
      title: await page.title(),
      url: page.url(),
    };
  },
  { path: "C:/temp/social-browser-page.png" },
);

console.log(result);

Inside the callback, you can read the title and URL, evaluate DOM code, or take a screenshot:

const details = await SOCIALBROWSER.page.runPuppeteer(async (browser, page) => ({
  title: await page.title(),
  url: page.url(),
  heading: await page.$eval("h1", (node) => node.textContent.trim()),
}));

console.log(details);

For a simple serializable Puppeteer method call, page.puppeteer("title") can be used:

const title = await SOCIALBROWSER.page.puppeteer("title");
console.log(title);

Methods that require unsupported Chrome DevTools Protocol domains may not be available in every embedded browser build.

Safe Error Handling

Page helper actions fail safely when the target or action is unavailable. They normally resolve to null instead of throwing, so guard important results before continuing.

const button = await SOCIALBROWSER.page.click("#does-not-exist");

if (!button) {
  console.log("The button was not available.");
}

Complete Example: Search and Collect Results

This example waits for the search field, types naturally, uses the visible cursor, waits for results, reads result-card titles, and returns an array while guarding against missing elements.

const page = SOCIALBROWSER.page;
const search = await page.waitForSelector("#site-search", {
  visible: true,
  timeout: 10000,
});

if (!search) return [];

await page.type("#site-search", "Social Browser", { clear: true });
const searchButton = await page.waitForSelector("#search-button", {
  visible: true,
  timeout: 5000,
});

if (!searchButton) return [];

await page.cursor.move("#search-button");
await page.cursor.click("#search-button");

const results = await page.waitForSelector(".result-card", {
  visible: true,
  timeout: 15000,
});

if (!results) return [];

return (await page.$$eval(".result-card", (cards) =>
  cards.map((card) => card.querySelector("h2")?.textContent?.trim()).filter(Boolean)
)) || [];

Complete Example: Login Form

Use placeholder credentials while developing. Do not hard-code real passwords in shared User Scripts.

const page = SOCIALBROWSER.page;
const form = await page.waitForSelector("form#login", {
  visible: true,
  timeout: 10000,
});

if (!form) return null;

await page.type("#email", "name@example.com", { clear: true });
await page.type("#password", "placeholder-password", { clear: true });

const submit = await page.waitForSelector('button[type="submit"]', {
  visible: true,
  timeout: 5000,
});

if (!submit) return null;

await page.click(submit);

return await page.waitForSelector(".dashboard, .login-error", {
  visible: true,
  timeout: 15000,
});

Use only accounts and pages you are authorized to operate, and follow the terms and policies of the websites you use. Social Browser does not guarantee access, account status, CAPTCHA results, or human-like treatment by a third-party website.