How can I solve captcha's during automated testing?

Last updated

A CAPTCHA exists to tell a human from a script, and your automated test is a script. There is no way to make a real CAPTCHA challenge pass reliably from an automated run, and you should not try to on a site you do not own: reCAPTCHA and hCaptcha both prohibit it, and third-party solving services exist mainly to serve abuse. The workable answer is to stop the challenge appearing at all in your test environment.

Use the official test keys

Both major providers publish key pairs that always pass and are meant for exactly this. Configure them in your staging or CI environment and the widget renders, your form still posts a token, and verification always succeeds.

Google publishes a test site key and secret for reCAPTCHA v2 that always returns a successful verification, documented on the reCAPTCHA FAQ page. hCaptcha publishes equivalent test credentials, including keys that always pass and keys that always fail, which is the more useful pair: the failing key lets you test your own error handling, which is the part of the flow that usually breaks.

The rule is the same for both. Test keys belong in test environments only. A production deployment that picks them up has no bot protection at all.

Turn the check off in test environments

If your application controls the CAPTCHA, the cleanest approach is a flag that skips verification when the environment is not production:

def captcha_verified?(response)
  return true if Rails.env.test?

  # real verification against the provider
end

This is what most teams end up doing, because it keeps the CAPTCHA out of every test rather than only the ones that submit the form. Guard it on the environment, never on a request parameter or header: a bypass that a caller can trigger is a bypass an attacker can trigger.

Allowlist your test traffic

Where the challenge has to stay in place, both providers let you reduce it for known traffic. reCAPTCHA v3 returns a score rather than a challenge, so a test run scores low but never faces a puzzle, and your own threshold decides what happens next. Lowering that threshold for a staging hostname keeps the integration real while letting tests through.

Test what surrounds the CAPTCHA, not the CAPTCHA

The widget is a third-party component that Google or hCaptcha already tests. What is worth your test coverage is your own code around it:

  • The form submits and the token reaches your backend.
  • Verification failure is handled: the user sees a usable error and the form does not lose its contents.
  • A missing or expired token is rejected server-side, not only in the browser.
  • The page still works with the widget blocked, which is what a privacy extension or a corporate proxy will do to some of your users.

What about solver services and stealth plugins?

Tools that solve challenges automatically, whether commercial solving APIs or browser plugins that hide automation, are built to defeat bot protection. Using them against a site you do not own generally breaks that site's terms and the CAPTCHA provider's terms, and it is not testing. On your own site they are the wrong tool as well: they add an unreliable third-party dependency to your pipeline for a problem a test key solves in one line of configuration.

If you are hitting CAPTCHAs on a site you do not control, that is the site telling you it does not want automated traffic. The route through it is permission, not tooling.

TestingBot runs your Selenium, Playwright and Puppeteer tests on real browsers and devices. Point your suite at a staging environment configured with test keys and the whole flow runs end to end, including the failure paths. See automated testing on TestingBot.

Other Questions