ScreenshotNeo

BlogHow-to

How to Bypass CAPTCHAs in Browser Automation

For authorized browser tests, use your CAPTCHA provider’s test setup or a controlled mock. Don’t automate around a live challenge on a site you don’t control.

By the ScreenshotNeo team4 October 20269 min read

For a site you own or are authorized to test, the reliable way to get browser automation past a CAPTCHA is to configure the CAPTCHA provider’s documented test mode or use a deterministic mock in a non-production environment. Don’t try to defeat a live challenge. For a third-party site, stop at the challenge and use its supported access route or hand off to a person.

This guide uses Google reCAPTCHA examples because its official documentation publishes testing guidance and dedicated v2 test keys. The same principle applies to other providers: use their documented test configuration rather than attempting to solve or evade their production challenge.

1. Choose the right test approach

First decide what the test is meant to prove. A browser test can verify that your form submits and your application handles success and failure. It cannot establish that a production risk score is accurate if the provider says test traffic does not represent real traffic.

Approach Use it for What it validates Limit
Provider test key Authorized functional tests against your test or staging app Widget integration, form submission, and application success handling Test scores may not represent production risk. Keep test keys out of production.
Controlled mock Application tests where provider behavior is outside the test’s scope Your success, failure, and error handling Does not validate the real provider integration.
Production assessment Testing your deployed integration and server-side policy Token assessment, expected action, and your risk response Not a deterministic challenge-puzzle test.
Human-assisted check An authorized flow that genuinely presents a live challenge The end-to-end flow with a person completing the challenge Requires a person and should be an explicit test step.
Third-party live CAPTCHA No authorized test configuration or written permission Nothing suitable for unattended automation Stop and use supported access or contact the site owner.

Google recommends a separate reCAPTCHA v3 key for test environments and documents v2 test keys that always pass verification. Google warns that v3 scores may not be accurate in tests because v3 relies on real traffic. Keep functional test outcomes separate from production risk-score validation. Google’s reCAPTCHA FAQ documents these limitations.

2. Set up reCAPTCHA for an authorized test

  1. Confirm the site and test account belong to your organization or that written authorization covers the test.
  2. Use a non-production environment such as staging. Give it its own test key and credentials; do not silently substitute those values into production.
  3. For reCAPTCHA v2, Google publishes these keys for automated testing. The widget displays a warning, and verification requests always pass:
    Site key:   6LeIxAcTAAAAAJcZVRqyHh71UMIEGN_QMXL8QxT
    Secret key: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe

    Use the exact values from Google’s current FAQ when configuring your test application. The site key is public client configuration; the secret belongs only on your server. Never expose a production secret in browser code, a test report, or a committed file.

  4. For v3, create a separate test key and configure it only in the test environment. Treat its score as test plumbing, not as a production-quality risk signal.
  5. Verify your application handles successful submission and the failure or expired-token paths. For those paths, use a controlled mock or test fixture instead of changing a live challenge.

Google’s key guidance describes score-based keys as verifying interactions without user interaction, while checkbox and policy-based challenge keys can involve interactive challenges. It says checkbox keys add friction and do not significantly improve accuracy in its comparison. Choose a production key type based on your actual user flow and risk policy, not on what makes a test easiest. Google Cloud’s key type guidance also cautions that CAPTCHA challenges may not meet every accessibility requirement.

3. Run a Playwright test against your staging app

The example below assumes your staging app has a signup page at /signup, a form named signup, and a success message with role="status". Adjust those selectors to match your app. The test key must already be configured server-side in staging; Playwright should submit the normal form and observe the application outcome.

npm install --save-dev @playwright/test
npx playwright install chromium

Save as tests/signup.spec.js:

const { test, expect } = require('@playwright/test');

test('staging signup accepts the provider test configuration', async ({ page }) => {
  await page.goto('https://staging.example.com/signup');
  await page.getByLabel('Email').fill('automation@example.test');
  await page.getByLabel('Password').fill('example-test-password');
  await page.getByRole('button', { name: 'Create account' }).click();

  await expect(page.getByRole('status')).toContainText('Account created');
});

Run it with:

npx playwright test tests/signup.spec.js --project=chromium

Use a disposable test account and a staging endpoint that cannot trigger real purchases, emails, or other production side effects. Avoid assertions against reCAPTCHA’s internal iframe markup or timing: the app-visible result is the contract your test should check.

4. Test the application boundary with a mock when appropriate

If a test is only about your app’s handling of a verification result, inject a deterministic verifier in the test environment. Keep the mock behind an explicit test configuration that cannot be enabled in production. This example shows the shape of the boundary; wire it into your own server framework and test dependency mechanism.

// verifier.js
export async function verifyCaptcha(token) {
  // Production implementation calls the CAPTCHA provider from the server.
  return providerVerify(token);
}

// In a test-only dependency setup, replace the verifier:
const fakeVerifier = async (token) => ({
  valid: token === 'test-success',
  action: 'signup'
});

// Example assertions for the application handler:
assert.equal((await submitSignup({ token: 'test-success', verify: fakeVerifier })).status, 201);
assert.equal((await submitSignup({ token: 'test-failure', verify: fakeVerifier })).status, 400);

