Skip to main content

Capabilities

Using Playwright with BrowserStack requires passing the custom capabilities in an object, and passing this object to the Playwright URL endpoint on BrowserStack. This section includes a sample script file along with a detailed reference of all the supported capabilities.

// fixtures.js

const base = require('@playwright/test');
const cp = require('child_process');
const clientPlaywrightVersion = cp
  .execSync('npx playwright --version')
  .toString()
  .trim()
  .split(' ')[1];
const BrowserStackLocal = require('browserstack-local');

// BrowserStack Specific Capabilities.
const caps = {
  os: 'osx',
  os_version: 'catalina',
  browser: 'chrome',
  browser_version: 'latest',
  'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'YOUR_USERNAME',
  'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY',
  'browserstack.geoLocation': 'FR',
  project: 'My First Project',
  build: 'playwright-build-1',
  name: 'My first playwright test',
  buildTag: 'reg',
  resolution: '1280x1024',
  'browserstack.local': 'true',
  'browserstack.localIdentifier': 'local_connection_name',
  'browserstack.playwrightVersion': '1.latest',
  'client.playwrightVersion': '1.latest',
  'browserstack.debug': 'true',  // enabling visual logs
  'browserstack.console': 'info'  // Enabling Console logs for the test
  'browserstack.networkLogs': 'true'  // Enabling network logs for the test
  'browserstack.networkLogsOptions':
      {
        'captureContent': 'true'
      }
}

exports.bsLocal = new BrowserStackLocal.Local();

// replace YOUR_ACCESS_KEY with your key. You can also set an environment variable - "BROWSERSTACK_ACCESS_KEY".
exports.BS_LOCAL_ARGS = {
  key: process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY',
};

// Patching the capabilities dynamically according to the project name.
const patchCaps = (name, title) => {
  let combination = name.split(/@browserstack/)[0];
  let [browerCaps, osCaps] = combination.split(/:/);
  let [browser, browser_version] = browerCaps.split(/@/);
  let osCapsSplit = osCaps.split(/ /);
  let os = osCapsSplit.shift();
  let os_version = osCapsSplit.join(' ');
  caps.browser = browser ? browser : 'chrome';
  caps.browser_version = browser_version ? browser_version : 'latest';
  caps.os = os ? os : 'osx';
  caps.os_version = os_version ? os_version : 'catalina';
  caps.name = title;
};

const isHash = (entity) => Boolean(entity && typeof(entity) === "object" && !Array.isArray(entity));
const nestedKeyValue = (hash, keys) => keys.reduce((hash, key) => (isHash(hash) ? hash[key] : undefined), hash);
const isUndefined = val => (val === undefined || val === null || val === '');
const evaluateSessionStatus = (status) => {
  if (!isUndefined(status)) {
    status = status.toLowerCase();
  }
  if (status === "passed") {
    return "passed";
  } else if (status === "failed" || status === "timedout") {
    return "failed";
  } else {
    return "";
  }
}

exports.test = base.test.extend({
  page: async ({ page, playwright }, use, testInfo) => {
    // Use BrowserStack Launched Browser according to capabilities for cross-browser testing.
    if (testInfo.project.name.match(/browserstack/)) {
      patchCaps(testInfo.project.name, `${testInfo.file} - ${testInfo.title}`);
      const vBrowser = await playwright.chromium.connect({
        wsEndpoint:
          `wss://cdp.browserstack.com/playwright?caps=` +
          `${encodeURIComponent(JSON.stringify(caps))}`,
      });
      const vContext = await vBrowser.newContext(testInfo.project.use);
      const vPage = await vContext.newPage();
      await use(vPage);
      const testResult = {
        action: 'setSessionStatus',
        arguments: {
          status: evaluateSessionStatus(testInfo.status),
          reason: nestedKeyValue(testInfo, ['error', 'message'])
        },
      };
      await vPage.evaluate(() => {},
      `browserstack_executor: ${JSON.stringify(testResult)}`);
      await vPage.close();
      await vBrowser.close();
    } else {
      use(page);
    }
  },
});
// single_test.js

const expect = require('chai').expect
const { chromium } = require('playwright');

const cp = require('child_process');
const clientPlaywrightVersion = cp.execSync('npx playwright --version').toString().trim().split(' ')[1];

