CAPSOLVER
Blog
How to Solve CAPTCHA in BrowserStack with CapSolver API

How to Solve CAPTCHA in BrowserStack with CapSolver API

Logo of CapSolver

Lucas Mitchell

Automation Engineer

20-Aug-2025

BrowserStack is a leading cloud-based testing platform widely used by developers, QA teams, and automation engineers to run web automation, browser testing, and web scraping at scale. It provides instant access to thousands of real browsers, devices, and operating systems, making cross-browser testing, mobile testing, and automation with tools like Selenium, Playwright, and Puppeteer much easier.

For teams building automated browsers, bots, or large-scale scrapers, BrowserStack removes the need to maintain physical infrastructure. However, when tests or crawlers interact with production websites that employ anti-bot measures, CAPTCHAs often interrupt workflows, causing failures or requiring manual intervention.

CapSolver is an AI-powered CAPTCHA-solving service that handles a wide range of CAPTCHA types, including reCAPTCHA and Cloudflare Turnstile, with high accuracy and speed. Integrating CapSolver with BrowserStack ensures smoother automation, keeping CI/CD pipelines, test suites, and scraping tasks efficient and reliable.

BrowserStack Overview & Use Cases

BrowserStack is an AI-enhanced testing platform that reimagines the testing lifecycle, offering comprehensive solutions for browser and app testing. By leveraging a unified data store and AI agents, it accelerates test automation and improves reliability at scale. Teams can run cross-browser and mobile tests on real devices, perform automated UI and end-to-end testing with frameworks like Selenium, Playwright, and Puppeteer, and include visual and accessibility checks — all integrated with CI/CD tools such as Jenkins, Travis CI, and GitLab.

In automation-heavy workflows, such as e-commerce end-to-end testing or login flow validation, CAPTCHAs often act as anti-bot defenses, interrupting scripts and reducing reliability. CapSolver provides an automated solution, seamlessly handling these challenges to keep tests running smoothly.

Why CAPTCHA Solving is Needed

During automated testing on BrowserStack, scripts may navigate to websites protected by anti-bot systems that deploy CAPTCHAs to prevent scripted access. These challenges—intended to verify human users—can cause test failures, flaky results, or the need for manual overrides, undermining the efficiency of CI/CD pipelines. For instance, testing a form submission on a site with reCAPTCHA might fail without a way to solve the challenge programmatically.

Common CAPTCHA types include:

CAPTCHA Type Description
reCAPTCHA v2 Requires users to check a box or select images based on a prompt.
reCAPTCHA v3 Uses a scoring system to assess user behavior, often invisible to users.
Cloudflare Turnstile A privacy-focused CAPTCHA alternative that minimizes user interaction.

Integrating CapSolver into your BrowserStack tests allows automation scripts to solve these CAPTCHAs dynamically, ensuring tests run smoothly across diverse environments without interruptions.

How to Use CapSolver to Handle CAPTCHAs

CapSolver's API solves CAPTCHAs by submitting tasks and retrieving solutions via simple HTTP requests. To integrate it with BrowserStack, incorporate CapSolver calls into your automation scripts (e.g., Selenium, Playwright, or Puppeteer) that run on BrowserStack's remote grid.

Steps to Integrate CapSolver with BrowserStack

  1. Sign Up for CapSolver: Register at CapSolver Dashboard, add funds, and get your API key.
  2. Set Up BrowserStack: Create a BrowserStack account, obtain your username and access key, and configure your automation framework to connect to BrowserStack's hub.
  3. Install Dependencies: Depending on your framework, install packages like selenium, playwright, or pyppeteer.
  4. Add CapSolver Logic: In your script, detect CAPTCHAs (e.g., by site key), create a CapSolver task, poll for the solution, and inject it into the page.
  5. Run Tests on BrowserStack: Execute scripts on various BrowserStack configurations (e.g., Windows/Chrome, macOS/Safari) to verify CAPTCHA handling across platforms.

Key Code Snippet

Below is a basic Python function to solve reCAPTCHA v2 using CapSolver:

python Copy
import requests
import time

API_KEY = "YOUR_CAPSOLVER_API_KEY"

