Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quickstarts #2

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions examples/contexts/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Browserbase Context Persistence Demo

This project demonstrates how to use Browserbase's context persistence feature to maintain browser state across multiple sessions.

## Overview

The demo script showcases:
- Creating a Browserbase context
- Starting a browser session with a persistent context
- Setting and verifying cookie persistence between pages
- Creating a new session with the same context
- Verifying that the browser state (cookies) persists between sessions

## Prerequisites

- Node.js (v14 or higher recommended)
- A Browserbase account with API access
- Your Browserbase Project ID and API Key

## Installation

1. Clone this repository
2. Install dependencies: npm install
3. Create a `.env` file and add your Browserbase Project ID and API Key
4. Run: tsc -w
5. Run: node dist/index.js
159 changes: 159 additions & 0 deletions examples/contexts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import Browserbase from "@browserbasehq/sdk";
import { chromium, type Browser, type Cookie } from "playwright-core";
import dotenv from "dotenv";

dotenv.config();

// Configuration
const CONTEXT_TEST_URL = "https://www.browserbase.com";
const BROWSERBASE_PROJECT_ID = process.env["BROWSERBASE_PROJECT_ID"]!;
const BROWSERBASE_API_KEY = process.env["BROWSERBASE_API_KEY"]!;

const bb = new Browserbase({
apiKey: BROWSERBASE_API_KEY,
});

// Helper functions
function addHour(date: Date): number {
const SECOND = 1000;
return new Date(date.getTime() + 60 * 60 * 1000).getTime() / SECOND;
}

async function findCookie(
browser: Browser,
name: string
): Promise<Cookie | undefined> {
const [defaultContext] = browser.contexts();
const cookies = await defaultContext?.cookies();
console.log("Cookies:", cookies);
return cookies?.find((cookie) => cookie.name === name);
}

async function runSessionWithContextPersistence() {
let contextId: string;
let sessionId: string;
let testCookieName: string;
let testCookieValue: string;

try {
// Step 1: Create a context
console.log("Creating a new context...");
const context = await bb.contexts.create({
projectId: BROWSERBASE_PROJECT_ID,
});
contextId = context.id;
console.log(`Context created with context ID: ${contextId}`);

// Step 2: Create a session with the context
console.log("Creating a session with the context...");
const session = await bb.sessions.create({
projectId: BROWSERBASE_PROJECT_ID,
browserSettings: {
context: {
id: contextId,
persist: true,
},
},
});
sessionId = session.id;
console.log(`Session created with session ID: ${sessionId}`);

// Step 3: Populate and persist the context
console.log(`Creating browser and navigating to ${CONTEXT_TEST_URL}`);
const browser = await chromium.connectOverCDP(session.connectUrl);
const browserContext = browser.contexts()[0]!;
const page = browserContext.pages()[0]!;

await page.goto(CONTEXT_TEST_URL, { waitUntil: "domcontentloaded" });

// Set a random cookie on the page
console.log("Adding cookies...");
const now = new Date();
testCookieName = `bb_${now.getTime().toString()}`;
testCookieValue = now.toISOString();

await browserContext.addCookies([
{
domain: ".browserbase.com",
expires: addHour(now),
name: testCookieName,
path: "/",
value: testCookieValue,
},
]);

console.log("-");
console.log(`Set test cookie: ${testCookieName}=${testCookieValue}`);
console.log("-");

// Validate cookie persistence between pages
console.log("Navigating to Google and back to check cookie persistence...");
await page.goto("https://www.google.com", {
waitUntil: "domcontentloaded",
timeout: 60000,
});
await page.goBack();

const cookie = await findCookie(browser, testCookieName);
console.log("-");
console.log("Cookie persisted between pages:", !!cookie);
console.log("-");

await page.close();
await browser.close();
console.log("Closing first session...");

// Wait for context to persist
const persistTimeout = 5000;
console.log(`Waiting ${persistTimeout}ms for context to persist...`);
await new Promise((resolve) => setTimeout(resolve, persistTimeout));

// Step 4: Create another session with the same context
console.log(`Creating a new session with the same context ID: ${contextId}...`);
const newSession = await bb.sessions.create({
projectId: BROWSERBASE_PROJECT_ID,
browserSettings: {
context: {
id: contextId,
persist: false,
},
},
});
const newSessionId = newSession.id;
console.log(`Session created with session ID: ${newSessionId}`);

// Step 5: Verify previous state
console.log(`Creating browser and navigating to ${CONTEXT_TEST_URL}`);
const newBrowser = await chromium.connectOverCDP(newSession.connectUrl);
const newPage = newBrowser.contexts()[0]!.pages()[0]!;

await newPage.goto(CONTEXT_TEST_URL, { waitUntil: "domcontentloaded" });

const foundCookie = await findCookie(newBrowser, testCookieName);
console.log("-");
console.log("Cookie found in new session:", !!foundCookie);
console.log("-");
console.log(
"Cookie value matches:",
foundCookie?.value === testCookieValue
);
console.log("-");

console.log("Closing second session...");
await newPage.close();
await newBrowser.close();

console.log("Context persistence test completed successfully!");
console.log(
`View session replays at:\n https://browserbase.com/sessions/${sessionId}\n https://browserbase.com/sessions/${newSessionId}`
);
} catch (error) {
console.error("An error occurred:", error);
process.exit(1);
}
}