(async () => {
  const caps = {
    'os': 'os x',
    'os_version': 'big sur',
    'browser': 'chrome',  // You can choose `chrome`, `edge` or `firefox` in this capability
    'browser_version': 'latest',  // We support v83 and above. You can choose `latest`, `latest-beta`, `latest-1`, `latest-2` and so on, in this capability
    'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'YOUR_USERNAME',
    'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY',
    'browserstack.geoLocation': "FR",
    'project': 'My First Project',
    'build': 'playwright-build-1',
    'name': 'My First Test',  // The name of your test and build. See browserstack.com/docs/automate/playwright/organize tests for more details
    'buildTag': 'reg',
    'resolution': '1280x1024',
    'browserstack.local': 'true',
    'browserstack.localIdentifier': 'local_connection_name',
    'browserstack.playwrightVersion': '1.latest',  
    'client.playwrightVersion': '1.latest'
    'browserstack.debug': 'true',  // enabling visual logs
    'browserstack.console': 'info'  // Enabling Console logs for the test
    'browserstack.networkLogs': 'true'  // Enabling network logs for the test
    'browserstack.networkLogsOptions':
      {
        'captureContent': 'true'
      }
  };
  const browser = await chromium.connect({
    wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify(caps))}`,
  });
  const page = await browser.newPage();
  await page.goto('https://www.google.com/ncr');
  const element = await page.$('[aria-label="Search"]');
  await element.click();
  await element.type('BrowserStack');
  await element.press('Enter');
  const title = await page.title('');
  console.log(title);
  try {
    expect(title).to.equal("BrowserStack - Google Search", 'Expected page title is incorrect!');
    // following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test
    await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'passed',reason: 'Title matched'}})}`);
  } catch {
    await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'failed',reason: 'Title did not match'}})}`);
  }
  await browser.close();
})();
// PlaywrightTest.java

package com.browserstack;

import com.google.gson.JsonObject;
import com.microsoft.playwright.*;
import java.net.URLEncoder;

public class PlaywrightTest {
    public static void main(String[] args) {
        try (Playwright playwright = Playwright.create()) {

    JsonObject capabilitiesObject = new JsonObject();
        capabilitiesObject.addProperty("os", "osx");
        capabilitiesObject.addProperty("os_version", "catalina");
        capabilitiesObject.addProperty("browser", "chrome");    // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`
        capabilitiesObject.addProperty("browser_version", "latest");
        capabilitiesObject.addProperty("browserstack.username", "BROWSERSTACK_USERNAME");
        capabilitiesObject.addProperty("browserstack.accessKey", "BROWSERSTACK_ACCESS_KEY");
        capabilitiesObject.addProperty("browserstack.geoLocation", "FR");
        capabilitiesObject.addProperty("project", "My First Project");
        capabilitiesObject.addProperty("build", "playwright-java-1");
        capabilitiesObject.addProperty("name", "Playwright first single test");
        capabilitiesObject.addProperty("buildTag", "reg");
        capabilitiesObject.addProperty("resolution", "1280x1024");
        capabilitiesObject.addProperty("browserstack.local", "true");
        capabilitiesObject.addProperty("browserstack.localIdentifier", "local_connection_name");
        capabilitiesObject.addProperty("browserstack.playwrightVersion", "1.latest");
        capabilitiesObject.addProperty("client.playwrightVersion", "1.latest");
        capabilitiesObject.addProperty("browserstack.debug", "true");
        capabilitiesObject.addProperty("browserstack.console", "info");
        capabilitiesObject.addProperty("browserstack.networkLogs", "true");
            JsonObject nwOptions = new JsonObject();
                nwOptions.addProperty("captureContent", "true");
        capabilitiesObject.addProperty("browerstack.networkLogsOptions", nwOptions);    
            
            BrowserType chromium = playwright.chromium(); 
            String caps = URLEncoder.encode(capabilitiesObject.toString(), "utf-8");
            String ws_endpoint = "wss://cdp.browserstack.com/playwright?caps=" + caps;
            Browser browser = chromium.connect(ws_endpoint);
            Page page = browser.newPage();
            try {
                page.navigate("https://www.google.co.in/");
                Locator locator = page.locator("[aria-label='Search']");
                locator.click();
                page.fill("[aria-label='Search']", "BrowserStack");
                page.locator("[aria-label='Google Search'] >> nth=0").click();
                String title = page.title();

                if (title.equals("BrowserStack - Google Search")) {
                    // following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test
                    markTestStatus("passed", "Title matched", page);
                } else {
                    markTestStatus("failed", "Title did not match", page);
                }
                
            } catch (Exception err) {
                markTestStatus("failed", err.getMessage(), page);
            }
            browser.close();
        } catch (Exception err) {
            System.out.println(err);
        }
    }

    public static void markTestStatus(String status, String reason, Page page) {
        Object result;
        result = page.evaluate("_ => {}", "browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}");
    }
}
# playwright-test.py