def solve_captcha(site_key, url):
    # Create a Capsolver task
    create_task = {
        "clientKey": API_KEY,
        "task": {
            "type": "ReCaptchaV2TaskProxyless",
            "websiteURL": url,
            "websiteKey": site_key,
        }
    }
    
    resp = requests.post("https://api.capsolver.com/createTask", json=create_task)
    task_id = resp.json().get("taskId")
    
    if not task_id:
        raise RuntimeError("Failed to create CapSolver task")
    
    # Poll for the result
    while True:
        result = requests.post(
            "https://api.capsolver.com/getTaskResult",
            json={"clientKey": API_KEY, "taskId": task_id}
        )
        payload = result.json()
        if payload.get("status") == "ready":
            return payload["solution"]["gRecaptchaResponse"]
        
        time.sleep(2)

Notes:

  • Replace YOUR_CAPSOLVER_API_KEY with your actual API key.
  • To solve other CAPTCHA types, update the type field in the task dictionary (e.g., ReCaptchaV2TaskProxyless).

Complete Code Example + Step-by-Step Explanation

Below are complete examples for integrating CapSolver with BrowserStack using Selenium, Playwright, and Puppeteer. Each tests a reCAPTCHA demo site on multiple platforms.

Prerequisites

  • Install dependencies:
bash Copy
pip install selenium playwright pyppeteer requests python-dotenv
  • For Playwright/Puppeteer:
bash Copy
playwright install
  • Create a .env file with the following variables:
Copy
CAPSOLVER_API_KEY
BROWSERSTACK_USERNAME
BROWSERSTACK_ACCESS_KEY

Selenium Example

python Copy
import time
import os
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from dotenv import load_dotenv

# Load environment variables
load_dotenv()
API_KEY = os.getenv("CAPSOLVER_API_KEY")
BROWSERSTACK_USERNAME = os.getenv("BROWSERSTACK_USERNAME")
BROWSERSTACK_ACCESS_KEY = os.getenv("BROWSERSTACK_ACCESS_KEY")

def solve_captcha(site_key, url):
    """Create a CapSolver task and poll for the solution token."""
    create_task = {
        "clientKey": API_KEY,
        "task": {
            "type": "ReCaptchaV2TaskProxyless",
            "websiteURL": url,
            "websiteKey": site_key,
        }
    }

    print(f"Creating task with API_KEY: {API_KEY[:10]}...")
    print(f"Site key: {site_key}")
    print(f"URL: {url}")

    resp = requests.post("https://api.capsolver.com/createTask", json=create_task)
    print(f"Response status: {resp.status_code}")
    print(f"Response text: {resp.text}")
    resp.raise_for_status()
    task_id = resp.json().get("taskId")

    if not task_id:
        raise RuntimeError("Failed to create CapSolver task")

    while True:
        result = requests.post(
            "https://api.capsolver.com/getTaskResult",
            json={"clientKey": API_KEY, "taskId": task_id}
        )
        print(f"Task result status: {result.status_code}")
        print(f"Task result response: {result.text}")
        result.raise_for_status()
        payload = result.json()

        if payload.get("status") == "ready":
            return payload["solution"]["gRecaptchaResponse"]

        time.sleep(2)

def main():
    if not BROWSERSTACK_USERNAME or not BROWSERSTACK_ACCESS_KEY:
        raise SystemExit("Please set BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY environment variables")

    # BrowserStack capabilities
    bstack_options = {
        "os": "Windows",
        "osVersion": "11",
        "buildName": "Capsolver Test",
        "sessionName": "Captcha Solve",
        "local": "false",
        "debug": "true",
        "video": "true",
        "networkLogs": "true",
    }

    options = Options()
    options.set_capability("browserName", "Chrome")
    options.set_capability("browserVersion", "latest")
    options.set_capability("bstack:options", bstack_options)

    hub_url = f"https://{BROWSERSTACK_USERNAME}:{BROWSERSTACK_ACCESS_KEY}@hub-cloud.browserstack.com/wd/hub"
    driver = webdriver.Remote(command_executor=hub_url, options=options)

    # Print session info for live observation
    print(f"BrowserStack Session ID: {driver.session_id}")
    print("Watch live at: https://automate.browserstack.com/dashboard/v2/builds")

    try:
        url = "https://www.google.com/recaptcha/api2/demo"
        driver.get(url)

        site_key = driver.find_element(By.CLASS_NAME, "g-recaptcha").get_attribute("data-sitekey")
        token = solve_captcha(site_key, url)

        # Make response textarea visible and set the token
        driver.execute_script('document.getElementById("g-recaptcha-response").style.display = "block";')
        driver.execute_script(f'document.getElementById("g-recaptcha-response").value = "{token}";')
        driver.find_element(By.ID, "recaptcha-demo-submit").click()

        time.sleep(3)  # Wait for page to load

        # Inspect page after submission
        print("=" * 50)
        print("PAGE RESPONSE AFTER SUBMIT:")
        print("=" * 50)
        print(f"Current URL: {driver.current_url}")
        print(f"Page Title: {driver.title}")

        page_source = driver.page_source
        print(f"Page source length: {len(page_source)} characters")

        # Check for success or error indicators
        if any(word in page_source.lower() for word in ['success', 'verificado', 'genial', 'hooray']):
            print("✅ SUCCESS indicator found in page!")
        if "error" in page_source.lower():
            print("❌ ERROR indicator found in page!")
        if "captcha" in page_source.lower():
            print("🔄 CAPTCHA still present in page")

        # Preview first 500 characters of body text
        try:
            body = driver.find_element(By.TAG_NAME, "body")
            print(f"Body text preview:\n{body.text[:500]}")
        except Exception:
            print("Could not extract body text")

        print("=" * 50)
        time.sleep(2)

    finally:
        driver.quit()

