Introduction to BrowserStack
BrowserStack is a cloud-based cross-browser testing platform that enables developers and QA teams to test websites and mobile applications across thousands of real browsers, operating systems, and devices. It eliminates the need for maintaining an in-house device lab, providing instant access to comprehensive testing environments. BrowserStack helps identify compatibility issues, ensure consistent user experiences, and accelerate the development lifecycle through its Live, Automate, App Live, App Automate, and Percy testing services.
Core BrowserStack Products
Live Testing Services
| Product | Purpose | Key Features |
|---|
| Live | Manual cross-browser testing of websites | Real browsers on real OS, local testing, browser dev tools |
| App Live | Manual testing of mobile apps | Real devices, geolocation testing, network simulation |
| Percy | Visual testing & UI review | Screenshot comparison, visual diffs, responsive testing |
| ScreenShot | Bulk screenshot capture | Multiple browsers at once, responsive layouts testing |
| Local | Test localhost & internal environments | Secure tunnel to private networks, no public access required |
Automated Testing Services
| Product | Purpose | Key Features |
|---|
| Automate | Automated browser testing | Selenium & Cypress integration, parallel tests, CI/CD integration |
| App Automate | Automated app testing | Appium support, real device cloud, test analytics |
| Test Observability | Test analytics & insights | Failure analysis, test flakiness detection, trend reporting |
| Enterprise | Team management & security | Single sign-on, role-based access, audit logs |
BrowserStack Live Testing
Quick Start Steps
- Log in to BrowserStack account
- Select “Live” from dashboard
- Choose browser, OS and device combination
- Enter URL to test
- Perform manual tests in real browser environment
Keyboard Shortcuts
| Action | Windows/Linux | macOS |
|---|
| Switch to local machine | Ctrl+Shift+1 | Cmd+Shift+1 |
| Switch to remote machine | Ctrl+Shift+2 | Cmd+Shift+2 |
| Access DevTools | F12 or Ctrl+Shift+I | Cmd+Option+I |
| Take screenshot | Ctrl+Shift+S | Cmd+Shift+S |
| Open new tab | Ctrl+N | Cmd+N |
| Switch tab | Ctrl+Tab | Cmd+Shift+→ |
| Text select mode | Ctrl+Shift+T | Cmd+Shift+T |
| Geolocation settings | Ctrl+Shift+L | Cmd+Shift+L |
| Network settings | Ctrl+Shift+N | Cmd+Shift+N |
| End session | Alt+Q | Option+Q |
Live Testing Features
- Real device interaction (swipe, multi-touch)
- Responsive testing with viewport resizing
- Network throttling options
- Browser developer tools access
- Local testing via BrowserStackLocal
- Text and file upload/download testing
- Instant screenshots capture
- Session video recording
BrowserStack Automate
Setup and Configuration
Basic Selenium Configuration (Java)
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
public class BrowserStackTest {
public static void main(String[] args) throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("browserName", "Chrome");
capabilities.setCapability("browserVersion", "latest");
capabilities.setCapability("os", "Windows");
capabilities.setCapability("osVersion", "10");
HashMap<String, Object> browserStackOptions = new HashMap<String, Object>();
browserStackOptions.put("userName", "USERNAME");
browserStackOptions.put("accessKey", "ACCESS_KEY");
browserStackOptions.put("projectName", "My Project");
browserStackOptions.put("buildName", "Build #1");
browserStackOptions.put("sessionName", "My Test");
capabilities.setCapability("bstack:options", browserStackOptions);
WebDriver driver = new RemoteWebDriver(
new URL("https://hub-cloud.browserstack.com/wd/hub"), capabilities);
driver.get("https://www.example.com");
// Test code
driver.quit();
}
}
Cypress Configuration (cypress.json)
{
"projectId": "your-project-id",
"baseUrl": "https://example.com",
"integrationFolder": "cypress/integration",
"defaultCommandTimeout": 10000,
"viewportHeight": 900,
"viewportWidth": 1440,
"browserstack": {
"username": "USERNAME",
"accessKey": "ACCESS_KEY",
"dashboardProject": "My Dashboard Project",
"dashboardBuild": "Build 1",
"browsers": [
{
"browser": "chrome",
"os": "Windows 10",
"versions": ["latest", "latest-1"]
},
{
"browser": "firefox",
"os": "OS X Monterey",
"versions": ["latest"]
}
]
}
}
Common Desired Capabilities
| Category | Capability | Description | Example Values |
|---|
| Browser | browserName | Browser type | chrome, firefox, edge, safari |
| Â | browserVersion | Browser version | latest, latest-1, 100 |
| OS | os | Operating system | Windows, OS X, Android, iOS |
| Â | osVersion | OS version | 10, Monterey, 12 |
| Project | buildName | Build identifier | Sprint-4, Release-2.1 |
| Â | projectName | Project name | E-commerce Website |
| Â | sessionName | Test session name | Homepage Navigation Test |
| Settings | debug | Enable debugging | true, false |
| Â | networkLogs | Capture network logs | true, false |
| Â | consoleLogs | Capture console logs | true, false |
| Â | video | Record video | true, false |
| Â | seleniumVersion | Specify Selenium version | 4.0.0 |
| Mobile | deviceName | Mobile device | iPhone 13, Google Pixel 6 |
| Â | realMobile | Use real device | true, false |
| Â | appiumVersion | Appium version | 1.22.0 |
BrowserStack App Testing
App Live Quick Start
- Upload your APK/IPA file
- Select device and OS combination
- Launch app on the selected device
- Perform manual testing
App Automate with Appium (Java)
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import org.openqa.selenium.remote.DesiredCapabilities;
public class BrowserStackAppTest {
public static void main(String[] args) throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
HashMap<String, Object> browserStackOptions = new HashMap<String, Object>();
browserStackOptions.put("userName", "USERNAME");
browserStackOptions.put("accessKey", "ACCESS_KEY");
browserStackOptions.put("appiumVersion", "1.22.0");
browserStackOptions.put("projectName", "My App Project");
browserStackOptions.put("buildName", "Build #1");
browserStackOptions.put("sessionName", "Login Test");
capabilities.setCapability("bstack:options", browserStackOptions);
capabilities.setCapability("platformName", "iOS");
capabilities.setCapability("platformVersion", "15");
capabilities.setCapability("deviceName", "iPhone 13 Pro");
capabilities.setCapability("app", "bs://app-id-hash");
AppiumDriver<MobileElement> driver = new AppiumDriver<MobileElement>(
new URL("https://hub-cloud.browserstack.com/wd/hub"), capabilities);
// Test code
driver.quit();
}
}
App Automate Features
- Native app testing on real devices
- Hybrid app testing support
- Gesture automation (swipe, pinch, zoom)
- Biometric authentication testing
- Geolocation simulation
- Network condition simulation
- App upload/install
- Device logs and video recording
- Appium Inspector integration
BrowserStack Local Testing
Local Binary Setup
- Download BrowserStackLocal binary from dashboard
- Run with access key:
./BrowserStackLocal --key YOUR_ACCESS_KEY
Common Local Binary Parameters
| Parameter | Description | Example |
|---|
| –key | Your access key | –key abcd1234 |
| –local-identifier | Specify unique ID | –local-identifier test123 |
| –force-local | Force all traffic through local | –force-local |
| –force-proxy | Use proxy for all connections | –force-proxy |
| –proxy-host | Proxy host | –proxy-host 127.0.0.1 |
| –proxy-port | Proxy port | –proxy-port 8080 |
| –proxy-user | Proxy username | –proxy-user username |
| –proxy-pass | Proxy password | –proxy-pass password |
| –only | Restrict testing to listed domains | –only example.com,local.dev |
| –verbose | Enable verbose logging | –verbose |
| –force | Kill other running BrowserStackLocal | –force |
Local Testing in Automation
Java
import com.browserstack.local.Local;
public class LocalTest {
public static void main(String[] args) throws Exception {
Local local = new Local();
HashMap<String, String> options = new HashMap<String, String>();
options.put("key", "YOUR_ACCESS_KEY");
options.put("localIdentifier", "test123");
local.start(options);
System.out.println("Local binary connected");
// Set up WebDriver
DesiredCapabilities capabilities = new DesiredCapabilities();
HashMap<String, Object> browserStackOptions = new HashMap<String, Object>();
browserStackOptions.put("userName", "USERNAME");
browserStackOptions.put("accessKey", "ACCESS_KEY");
browserStackOptions.put("local", "true");
browserStackOptions.put("localIdentifier", "test123");
capabilities.setCapability("bstack:options", browserStackOptions);
// Run test
local.stop();
}
}
Node.js
const browserstack = require('browserstack-local');
const webdriver = require('selenium-webdriver');
// Creates an instance of Local
const bs_local = new browserstack.Local();
// Start BrowserStackLocal
const bs_local_args = { 'key': 'YOUR_ACCESS_KEY', 'localIdentifier': 'test123' };
bs_local.start(bs_local_args, function() {
console.log("Started BrowserStackLocal");
// Set up WebDriver
let capabilities = {
'bstack:options': {
'userName': 'USERNAME',
'accessKey': 'ACCESS_KEY',
'local': 'true',
'localIdentifier': 'test123',
'projectName': 'My Project',
'buildName': 'Local Testing'
},
'browserName': 'Chrome'
};
// Run test
// Stop local at end
bs_local.stop(function() {
console.log("Stopped BrowserStackLocal");
});
});
BrowserStack Percy
Setup for Web Application
Install Percy SDK for your framework
npm install --save-dev @percy/cli @percy/cypress
Add Percy to your tests
Cypress
// In cypress/support/commands.js
import '@percy/cypress';
// In your test
describe('Homepage', () => {
it('should display correctly', () => {
cy.visit('/');
cy.percySnapshot('Homepage');
});
});
WebdriverIO
const percySnapshot = require('@percy/webdriverio');
describe('Visual Test', () => {
it('should match homepage design', async () => {
await browser.url('/');
await percySnapshot('Homepage');
});
});
Percy CLI Commands
| Command | Description |
|---|
npx percy exec -- cypress run | Run Cypress tests with Percy |
npx percy exec -- wdio wdio.conf.js | Run WebdriverIO tests with Percy |
npx percy screenshot path/to/site.html | Take snapshot of static HTML |
npx percy exec:start | Start Percy in snapshot mode |
npx percy exec:stop | Stop Percy server |
npx percy upload path/to/snapshots | Upload snapshots to Percy |
Percy Snapshot Options
cy.percySnapshot('Name', {
widths: [375, 768, 1280], // Responsive widths to capture
minHeight: 1000, // Minimum height
percyCSS: '.flaky-element { visibility: hidden; }', // Hide flaky elements
scope: '.main-content', // Limit snapshot to element
discovery: { // Discovery options
requestHeaders: { // Custom headers for snapshot
Authorization: 'Basic xxx'
},
disableShadowDOM: false // Shadow DOM handling
}
});
BrowserStack Test Analytics & Reporting
Accessing Reports
- Log in to BrowserStack dashboard
- Navigate to “Reports” section
- Filter by project, build, or test
- View test status, errors, and metrics
Test Status Marking
// Java - Selenium
import org.openqa.selenium.JavascriptExecutor;
// Mark test as passed
((JavascriptExecutor)driver).executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\", \"reason\": \"All assertions passed\"}}");
// Mark test as failed
((JavascriptExecutor)driver).executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"failed\", \"reason\": \"Title assertion failed\"}}");
// JavaScript - WebdriverIO
// Mark test as passed
await browser.executeScript('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status": "passed", "reason": "All assertions passed"}}');
// Mark test as failed
await browser.executeScript('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status": "failed", "reason": "Login failed"}}');
Debug Information APIs
// Java - Add custom test metadata
((JavascriptExecutor)driver).executeScript("browserstack_executor: {\"action\": \"annotate\", \"arguments\": {\"data\": \"User login successful\", \"level\": \"info\"}}");
// Console logs
((JavascriptExecutor)driver).executeScript("browserstack_executor: {\"action\": \"consoleLogs\", \"arguments\": {\"type\": \"info\"}}");
// Network logs
((JavascriptExecutor)driver).executeScript("browserstack_executor: {\"action\": \"networkLogs\", \"arguments\": {\"enable\": true}}");
Test Observability Features
- Failure analysis
- Test flakiness detection
- Test impact analysis
- Error grouping
- Test analytics dashboard
- Trend reporting
Parallel Testing & CI/CD Integration
Parallel Testing Setup
// Java TestNG example
@Test(threadPoolSize = 5, invocationCount = 5, timeOut = 30000)
public void testParallel() {
// Each thread gets unique capabilities
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("browserName", "Chrome");
capabilities.setCapability("browserVersion", "latest");
// Create unique session for each thread
WebDriver driver = new RemoteWebDriver(new URL("https://hub-cloud.browserstack.com/wd/hub"), capabilities);
// Test code
driver.quit();
}
CI/CD Integration Examples
Jenkins Pipeline
pipeline {
agent any
stages {
stage('BrowserStack Test') {
steps {
browserstack(credentialsId: 'browserstack') {
sh 'npm install'
sh 'npm test'
}
}
}
}
}
GitHub Actions
name: BrowserStack Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run BrowserStack tests
env:
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
run: npm test
CircleCI
version: 2.1
jobs:
test:
docker:
- image: cimg/node:16.13
steps:
- checkout
- run:
name: Install dependencies
command: npm install
- run:
name: Run BrowserStack tests
command: npm test
environment:
BROWSERSTACK_USERNAME: ${BROWSERSTACK_USERNAME}
BROWSERSTACK_ACCESS_KEY: ${BROWSERSTACK_ACCESS_KEY}
workflows:
version: 2
build_and_test:
jobs:
- test
Mobile App Testing
App Upload APIs
# Upload Android APK
curl -u "USERNAME:ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/upload" \
-F "file=@/path/to/app.apk"
# Upload iOS IPA
curl -u "USERNAME:ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/upload" \
-F "file=@/path/to/app.ipa"
App Automate Capabilities
| Category | Capability | Description | Example |
|---|
| App | app | App ID from upload | bs://app-id-hash |
| Â | appPackage | Android package name | com.example.app |
| Â | appActivity | Android main activity | .MainActivity |
| Â | bundleId | iOS bundle identifier | com.example.app |
| Mobile | deviceName | Device to test on | iPhone 13 Pro, Samsung Galaxy S22 |
| Â | platformName | Mobile platform | iOS, Android |
| Â | platformVersion | OS version | 15, 12 |
| Â | orientation | Device orientation | portrait, landscape |
| Features | geoLocation | Set location | US, IN |
| Â | deviceOrientation | Device rotation | portrait, landscape |
| Â | language | App language | fr, en |
| Â | locale | App locale | fr_FR, en_US |
| Settings | idleTimeout | Session timeout in seconds | 300 |
| Â | noReset | Preserve app state | true, false |
| Â | fullReset | Clean app state | true, false |
App Testing Advanced Features
- Biometric authentication
- QR/barcode scanning
- Deep linking
- Background app management
- Push notification testing
- Offline mode testing
- App install/uninstall
- Device permissions management
Security Features
User Management
- Role-based access control
- Team management
- Project-based permissions
- IP-based access restrictions
Enterprise Features
- Single Sign-On (SSO) integration
- Audit logs
- Data retention policies
- Network security settings
- Secure local testing
Compliance
- SOC2 compliance
- GDPR compliance
- Data encryption
- PII handling
- Secure credential management
Optimization Best Practices
Test Efficiency
- Use proper waits (implicit, explicit, fluent)
- Implement page object model
- Run tests in parallel
- Use correct selectors (IDs over XPaths)
- Implement smart retries for flaky elements
- Limit test scope to specific functionality
BrowserStack-Specific Tips
- Use latest browser versions when possible
- Specify exact OS and browser combinations
- Limit parallel sessions to plan capacity
- Properly name tests and builds
- Use session timeouts to avoid wasted minutes
- Mark tests with proper status and reasons
- Use local binary with force flag when needed
Performance Optimization
- Bundle tests logically for parallel execution
- Use browserstack.json configuration file
- Implement smart waiting strategies
- Optimize local testing connection
- Cache dependencies in CI/CD pipelines
- Use browserstack-cypress-cli for Cypress tests
Resources for Further Learning
Official Documentation
Integration Tutorials
Advanced Topics
- BrowserStack REST APIs
- Custom network profiles
- Performance testing
- Test observability
- Mobile gesture automation
- Visual regression testing strategies
Remember that BrowserStack constantly updates its features and capabilities. Regular review of their documentation and release notes will help you leverage the latest tools and features for your testing needs.