Cogitator
Browser

BrowserSession

Manage browser lifecycle, tabs, cookies, proxy, and stealth configuration with BrowserSession.

Overview

BrowserSession is the core class that manages a Playwright browser instance. It handles launching the browser, creating contexts with the right configuration, and provides tab and cookie management.

Every browser tool receives a session reference and operates on its active page.

import { BrowserSession } from '@cogitator-ai/browser';

const session = new BrowserSession({
  headless: true,
  browser: 'chromium',
  stealth: true,
});

await session.start();
// ... use tools ...
await session.close();

Configuration

The full BrowserSessionConfig interface:

interface BrowserSessionConfig {
  headless?: boolean; // default: true
  browser?: BrowserType; // 'chromium' | 'firefox' | 'webkit', default: 'chromium'
  stealth?: boolean | StealthConfig;
  proxy?: string | ProxyConfig;
  viewport?: { width: number; height: number }; // default: 1280x720
  userAgent?: string;
  locale?: string; // e.g. 'en-US'
  timezone?: string; // e.g. 'America/New_York'
  geolocation?: { latitude: number; longitude: number };
  persistentContext?: string; // user data dir; profile survives restarts
  cookies?: BrowserCookie[]; // initial cookies
  timeout?: number; // navigation timeout, default: 30000ms
  actionTimeout?: number; // action timeout, default: 10000ms
  pool?: { maxPages: number }; // max open tabs for newTab(), positive integer
  robots?: RobotsChecker; // block navigations the site's robots.txt disallows
}

Persistent Profile

persistentContext launches Playwright's persistent context with the given user data directory. Cookies, localStorage, IndexedDB and cache survive across sessions, which keeps logins without exporting cookies. In this mode session.browser is null and the profile's existing tabs become the session's tabs.

const session = new BrowserSession({ persistentContext: './.browser-profile' });
await session.start();

Tab Limit

pool.maxPages caps the number of tabs newTab() may open. Opening a tab beyond the limit throws Tab limit reached: pool.maxPages is N.

const session = new BrowserSession({ pool: { maxPages: 3 } });

robots.txt

robots takes a checker such as RobotsPolicy from @cogitator-ai/core. Every page navigation, typed, clicked, redirected or in a frame, is checked against the site's robots.txt, and disallowed ones are blocked. newTab(url) and the browser_navigate tool throw robots.txt does not allow visiting <url>, so an agent learns why.

import { RobotsPolicy } from '@cogitator-ai/core';

const userAgent = 'NewsBot/1.0 (+https://example.com/bot)';
const session = new BrowserSession({ userAgent, robots: new RobotsPolicy({ userAgent }) });

Browser Types

Playwright supports three browser engines:

new BrowserSession({ browser: 'chromium' }); // Chrome, Edge
new BrowserSession({ browser: 'firefox' }); // Firefox
new BrowserSession({ browser: 'webkit' }); // Safari

Proxy

Pass a URL string or a full ProxyConfig with authentication:

new BrowserSession({ proxy: 'http://proxy.example.com:8080' });

new BrowserSession({
  proxy: {
    server: 'http://proxy.example.com:8080',
    username: 'user',
    password: 'pass',
  },
});

User Agent

An explicit userAgent wins over stealth: the random stealth user agent is skipped, but the evasion scripts still run and report a navigator.platform that matches your user agent.

Viewport and Locale

new BrowserSession({
  viewport: { width: 1920, height: 1080 },
  locale: 'de-DE',
  timezone: 'Europe/Berlin',
  geolocation: { latitude: 52.52, longitude: 13.405 }, // also grants the geolocation permission
});

Lifecycle

start()

Launches the browser, creates a context with the configured options, opens the first tab, and applies stealth evasions if enabled. If any step fails, everything launched so far is closed and the error is rethrown, so the session can be started again. Calling start() while the session is running or starting throws.

const session = new BrowserSession({ headless: false });
await session.start();

If the browser context closes on its own (crash, the user closing a headed window), the session resets and started becomes false.

ensureStarted()

Starts the session if needed. Concurrent callers share a single launch. Tools returned by browserTools() call it before every execution, so a session that was never started, or whose browser was closed or crashed, is (re)launched on the next tool call.

await Promise.all([session.ensureStarted(), session.ensureStarted()]); // one browser

onStart(listener)

Registers a listener that receives the BrowserContext after every successful start, and immediately if the session is already running. Returns an unsubscribe function. The network tools use it to record traffic from the first request.

const unsubscribe = session.onStart((context) => {
  context.on('request', (req) => console.log(req.url()));
});

close()

Closes the browser (or the persistent context) and cleans up all resources. Safe to call multiple times, and waits for a launch in progress first.

await session.close();

BrowserSession is also async-disposable, so await using closes it at the end of the scope:

await using session = new BrowserSession();
await session.start();

page

Returns the currently active Page object. Throws if the session hasn't been started. If the active tab was closed, the session falls back to an open tab. session.started tells whether a context is running and session.activeTabIndex returns the active tab index.

const page = session.page;
console.log(page.url());

Tab Management

Sessions support multiple tabs. New tabs automatically become the active tab. Pages opened by the site itself (popups, target="_blank" links) are tracked in tabs too, without changing the active tab.

newTab(url?)

Opens a new tab, optionally navigating to a URL. Returns the Playwright Page object. If navigation fails the tab is closed and the error is rethrown. Respects pool.maxPages.

const page = await session.newTab('https://example.com');

switchTab(index)

Switches the active tab by index.

session.switchTab(0); // switch to first tab

closeTab(index?)

Closes a tab by index. Defaults to closing the active tab. Cannot close the last remaining tab.

await session.closeTab(1);

tabs

Returns a copy of all open Page objects. Tabs closed outside the session are pruned, and switchTab/closeTab indexes always refer to this pruned list.

for (const tab of session.tabs) {
  console.log(tab.url());
}

getCookies()

Returns all cookies from the current browser context.

const cookies = await session.getCookies();

setCookies(cookies)

Adds cookies to the browser context. Cookies with a domain but no path default to path: '/'.

await session.setCookies([{ name: 'session', value: 'abc123', domain: '.example.com' }]);

saveCookies(filePath) / loadCookies(filePath)

Persist cookies to a JSON file and restore them later. Useful for maintaining login state across sessions. loadCookies requires a JSON array and skips entries without name, value, and url or domain.

await session.saveCookies('./cookies.json');

// later...
const session2 = new BrowserSession();
await session2.start();
await session2.loadCookies('./cookies.json');

Initial Cookies

Pass cookies at construction time to have them applied on start():

const session = new BrowserSession({
  cookies: [{ name: 'token', value: 'xyz', domain: '.example.com', path: '/' }],
});
await session.start();

Accessing Playwright Objects

For advanced use cases, you can access the underlying Playwright objects directly:

session.browser; // Browser | null (null with persistentContext)
session.context; // BrowserContext | null
session.page; // active Page

The resolved configuration is available too:

session.config; // BrowserSessionConfig with defaults applied
session.stealthEnabled; // true when `stealth` is set
session.stealthConfig; // StealthConfig merged with defaults, or null

Next Steps

On this page