if __name__ == "__main__":
    main()
Step Description
1. Load Dependencies and Env Import libraries and load API keys from .env.
2. Define solve_captcha Create and poll CapSolver task for reCAPTCHA v2 solution.
3. Configure BrowserStack Set capabilities for remote WebDriver (e.g., Windows/Chrome).
4. Navigate and Solve Go to demo site, extract site key, solve CAPTCHA, inject token.
5. Submit and Verify Click submit, wait, and check for success indicators in response.
6. Clean Up Quit the driver to close the session.

Playwright Example (Async)

python Copy
import time
import os
import requests
import asyncio
import json
from playwright.async_api import async_playwright
from dotenv import load_dotenv

# Load environment variables
load_dotenv()
API_KEY = os.getenv("CAPSOLVER_API_KEY")
BROWSERSTACK_USERNAME = os.getenv("BROWSERSTACK_USERNAME")
BROWSERSTACK_ACCESS_KEY = os.getenv("BROWSERSTACK_ACCESS_KEY")

def solve_captcha(site_key, url):
    """
    Create a CapSolver task and poll for a solution token.
    Works the same as Selenium example.
    """
    create_task = {
        "clientKey": API_KEY,
        "task": {
            "type": "ReCaptchaV2TaskProxyless",
            "websiteURL": url,
            "websiteKey": site_key,
        }
    }

    print(f"Creating task with API_KEY: {API_KEY[:10]}...")
    print(f"Site key: {site_key}")
    print(f"URL: {url}")

    resp = requests.post("https://api.capsolver.com/createTask", json=create_task)
    print(f"Response status: {resp.status_code}")
    print(f"Response text: {resp.text}")
    resp.raise_for_status()
    task_id = resp.json().get("taskId")

    if not task_id:
        raise RuntimeError("Failed to create CapSolver task")

    # Poll until solution is ready
    while True:
        result = requests.post(
            "https://api.capsolver.com/getTaskResult",
            json={"clientKey": API_KEY, "taskId": task_id}
        )
        result.raise_for_status()
        payload = result.json()
        if payload.get("status") == "ready":
            return payload["solution"]["gRecaptchaResponse"]
        time.sleep(2)