Keep the mock’s interface aligned with the fields your application actually consumes. A mock that always returns success can hide missing-token handling, invalid-token behavior, action mismatches, and provider outages. Add separate deterministic cases for those application paths.

5. Validate production integration without trying to solve challenges

Production checks should verify that the server assesses the token and applies the correct policy. For score-based integrations, bind the assessment to the expected action and reject invalid or mismatched tokens according to your policy. Google’s automated-threat guidance recommends creating assessments for tokens and checking that the expected action matches the client action. See Google Cloud’s automated-threat guidance and assessment documentation.

Do not make repeated attempts to clear a production CAPTCHA part of an unattended test. If a live challenge appears unexpectedly, record the environment and test context, stop the automation, and investigate whether the key, domain, action, or risk policy is configured as intended. For a third-party flow, use its supported route or a human handoff.

6. Accessibility and human handoff

A CAPTCHA should not be the only way a person can use your service. Google’s help documentation describes an audio option for visually challenged users, while its key selection guidance notes that CAPTCHA challenges are not accessible for everyone. Provide an accessible alternative or assisted support route, and include that route in your product’s operational design. Google’s reCAPTCHA help page explains the audio option.

In automated tests, assert that the accessible route or support link is present when your design requires it. Do not attempt to automate the audio puzzle as a substitute for an accessible product flow.

7. Troubleshooting

Symptom Likely cause Fix
“Localhost is not in the list of supported domains” The key’s allowed domains do not include the development hostname. Use a separate development key and add only the required development domain. Google recommends separate development and production keys; do not broaden the production key for convenience.
Test form fails even though the v2 test widget appears The application may be using the wrong site key or server secret, or its server-side verification path differs from the test configuration. Check the staging environment’s paired key configuration and server logs. Confirm the test secret is configured only on the server and that the deployed staging process loaded the intended values.
Test passes but the production score differs That is expected: Google says v3 test scores may not be accurate because it relies on real traffic. Use tests to validate integration behavior. Evaluate risk thresholds with suitable production signals and monitoring, not with a functional test score.
“Invalid,” “expired,” or missing token The token was not generated, was stale, was reused, or did not reach the server. For a test, inspect the form submission and server request path. Generate a fresh token as the provider integration expects; use a mock to exercise negative cases deterministically.
Expected action does not match The client token’s action and server assessment’s expected action differ. Use the same action identifier on both sides and reject mismatches according to your server policy. Check the provider’s assessment response.
Browser test hangs waiting for a challenge or selector The test is using a production key, a real interactive challenge, or a selector tied to provider internals. Use the documented test setup in staging, or mock the verification boundary for an app-only test. Wait for your app’s result state rather than challenge iframe details.
Works locally, fails in CI CI may be using different environment variables, a disallowed hostname, or a different staging deployment. Compare key configuration and hostname, use a dedicated CI/staging key where appropriate, and log non-secret configuration identifiers. Never print secrets into CI logs.
CAPTCHA blocks an accessibility test The test is relying on puzzle completion rather than the accessible alternative. Test the alternative or assisted route your product provides. For a live third-party challenge, hand off to a person.

8. Reliability, performance, and cost

  • Reliability: Provider test keys and deterministic mocks make functional tests repeatable. Keep separate suites for provider integration, application behavior, and production risk policy so a change in one does not obscure failures in another.
  • Performance: Do not add challenge-solving retries or long fixed sleeps. Wait for the application’s observable success or failure state with a bounded test timeout. Reuse the browser process for your normal test runner setup, while isolating accounts and state between cases.
  • Failure handling: Treat provider network errors as a distinct application case. Decide whether your server fails closed, offers another verification route, or retries based on your risk and availability needs; test that policy explicitly.
  • Cost: The research sources do not establish provider pricing, so check the provider’s current plan and billing documentation before estimating test cost. A controlled mock avoids calling the provider for tests that do not need to validate its integration. Keep any provider usage within your authorized test environment.

9. Or skip the browser setup

If the task is to capture a page rather than test your site’s CAPTCHA integration, ScreenshotNeo offers a website screenshot API and MCP server. A screenshot API does not solve CAPTCHA challenges or make an unauthorized third-party flow accessible. ScreenshotNeo reports bot checks, blank pages, timeouts, failed loads, and cache hits in response headers; those outcomes are not billed. It also removes known cookie/consent banners, newsletter popups, and chat widgets before capture. Each cleanup step can be turned off.

One GET request returns an image or PDF. This cURL example saves a WebP capture:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));

See the ScreenshotNeo API documentation for parameters and response details. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Plans include 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed; an MCP server lets AI agents take screenshots. Sign up for 1,000 free screenshots a month, with no card required.

10. Frequently asked questions

Can I use Google’s public v2 test keys in production?

No. Google’s FAQ says the test widget warns against production use. Keep test keys in non-production environments.

Does a v3 test score tell me whether production users will pass?

No. Google says test scores may not be accurate because v3 relies on real traffic. Use functional tests for integration behavior and evaluate production risk separately.

What should I do when an unfamiliar site presents a CAPTCHA?

Stop the automation and use the site’s supported access route or a human handoff. Do not attempt to defeat its access control without authorization.

Can ScreenshotNeo bypass a CAPTCHA?

No. It is a screenshot API and MCP server, not a CAPTCHA solver. Its response identifies outcomes such as bot checks, and those outcomes are not billed.