Docs
Dashboard
Examples / Get startedBeta

Sessions and Playwright

Start a session, connect Playwright to its browser over CDP, read a page, and stop the session. The same page is then read through the actions API, which drives the browser without Playwright.

When to use it: Your first session: you know Playwright, or want to see the actions API next to it.

Usessessions, Playwright over CDP (connectUrl), the actions API (content)
Needsany plan; no shell, no model
Sitebooks.toscrape.com, a demo shop made for scraping practice
Outputoutput/result.json: the page title and the first 5 books with their prices
LanguagesNode and Python

The code

The example as it is in its folder. Both versions do the same job and write the same output/, so one result check covers both.

/** * Sessions and Playwright: start a session, connect Playwright to its browser, read a page, stop the session. * *   npx tsx node/index.ts            (BOXLINE_API_KEY in the environment) * * Writes output/result.json: the page title and the first 5 books with their prices. */import { mkdirSync, writeFileSync } from "node:fs";import { join } from "node:path";import { Boxline } from "@boxline/sdk";import { chromium } from "playwright-core";const out = process.env.OUTPUT_DIR ?? "output";const bx = new Boxline(); // reads BOXLINE_API_KEY, and BOXLINE_API_URL for another APIconst session = await bx.sessions.create({ timeout: 300, userMetadata: { example: "sessions-and-playwright" } });console.log(`Session: ${session.id}`);const browser = await chromium.connectOverCDP(session.connectUrl!); // a signed URL: treat it like a passwordtry {  const page = browser.contexts()[0]!.pages()[0]!;  await page.goto("https://books.toscrape.com/");  const title = await page.title();  const books = await page.$$eval("article.product_pod", (items) =>    items.slice(0, 5).map((item) => ({      title: item.querySelector("h3 a")?.getAttribute("title") ?? "",      price: item.querySelector(".price_color")?.textContent?.trim() ?? "",    })),  );  console.table(books);  // The actions API drives the same browser without Playwright: one HTTP call, here for the page as text.  const { title: actionsTitle, content } = await session.content("text");  console.log(`The actions API sees "${actionsTitle}" (${content.length} characters of text)`);  mkdirSync(out, { recursive: true });  writeFileSync(join(out, "result.json"), JSON.stringify({ sessionId: session.id, title, books, actionsTitle }, null, 2));} finally {  await session.stop(); // saves the session and ends its billing  await browser.close().catch(() => undefined);}

Run it

Get the examples with git clone https://github.com/Boxline-dev/examples.git and open this one: cd examples/sessions-and-playwright. Put your API key in BOXLINE_API_KEY (and BOXLINE_API_URL for another API), then run either version from the example’s folder. Both write to output/ and stop their sessions when they finish.

# Node 18 or newer, in the example's folderexport BOXLINE_API_KEY=…   # your API keynpm install @boxline/sdk playwright-core tsxnpx tsx node/index.ts

Then check the result, from the same folder: npx tsx check.ts output. It exits with 0 only when the result is right.

What its check proves

check.ts reads what the example wrote and passes only when the result is right, not merely when the example ran.

There are 5 books, the first is "A Light in the Attic" at £51.77, every book has a £ price, and Playwright and the actions API saw the same page.

Source

github.com/Boxline-dev/examples/sessions-and-playwright on GitHub, with its README.md, check.ts and .env.example. The examples are open source. See all examples.

These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.