Skip to main content

Watching your sessions

Both the Browserless Docker image and Dedicated hosted plans have the ability to watch sessions as they run in real-time. This is a powerful debugging and monitoring feature for engineers building on top of Browserless.

This guide covers three methods for watching your sessions:

  1. Using the Docker image session viewer
  2. Using the Sessions tab in Dedicated plans
  3. Programmatically watching sessions via GraphQL API

Watching sessions on the Docker image

To use the session viewer on the Docker image, you don't need to do anything special in your code or how you connect to Browserless. Optionally, you can add an id parameter to your connect call to sort or filter sessions to the one you care about.

Start the container as usual:

$ docker run --rm -p 3000:3000 ghcr.io/browserless/chrome

Then, in your application or script connect to it.

import puppeteer from "puppeteer";

const browser = await puppeteer.connect({
browserWSEndpoint: `wss://YOUR_CONTAINER_URL_HERE?token=YOUR_API_TOKEN_HERE`,
});
const page = await browser.newPage();
await page.goto("https://example.com/");
await browser.close();

In your browser, you can go to http://localhost:3000/sessions to get a JSON of the running sessions.

info

If your session is immediately closing, then you can keep it open by not calling browser.close at the end (just remember to terminate your script with CTRL+C or similar).

Using the Sessions tab in Dedicated plans

In Dedicated plans, you can see your active sessions at any time by going to the Sessions portion of the account page.

To view running sessions:

  1. Click the "Fetch Running Sessions" button to retrieve actively running sessions across all your workers
  2. Click the "Debugger" link to open and view specific sessions

Sessions appear in the list immediately after connecting, simply refresh by clicking "Fetch Running Sessions".

Programmatically watching your sessions on Dedicated plans

Thanks to our powerful GraphQL API, you can programmatically retrieve your running sessions with a simple API call. This feature allows you to build powerful integrations:

  • End-users can witness their automation running in real-time
  • Engineers can debug live production issues
  • You can more easily pinpoint problems in your scripts

Security note: When setting this up, ensure you don't accidentally expose non-relevant sessions among your users. Use a unique id parameter to filter and distinguish between running sessions.

For those that want to see the full example, see below. We'll break it down step-by-step afterwards.

import puppeteer from "puppeteer";

const apiToken = "YOUR_API_TOKEN_HERE";
const id = "some-unique-id";

const getSessionsById = (id) => {
return fetch("https://api.browserless.io/graphql", {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
query: `
query getSessions($id: String!, $apiToken: String!) {
sessions(apiToken: $apiToken, id: $id) {
description
devtoolsFrontendUrl
id
title
url
browserId
browserWSEndpoint
}
}
`,
variables: {
id,
apiToken,
},
}),
})
.then((res) => res.json())
.then((res) => res.data.sessions)
.catch((error) => {
console.log(`Error retrieving sessions ${error.message}`);
return null;
});
};

const run = async () => {
const sleep = (ms) => new Promise((res) => setTimeout(res, ms));

let browser = null;

try {
browser = await puppeteer.connect({
browserWSEndpoint: `wss://YOUR_CONTAINER_URL_HERE?token=${apiToken}&id=${id}`,
});

const page = await browser.newPage();
await page.goto("https://example.com");

const [session] = await getSessionsById(id);

if (!session) {
throw new Error(`Error retrieving session!`);
}

console.log(`Open: ${session.devtoolsFrontendUrl} in your browser!`);

// Let the page stay open for 30 seconds so we can debug!
await sleep(30000);
} catch (error) {
console.error(`Saw error when running: ${error.message}`);
} finally {
if (browser) {
console.log(`Shutting down the browser.`);
browser.close();
}
}
};

run();

Selecting the modules to use

The examples above use puppeteer or playwright for browser automation.

You're free to use whatever modules you like, including Selenium. However, Puppeteer and Playwright are the most commonly used libraries and have the best support.

Next, let's set up the function to get sessions from the GraphQL endpoint.

Fetching sessions

Our function below takes a single argument: the id we intend to use for the session. In a production system, you should always make this ID unique as it'll prevent you from accidentally watching the wrong session. If you need a recommendation, we suggest something like a UUID or a GUID library.

const getSessionsById = (id) => {
return fetch('https://api.browserless.io/graphql', {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({
query: `
query getSessions($id: String!, $apiToken: String!) {
sessions(apiToken: $apiToken, id: $id) {
description
devtoolsFrontendUrl
id
title
url
browserId
browserWSEndpoint
}
}
`,
variables: {
id,
apiToken,
},
});
})
.then((res) => res.json())
.then((res) => res.data.sessions)
.catch((error) => {
console.log(`Error retrieving sessions ${error.message}`);
return null;
});
};

The below query is the underlying GraphQL request, that says we want to retrieve the following properties for our session. In our example we only make use of the devtoolsFrontendUrl, so you're free to remove the others if you wish, they're there for educational purposes.

query getSessions($id: String!, $apiToken: String!) {
sessions(apiToken: $apiToken, id: $id) {
description
devtoolsFrontendUrl
id
title
url
id
browserId
browserWSEndpoint
}
}

In GraphQL terms, we're setting up a "function" here that retrieves sessions with your API Token and id. The response will contain something like:

{
"data": {
"sessions": [
{
"id": null,
"initialConnectURL": "wss://YOUR_CONTAINER_URL_HERE/firefox/playwright/?token=YOUR_API_TOKEN_HERE",
"isTempDataDir": true,
"launchOptions": {},
"numbConnected": 1,
"routePath": ["/firefox/playwright", "/firefox/playwright"],
// ...
}
]
}
}

In all of our returned links we omit your API token, so you'll need to add it to the link manually to visit it. This is done for security purposes.

Hooking up puppeteer/playwright

In our puppeteer or playwright setups, the run function, we start the browser and begin to write our script. Once we know the page is open, we use our GraphQL fetching function to get the active sessions (filtered by id), and log the response.

In reality you can do whatever you'd like with this response: save it in a database or load it in a user's page. However, once the session is done the link will no longer respond properly, and the session will return a 404.

Here's that code again:

const run = async () => {
const sleep = (ms) => new Promise((res) => setTimeout(res, ms));

let browser = null;

try {
browser = await puppeteer.connect({
browserWSEndpoint: `wss://YOUR_CONTAINER_URL_HERE?token=${apiToken}&id=${id}`,
});

const page = await browser.newPage();
await page.goto("https://example.com");

const [session] = await getSessionsById(id);

if (!session) {
throw new Error(`Error retrieving session!`);
}

console.log(`Open: ${session.devtoolsFrontendUrl} in your browser!`);

// Let the page stay open for 30 seconds so we can debug!
await sleep(30000);
} catch (error) {
console.error(`Saw error when running: ${error.message}`);
} finally {
if (browser) {
console.log(`Shutting down the browser.`);
browser.close();
}
}
};

run();

You'll note that we have a page.waitFor call in here as well: this is to ensure you have time to visit the debugging page. In a production system, the page interactions can happen quickly, and so it's easy to go to a debug page and miss all of the interactivity. If it's crucial that you witness the script as it runs we recommend pausing the script on startup with the &pause query-string parameter in your puppeteer.connect call.

That's it! You've successfully setup a running puppeteer session, and have a way to view the session as needed! If you've found this helpful, or need help with an issue, please let us know