// Run the script
console.log("Running script...");
await runSessionWithContextPersistence();
console.log("Script completed!");
20 changes: 20 additions & 0 deletions examples/contexts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "contexts-playwright",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@browserbasehq/sdk": "^2.0.0",
"dotenv": "^16.4.7",
"playwright-core": "^1.43.1"
},
"devDependencies": {
"@types/node": "^20.12.7"
}
}
1 change: 1 addition & 0 deletions examples/contexts/placeholder.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

11 changes: 11 additions & 0 deletions examples/contexts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es2022",
"module": "nodenext",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"outDir": "dist/"
}
}
21 changes: 21 additions & 0 deletions examples/screenshot/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Browserbase Inc

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
62 changes: 62 additions & 0 deletions examples/screenshot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="logo/dark.svg"/>
<img alt="Browserbase logo" src="logo/light.svg" width="300" />
</picture>
</p>

<p align="center">
<a href="https://docs.browserbase.com">Documentation</a>
<span>&nbsp;·&nbsp;</span>
<a href="https://www.browserbase.com/playground">Playground</a>
</p>
<br/>

## Playwright with Browserbase
Browserbase is the best developer platform to reliably run, manage, and monitor headless browsers.

Get browsers' full control and leverage Browserbase's
[Infrastructure](https://docs.browserbase.com/under-the-hood), [Stealth Mode](https://docs.browserbase.com/features/stealth-mode), and
[Session Debugger](https://docs.browserbase.com/features/sessions) to power your automation, test suites,
and LLM data retrievals.

**Get started in under one minute** with Playwright.


## Setup

### 1. Install dependencies and launch TypeScript in watch mode:

```bash
npm install
tsc -w
```


### 2. Get your Browserbase API Key and Project ID:

- [Create an account](https://www.browserbase.com/sign-up) or [log in to Browserbase](https://www.browserbase.com/sign-in)
- Copy your API Key and Project ID [from your Settings page](https://www.browserbase.com/settings)
- Create a `.env` file in the root of the project and add the following variables:

```
BROWSERBASE_PROJECT_ID=xxx
BROWSERBASE_API_KEY=xxxx
```

### 3. Run the script:

```bash
node dist/index.js
```

### 4. Optional: Run in parallel

Update the `COUNT_TO_RUN_IN_PARALLEL` variable in the `index.ts` file to have parallel runs for testing.


## Further reading

- [See how to leverage the Session Debugger for faster development](https://docs.browserbase.com/guides/browser-remote-control#accelerate-your-local-development-with-remote-debugging)
- [Learn more about Browserbase infrastructure](https://docs.browserbase.com/under-the-hood)
- [Explore the Sessions API](https://docs.browserbase.com/api-reference/list-all-sessions)
86 changes: 86 additions & 0 deletions examples/screenshot/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { chromium } from "playwright-core";
import Browserbase from "@browserbasehq/sdk";
import dotenv from "dotenv";
import { writeFileSync } from "fs";

dotenv.config();

const PROJECT_ID = process.env.BROWSERBASE_PROJECT_ID;
const API_KEY = process.env.BROWSERBASE_API_KEY;

const URL_TO_TAKE_SCREENSHOT_OF = "https://www.oakley.com/en-us";

if (!API_KEY) {
throw new Error("BROWSERBASE_API_KEY is not set");
}

if (!PROJECT_ID) {
throw new Error("BROWSERBASE_PROJECT_ID is not set");
}

async function main() {
const bb = new Browserbase({
apiKey: API_KEY,
});

const session = await bb.sessions.create({
projectId: PROJECT_ID as string,
proxies: true,
browserSettings: {
viewport: {
width: 375,
height: 814,
},
fingerprint: {
devices: ["mobile"],
operatingSystems: ["ios"],
screen: {
minWidth: 375,
maxWidth: 428,
minHeight: 667,
maxHeight: 926,
},
},
},
});
console.log(`Session created, id: ${session.id}`);

console.log("Starting remote browser...");
const browser = await chromium.connectOverCDP(session.connectUrl);
const defaultContext = browser.contexts()[0];
const page = defaultContext.pages()[0]

await page.goto(URL_TO_TAKE_SCREENSHOT_OF, {
// let's make sure the page is fully loaded before asking for the live debug URL
waitUntil: "domcontentloaded",
});

const debugUrls = await bb.sessions.debug(session.id);
console.log(
`Session started, live debug accessible here: ${debugUrls.debuggerUrl}.`
);

console.log("Taking a screenshot!");
const buf = await page.screenshot({ fullPage: true });
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
writeFileSync(
`${process.env.HOME}/Downloads/screenshot-${timestamp}.jpeg`,
buf
);
console.log(
`Screenshot saved to Downloads folder: screenshot-${timestamp}.jpeg`
);

console.log("Shutting down...");
await page.close();
await browser.close();

console.log(
`Session complete! View replay at https://browserbase.com/sessions/${session.id}`
);
}

const COUNT_TO_RUN_IN_PARALLEL = 1;
for (let i = 0; i < COUNT_TO_RUN_IN_PARALLEL; i++) {
main();
}
Loading