import json
import urllib
import subprocess
from playwright.sync_api import sync_playwright

desired_cap = {
  'os': 'osx',
  'os_version': 'catalina',
  'browser': 'chrome',  # allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`
  'browser_version': 'latest', # this capability is valid only for branded `chrome` and `edge` browsers and you can specify any browser version like `latest`, `latest-beta`, `latest-1` and so on.
  'browserstack.username': 'BROWSERSTACK_USERNAME',
  'browserstack.accessKey': 'BROWSERSTACK_ACCESS_KEY',
  'browserstack.geoLocation': 'FR',
  'project': 'My First Project',
  'build': 'playwright-python-1',
  'name': 'My First Test',
  'buildTag': 'reg',
  'resolution': '1280x1024',
  'browserstack.local': 'true',
  'browserstack.localIdentifier': 'local_connection_name',
  'browserstack.playwrightVersion': '1.latest',
  'client.playwrightVersion': '1.latest'
    'browserstack.debug': 'true',  # enabling visual logs
    'browserstack.console': 'info',  # Enabling Console logs for the test
    'browserstack.networkLogs': 'true',  # Enabling network logs for the test
    'browserstack.networkLogsOptions':
      {
        'captureContent': 'true'
      }
  }

def run_session(playwright):
  clientPlaywrightVersion = str(subprocess.getoutput('playwright --version')).strip().split(" ")[1]
  desired_cap['client.playwrightVersion'] = clientPlaywrightVersion

  cdpUrl = 'wss://cdp.browserstack.com/playwright?caps=' + urllib.parse.quote(json.dumps(desired_cap))
  browser = playwright.chromium.connect(cdpUrl)
  page = browser.new_page()
  try:
    page.goto("https://www.google.co.in/")
    page.fill("[aria-label='Search']", 'Browserstack')
    locator = page.locator("[aria-label='Google Search'] >> nth=0")
    locator.click()
    title = page.title()

    if title == "Browserstack - Google Search":
      # following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test
      mark_test_status("passed", "Title matched", page)
    else:
      mark_test_status("failed", "Title did not match", page)
  except Exception as err:
      mark_test_status("failed", str(err), page)

  browser.close()

def mark_test_status(status, reason, page):
  page.evaluate("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\""+ status + "\", \"reason\": \"" + reason + "\"}}");

with sync_playwright() as playwright:
  run_session(playwright)
// PlaywrightTest.cs

using Microsoft.Playwright;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

class PlaywrightTest
{
    public static async Task main(string[] args)
    { 
    using var playwright = await Playwright.CreateAsync();
    Dictionary<string, string> browserstackOptions = new Dictionary<string, string>();
        browserstackOptions.Add("os", "osx");
        browserstackOptions.Add("os_version", "catalina");
        browserstackOptions.Add("browser", "chrome");  // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`
        browserstackOptions.Add("browser_version", "latest");
        browserstackOptions.Add("browserstack.username", "BROWSERSTACK_USERNAME");
        browserstackOptions.Add("browserstack.accessKey", "BROWSERSTACK_ACCESS_KEY");
        browserstackOptions.Add("geoLocation", "FR");
        browserstackOptions.Add("project", "Playwright first sample test");
        browserstackOptions.Add("name", "Playwright first sample test");
        browserstackOptions.Add("build", "playwright-dotnet-1");
        browserstackOptions.Add("buildTag", "reg");
        browserstackOptions.Add("resolution", "1280x1024");
        browserstackOptions.Add("browserstack.local", "true");
        browserstackOptions.Add("browserstack.localIdentifier", "local_connection_name");
        browserstackOptions.Add("browserstack.playwrightVersion", "1.latest");
        browserstackOptions.Add("client.playwrightVersion", "1.latest");
        browserstackOptions.Add("browserstack.debug", "true");
        browserstackOptions.Add("browserstack.console", "info");
        browserstackOptions.Add("browserstack.networkLogs", "true");
            Dictionary<string, string> nwOptions = new Dictionary<string, string>();
                nwOptions.Add("captureContent", "true")
        browserstackOptions.Add("browerstack.networkLogsOptions", nwOptions);    
        string capsJson = JsonConvert.SerializeObject(browserstackOptions);
        string cdpUrl = "wss://cdp.browserstack.com/playwright?caps=" + Uri.EscapeDataString(capsJson);

        await using var browser = await playwright.Chromium.ConnectAsync(cdpUrl);
        var page = await browser.NewPageAsync();
        try {
          await page.GotoAsync("https://www.google.co.in/");
          await page.Locator("[aria-label='Search']").ClickAsync();
          await page.FillAsync("[aria-label='Search']", "BrowserStack");
          await page.Locator("[aria-label='Google Search'] >> nth=0").ClickAsync();
          var title = await page.TitleAsync();

          if (title == "BrowserStack - Google Search")
          {
            // following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test
            await MarkTestStatus("passed", "Title matched", page);
          }
          else {
            await MarkTestStatus("failed", "Title did not match", page);
          }
        }
        catch (Exception err) {
          await MarkTestStatus("failed", err.Message, page);
        }
        await browser.CloseAsync();
    }