async def run_captcha_test(platform_config):
    """Run captcha test on a specific platform configuration via BrowserStack."""
    print(f"\n🚀 Testing on: {platform_config['name']}")
    async with async_playwright() as playwright:
        # Connect to BrowserStack using CDP endpoint
        ws_endpoint = f"wss://cdp.browserstack.com/playwright?caps={platform_config['caps_string']}"
        try:
            browser = await playwright.chromium.connect_over_cdp(ws_endpoint)
            context = await browser.new_context(viewport={'width': 1280, 'height': 720})
            page = await context.new_page()
            
            print(f"✅ Connected to BrowserStack")
            print("🔗 Watch live at: https://automate.browserstack.com/dashboard/v2/builds")
            
            # Navigate to reCAPTCHA demo page
            url = "https://www.google.com/recaptcha/api2/demo"
            await page.goto(url, wait_until="domcontentloaded", timeout=30000)
            await page.wait_for_selector(".g-recaptcha", timeout=20000)
            site_key = await page.get_attribute(".g-recaptcha", "data-sitekey")
            
            print(f"🔑 Found site key: {site_key}")
            print("\n🧩 Solving captcha with CapSolver...")
            token = solve_captcha(site_key, url)
            print(f"✅ Got captcha token: {token[:50]}...")
            
            # Inject token and submit form
            await page.evaluate('document.getElementById("g-recaptcha-response").style.display = "block";')
            await page.evaluate(f'document.getElementById("g-recaptcha-response").value = "{token}";')
            await page.click("#recaptcha-demo-submit")
            await page.wait_for_timeout(5000)
            
            # Get page info and check success
            current_url = page.url
            page_title = await page.title()
            body_text = await page.text_content("body")
            
            success_indicators = ['success', 'verificado', 'genial', 'hooray']
            is_success = any(word in body_text.lower() for word in success_indicators)
            has_error = 'error' in body_text.lower()
            has_captcha = 'captcha' in body_text.lower()
            
            print("\n" + "=" * 60)
            print(f"🎯 RESULTS FOR {platform_config['name']}:")
            print("=" * 60)
            print(f"📍 URL: {current_url}")
            print(f"📄 Title: {page_title}")
            print(f"🎉 Success: {'✅ YES' if is_success else '❌ NO'}")
            if has_error:
                print("❌ ERROR indicator found!")
            if has_captcha:
                print("🔄 CAPTCHA still present!")
            print(f"\n📝 Page Preview (first 500 chars):\n{'-'*40}\n{body_text[:500]}")
            print("=" * 60)
            
            await page.wait_for_timeout(3000)
            return {'platform': platform_config['name'], 'success': is_success, 'url': current_url, 'title': page_title}
        except Exception as e:
            print(f"❌ Error on {platform_config['name']}: {str(e)}")
            return {'platform': platform_config['name'], 'success': False, 'error': str(e)}
        finally:
            try:
                await browser.close()
            except Exception as e:
                print(f"Warning: Error closing browser: {e}")
                pass

def create_browserstack_caps(platform):
    """Create BrowserStack capabilities for Playwright and return URL-encoded string."""
    import urllib.parse
    caps = {
        'browserstack.username': BROWSERSTACK_USERNAME,
        'browserstack.accessKey': BROWSERSTACK_ACCESS_KEY,
        'project': 'Playwright Capsolver Test',
        'build': 'Captcha Solve Demo',
        'name': f"Captcha Test - {platform.get('browserName', 'chrome')}",
        'browserstack.debug': 'true',
        'browserstack.console': 'info',
        'browserstack.networkLogs': 'true',
        'browserstack.timezone': 'UTC'
    }
    if 'os' in platform:
        caps['os'] = platform['os']
        caps['os_version'] = platform['osVersion']
        caps['browser'] = platform['browserName']
        caps['browser_version'] = platform['browserVersion']
    elif 'deviceName' in platform:
        caps['device'] = platform['deviceName']
        caps['os_version'] = platform['osVersion']
        caps['browser'] = platform['browserName']
        caps['real_mobile'] = 'true'
    caps_json = json.dumps(caps)
    caps_string = urllib.parse.quote(caps_json)
    return caps, caps_string

async def main():
    """Main function to run tests on multiple platforms."""
    if not API_KEY or API_KEY == "YOUR_CAPSOLVER_API_KEY":
        raise SystemExit("Please set CAPSOLVER_API_KEY environment variable")

    platforms = [
        {'name': 'Windows 11 - Chrome', 'os': 'Windows', 'osVersion': '11', 'browserName': 'chrome', 'browserVersion': 'latest'},
        {'name': 'macOS Ventura - Chrome', 'os': 'OS X', 'osVersion': 'Ventura', 'browserName': 'chrome', 'browserVersion': 'latest'}
    ]

    print("🚀 Starting Playwright + BrowserStack + CapSolver Demo...")
    results = []
    for platform in platforms:
        try:
            caps, caps_string = create_browserstack_caps(platform)
            platform['caps'] = caps
            platform['caps_string'] = caps_string
            result = await run_captcha_test(platform)
            results.append(result)
            await asyncio.sleep(2)
        except Exception as e:
            print(f"❌ Failed to test {platform['name']}: {str(e)}")
            results.append({'platform': platform['name'], 'success': False, 'error': str(e)})

    # Summary
    print("\n" + "🏆"*60)
    print("FINAL SUMMARY - ALL PLATFORMS")
    print("🏆"*60)
    successful_platforms = [r['platform'] for r in results if r['success']]
    failed_platforms = [r['platform'] for r in results if not r['success']]
    for r in results:
        if r['success']:
            print(f"✅ {r['platform']}: SUCCESS")
        else:
            print(f"❌ {r['platform']}: FAILED - {r.get('error', 'Unknown error')}")
    print(f"\n📊 Success Rate: {len(successful_platforms)}/{len(results)} platforms")
    print(f"⏰ Test completed at: {time.strftime('%Y-%m-%d %H:%M:%S')}")
    if successful_platforms:
        print(f"\n🎉 Successful platforms: {', '.join(successful_platforms)}")
    if failed_platforms:
        print(f"\n⚠️  Failed platforms: {', '.join(failed_platforms)}")
    print("🏆"*60)

if __name__ == "__main__":
    asyncio.run(main())
Step Description
1. Load Dependencies and Env Import async libraries and load keys.
2. Define solve_captcha Same as Selenium; handles task creation/polling.
3. Configure Platforms Define BrowserStack configs for multiple OS/devices.
4. Connect and Test Use CDP to connect, navigate, solve, submit, and verify per platform.
5. Summarize Results Collect and print success rates across platforms.
6. Clean Up Close browser contexts asynchronously.

Puppeteer Example (pyppeteer)

python Copy
import time
import os
import requests
import asyncio
import json
import urllib.parse
from pyppeteer import connect
from dotenv import load_dotenv

# Load environment variables
load_dotenv()
API_KEY = os.getenv("CAPSOLVER_API_KEY")
BROWSERSTACK_USERNAME = os.getenv("BROWSERSTACK_USERNAME")
BROWSERSTACK_ACCESS_KEY = os.getenv("BROWSERSTACK_ACCESS_KEY")

def solve_captcha(site_key, url):
    """
    Create a CapSolver task and poll for a solution token.
    """
    create_task = {
        "clientKey": API_KEY,
        "task": {
            "type": "ReCaptchaV2TaskProxyless",
            "websiteURL": url,
            "websiteKey": site_key,
        }
    }

    print(f"Creating task with API_KEY: {API_KEY[:10]}...")
    print(f"Site key: {site_key}")
    print(f"URL: {url}")

    resp = requests.post("https://api.capsolver.com/createTask", json=create_task)
    print(f"Response status: {resp.status_code}")
    print(f"Response text: {resp.text}")
    resp.raise_for_status()
    task_id = resp.json().get("taskId")

    if not task_id:
        raise RuntimeError("Failed to create CapSolver task")

    # Poll until solution is ready
    while True:
        result = requests.post(
            "https://api.capsolver.com/getTaskResult",
            json={"clientKey": API_KEY, "taskId": task_id}
        )
        print(f"Task result status: {result.status_code}")
        print(f"Task result response: {result.text}")
        result.raise_for_status()
        payload = result.json()
        if payload.get("status") == "ready":
            return payload["solution"]["gRecaptchaResponse"]
        time.sleep(2)