    public static async Task MarkTestStatus(string status, string reason, IPage page) {
        await page.EvaluateAsync("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\"" + status + "\", \"reason\": \"" + reason + "\"}}");
    }
}
The following table lists the supported Playwright capabilities and how they must be defined in your tests:
Capability Description
os Set the operating system on which you want to run your test
Eg. Windows or OS X

Ref: Specify which OS is to be used to run the test
os_version Set the specific version of the OS
Eg. Windows: 10, 11 or OS X: Mojave, Catalina, Big Sur and Monterey

Ref: Specify which OS version is to be used to run the test
browser Set the browser you want to use for your test.
For branded browsers, use: chrome or edge.
The browser_version capability is applicable only when using a branded browser.

For Playwright’s bundled browsers, use: playwright-chromium, playwright-firefox or playwright-webkit.

Ref: Specify the browser to be used
browser_version Set the browser version for your test
Chrome: 83 and above
Edge: 83 and above
It is recommended that you use latest, latest-1, latest-2, latest-beta and so on, to test on the latest n versions of the required browser.

Ref: Specify the browser version to be used
browserstack.username Your BrowserStack username which you can find in your account settings.
browserstack.accessKey Your BrowserStack access key which you can find in your account settings.
browserstack.geolocation Simulate the location of browsers

"geolocation": "<country_code>"
project Any string that you want to group your builds into.
Eg. New dashboard

Ref: Specify a name for your project
build A string that you want to identify your build with.
Eg. build 1

Ref: Specify a name for your build or CI run
name A string that you want to identify your session with.
Eg. My Test

Ref: Specify a name for your build or CI run
buildTag A string that you want to tag your build with.
Eg. sanity

Ref: Specify a tag for your test build
resolution Set the resolution of your desktop OS before beginning your test

Default resolution is 1920x1080

Ref: Specify desktop screen resolution
browserstack.local Test your locally hosted website on BrowserStack.
Defaults to false. Set value as true to enable.
browserstack.localIdentifier Specify the unique Local Testing connection name.
Eg. local_connection_name
browserstack.playwrightVersion Specify the Playwright version for your tests.
Use 1.latest to run tests on the latest version.

Ref: Set the supported Playwright version in your tests
client.playwrightVersion Specify the Playwright version for your tests on the client system.
Use 1.latest to run tests on the latest version.

Set a Playwright version on the client machine
browserstack.maskCommands Redacts sensitive information from the Automate logs.

Ref: Prevent sensitive test data from appearing in the Automate logs.
browserstack.debug Helps debug issues detected through your tests

Disabled by default. Set True to enable.
browserstack.video Provides a video recording of the actions performed during the test.

Available by default. Set false to disable.

Ref: Records every test as it is executed on BrowserStack
browserstack.console Captures the browser’s console output at various steps of the test.
Available by default. Set value as disable to disable the console logs.

Ref: Capture the browser’s console output at various steps of the test
browserstack.networkLogs Provides a comprehensive log of all network activity during your Playwright tests.

Defaults to false. Set true to enable.

browserstack.networkLogsOptions Captures the request and response payload of your test session

Defaults to false. Set true to enable.

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked






Thank you for your valuable feedback

Is this page helping you?

Yes
No

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked






Thank you for your valuable feedback!

Talk to an Expert
Talk to an Expert