async def run_captcha_test(platform_config):
    """Run captcha test on a specific platform configuration."""
    print(f"\n🚀 Testing on: {platform_config['name']}")
    print(f"Platform details: {platform_config}")

    try:
        # Create BrowserStack WebSocket endpoint for Puppeteer
        ws_endpoint = f"wss://cdp.browserstack.com/puppeteer?caps={platform_config['caps_string']}"

        # Connect to BrowserStack using Puppeteer CDP
        browser = await connect(
            browserWSEndpoint=ws_endpoint,
            ignoreHTTPSErrors=True,
            args=['--no-sandbox', '--disable-setuid-sandbox']
        )

        # Create new page
        page = await browser.newPage()
        await page.setViewport({'width': 1280, 'height': 720})

        print(f"✅ Connected to BrowserStack via Puppeteer")
        print(f"🔗 Watch live at: https://automate.browserstack.com/dashboard/v2/builds")

        # Navigate to reCAPTCHA demo
        url = "https://www.google.com/recaptcha/api2/demo"
        await page.goto(url, {'waitUntil': 'domcontentloaded', 'timeout': 30000})
        print(f"📍 Navigated to: {url}")

        # Wait for page to load and find site key
        await page.waitForSelector(".g-recaptcha", {'timeout': 20000})
        site_key_element = await page.querySelector(".g-recaptcha")
        site_key = await page.evaluate('(element) => element.getAttribute("data-sitekey")', site_key_element)
        print(f"🔑 Found site key: {site_key}")

        # Solve captcha using CapSolver
        print("\n🧩 Solving captcha with CapSolver...")
        token = solve_captcha(site_key, url)
        print(f"✅ Got captcha token: {token[:50]}...")

        # Inject the captcha solution
        print("\n💉 Injecting captcha solution...")
        await page.evaluate('document.getElementById("g-recaptcha-response").style.display = "block";')
        await page.evaluate(f'document.getElementById("g-recaptcha-response").value = "{token}";')

        # Submit the form
        print("📤 Submitting form...")
        await page.click("#recaptcha-demo-submit")

        # Wait for response
        print("⏳ Waiting for response...")
        await asyncio.sleep(5)

        # Get results
        current_url = page.url
        page_title = await page.title()
        body_text = await page.evaluate('() => document.body.textContent')

        # Check for success indicators
        success_indicators = ['success', 'verificado', 'genial', 'hooray']
        is_success = any(word in body_text.lower() for word in success_indicators)
        has_error = 'error' in body_text.lower()
        has_captcha = 'captcha' in body_text.lower()

        # Display results
        print("\n" + "=" * 60)
        print(f"🎯 RESULTS FOR {platform_config['name']}:")
        print("=" * 60)
        print(f"📍 Current URL: {current_url}")
        print(f"📄 Page Title: {page_title}")
        print(f"⏰ Timestamp: {time.strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"🎉 Success: {'✅ YES' if is_success else '❌ NO'}")
        if has_error:
            print("❌ ERROR indicator found in page!")
        if has_captcha:
            print("🔄 CAPTCHA still present in page")
        print(f"\n📝 Page Response Preview:")
        print("-" * 40)
        print(body_text[:500])
        print("=" * 60)

        if is_success:
            print(f"\n🎊 SUCCESS! Captcha solved on {platform_config['name']}!")
        else:
            print(f"\n⚠️  Something went wrong on {platform_config['name']}.")

        # Wait a bit to observe results
        await asyncio.sleep(3)

        # Mark test status in BrowserStack
        try:
            status = "passed" if is_success else "failed"
            reason = f"Captcha solved successfully on {page_title}" if is_success else "Captcha solving failed"
            await page.evaluate(f'''
                browserstack_executor: {{
                    "action": "setSessionStatus", 
                    "arguments": {{
                        "status": "{status}", 
                        "reason": "{reason}"
                    }}
                }}
            ''')
        except Exception as e:
            print(f"Warning: Could not set BrowserStack status: {e}")

        return {'platform': platform_config['name'], 'success': is_success, 'url': current_url, 'title': page_title}

    except Exception as e:
        print(f"❌ Error on {platform_config['name']}: {str(e)}")
        return {'platform': platform_config['name'], 'success': False, 'error': str(e)}

    finally:
        try:
            if 'browser' in locals():
                await browser.close()
        except Exception as e:
            print(f"Warning: Error closing browser: {e}")
            pass


def create_browserstack_caps(platform):
    """Create BrowserStack capabilities for Puppeteer."""
    caps = {
        'browserstack.username': BROWSERSTACK_USERNAME,
        'browserstack.accessKey': BROWSERSTACK_ACCESS_KEY,
        'project': 'Puppeteer Capsolver Test',
        'build': 'Captcha Solve Demo - Puppeteer',
        'name': f"Captcha Test - {platform.get('browserName', 'chrome')} (Puppeteer)",
        'browserstack.debug': 'true',
        'browserstack.console': 'info',
        'browserstack.networkLogs': 'true',
        'browserstack.timezone': 'UTC'
    }

    # Add platform-specific capabilities
    if 'os' in platform:
        caps['os'] = platform['os']
        caps['os_version'] = platform['osVersion']
        caps['browser'] = platform['browserName']
        caps['browser_version'] = platform['browserVersion']
    elif 'deviceName' in platform:
        caps['device'] = platform['deviceName']
        caps['os_version'] = platform['osVersion']
        caps['browser'] = platform['browserName']
        caps['real_mobile'] = 'true'

    # Convert to URL-encoded JSON string
    caps_json = json.dumps(caps)
    caps_string = urllib.parse.quote(caps_json)

    return caps, caps_string


async def main():
    """Main function to run tests on multiple platforms."""
    if not API_KEY or API_KEY == "YOUR_CAPSOLVER_API_KEY":
        raise SystemExit("Please set CAPSOLVER_API_KEY environment variable")

    # Define platforms to test
    platforms = [
        {'name': 'Windows 11 - Chrome (Puppeteer)', 'os': 'Windows', 'osVersion': '11', 'browserName': 'chrome', 'browserVersion': 'latest'},
        {'name': 'macOS Ventura - Chrome (Puppeteer)', 'os': 'OS X', 'osVersion': 'Ventura', 'browserName': 'chrome', 'browserVersion': 'latest'},
        {'name': 'Samsung Galaxy S23 Ultra - Chrome (Puppeteer)', 'deviceName': 'Samsung Galaxy S23 Ultra', 'browserName': 'chrome', 'osVersion': '13.0'}
    ]

    print("🚀 Starting Puppeteer + BrowserStack + CapSolver Demo...")
    print(f"📱 Testing on {len(platforms)} different platforms:")
    for i, platform in enumerate(platforms, 1):
        print(f"  {i}. {platform['name']}")

    results = []

    # Test each platform
    for platform in platforms:
        try:
            caps, caps_string = create_browserstack_caps(platform)
            platform['caps'] = caps
            platform['caps_string'] = caps_string
            result = await run_captcha_test(platform)
            results.append(result)
            await asyncio.sleep(2)
        except Exception as e:
            print(f"❌ Failed to test {platform['name']}: {str(e)}")
            results.append({'platform': platform['name'], 'success': False, 'error': str(e)})

    # Final summary
    print("\n" + "🏆"*60)
    print("FINAL SUMMARY - ALL PLATFORMS (PUPPETEER)")
    print("🏆"*60)

    successful_platforms = [r['platform'] for r in results if r['success']]
    failed_platforms = [r['platform'] for r in results if not r['success']]

    for r in results:
        if r['success']:
            print(f"✅ {r['platform']}: SUCCESS")
        else:
            print(f"❌ {r['platform']}: FAILED - {r.get('error', 'Unknown error')}")

    print(f"\n📊 Success Rate: {len(successful_platforms)}/{len(results)} platforms")
    print(f"⏰ Test completed at: {time.strftime('%Y-%m-%d %H:%M:%S')}")

    if successful_platforms:
        print(f"\n🎉 Successful platforms: {', '.join(successful_platforms)}")
    if failed_platforms:
        print(f"\n⚠️  Failed platforms: {', '.join(failed_platforms)}")

    print("🏆"*60)
    print("\n💡 Note: This demo uses pyppeteer (Python Puppeteer) with BrowserStack")
    print("   For best results, ensure your BrowserStack plan supports CDP connections")


if __name__ == "__main__":
    asyncio.run(main())

Steps / Workflow

Step Description
1. Load Dependencies & Env Use pyppeteer with BrowserStack and CapSolver.
2. Define solve_captcha Same logic as the Playwright example.
3. Configure Platforms Supports Chrome/Chromium and some mobile devices.
4. Connect & Test Connect via WebSocket/CDP, navigate page, solve CAPTCHA, submit, and set session status.
5. Summarize Results Output results per platform and overall summary.
6. Clean Up Close the browser after each test.

Demo Walkthrough

These scripts demonstrate CAPTCHA solving on a reCAPTCHA demo site using BrowserStack's remote environments:

  1. Setup and Connection: The script connects to BrowserStack's hub/CDP endpoint with specified capabilities (e.g., Windows 11/Chrome).
  2. Navigation: Loads the demo URL and waits for the CAPTCHA element.
  3. CAPTCHA Detection and Solving: Extracts the site key, calls CapSolver, and injects the token.
  4. Submission: Clicks the submit button and waits for the response.
  5. Verification: Checks page content for success indicators and prints results.
  6. Multi-Platform Testing: For Playwright/Puppeteer, runs across defined platforms (e.g., desktop and mobile), summarizing outcomes.

You can observe sessions live on BrowserStack's dashboard using the printed session ID. Successful runs show the form submitted without CAPTCHA blocks.

Conclusion

Integrating CapSolver with BrowserStack enhances your automated testing by automatically handling CAPTCHAs, ensuring reliable results across diverse environments. This setup leverages BrowserStack's scalable grid and CapSolver's AI accuracy for efficient, interruption-free workflows.

Get started by signing up for CapSolver and BrowserStack. Implement the examples above and explore further integrations. For more, check the CapSolver docs and BrowserStack docs. Try this in your tests today and streamline your CAPTCHA challenges!

Bonus for Browser-use Users: Use the promo code BROWSERSTACK when recharging your CapSolver account and receive an exclusive 6% bonus credit—no limits, no expiration.
![][image1]

FAQ Section

Question Answer
What types of CAPTCHAs can CapSolver solve? CapSolver supports reCAPTCHA v2/v3, Cloudflare Turnstile, and more. Refer to the CapSolver documentation for a complete list.
How do I handle different CAPTCHA types? Update the CapSolver task type (e.g., ReCaptchaV2TaskProxyless) and adjust detection/injection logic based on the CAPTCHA's elements.
What if CapSolver fails to solve the CAPTCHA? Add retry mechanisms or fallbacks in your script. Monitor BrowserStack logs for debugging.
Can I use CapSolver with other testing platforms? Yes, CapSolver works with any automation framework via HTTP APIs, including local setups or other clouds like Sauce Labs.
Do I need proxies with CapSolver on BrowserStack? Proxies are optional but useful for geo-specific CAPTCHAs. BrowserStack handles IP diversity; see CapSolver docs for proxy integration.

Supported Browsers and Tools

  • BrowserStack: Supports Chrome, Firefox, Safari, Edge, and mobile browsers on real devices.
  • Automation Frameworks: Selenium, Playwright, Puppeteer, Appium, Cypress.

References

Compliance Disclaimer: The information provided on this blog is for informational purposes only. CapSolver is committed to compliance with all applicable laws and regulations. The use of the CapSolver network for illegal, fraudulent, or abusive activities is strictly prohibited and will be investigated. Our captcha-solving solutions enhance user experience while ensuring 100% compliance in helping solve captcha difficulties during public data crawling. We encourage responsible use of our services. For more information, please visit our Terms of Service and Privacy Policy.

More

.How to Solve CAPTCHAs in Python Using Botasaurus and CapSolver (Full Guide)
How to Solve CAPTCHAs in Python Using Botasaurus and CapSolver (Full Guide)

Learn to integrate Botasaurus (Python web scraping framework) with CapSolver API to automatically solve reCAPTCHA v2/v3 and Turnstile.

web scraping
Logo of CapSolver

Lucas Mitchell

12-Dec-2025

web scraping errors
What are 402, 403, 404, and 429 Errors in Web Scraping? A Comprehensive Guide

Master web scraping error handling by understanding what are 402, 403, 404, and 429 errors. Learn how to fix 403 Forbidden, implement rate limiting error 429 solutions, and handle the emerging 402 Payment Required status code.

web scraping
Logo of CapSolver

Sora Fujimoto

11-Dec-2025

Best Web Scraping APIs in 2026: Top Tools Compared & Ranked
Best Web Scraping APIs in 2026: Top Tools Compared & Ranked

Discover the best Web Scraping APIs for 2026. We compare the top tools based on success rate, speed, AI features, and pricing to help you choose the right solution for your data extraction needs.

web scraping
Logo of CapSolver

Ethan Collins

11-Dec-2025

CapSolver Extension icon with the text "Solve image captcha in your browser," illustrating the extension's primary function for ImageToText challenges.
CapSolver Extension: Effortlessly Solve Image Captcha and ImageToText Challenges in Your Browser

Use the CapSolver Chrome Extension for AI-powered, one-click solving of Image Captcha and ImageToText challenges directly in your browser.

Extension
Logo of CapSolver

Lucas Mitchell

11-Dec-2025

Cloudflare Challenge vs Turnstile by CapSolver
Cloudflare Challenge vs Turnstile: Key Differences and How to Identify Them

nderstand the key differences between Cloudflare Challenge vs Turnstile and learn how to identify them for successful web automation. Get expert tips and a recommended solver.

Cloudflare
Logo of CapSolver

Lucas Mitchell

10-Dec-2025

How to solve AWS Captcha / Challenge using PHP
How to Solve AWS Captcha / Challenge with PHP: A Comprehensive Guide

A detailed PHP guide to solving AWS WAF CAPTCHA and Challenge for reliable scraping and automation

AWS WAF
Logo of CapSolver

Rajinder Singh

10-Dec-2025