Ein CAPTCHA-Widget auf einer geschützten Staging-Seite bringt jeden automatisierten QA-Lauf zum Stillstand: Das Formular lässt sich nicht absenden, der Test bricht ab, und eine Regression bleibt womöglich unbemerkt. Puppeteer zusammen mit CaptchaAI schließt genau diese Lücke – Sie erkennen das Widget, fordern ein Token über die API an und verifizieren das Ergebnis gegen Ihren eigenen QA-Endpoint. Dieser Leitfaden zeigt den vollständigen Pfad für reCAPTCHA v2, reCAPTCHA v3 und Cloudflare Turnstile in eigenen oder autorisierten Testumgebungen.
Anwendungsbereich: Dieser Leitfaden richtet sich an Browser-basierte Tests in eigenen oder autorisierten QA- und Staging-Umgebungen. Er behandelt die Widget-Erkennung, die Prüfung von Verifikationspfaden und die Dokumentation von Testläufen – nicht das Umgehen fremder Schutzmechanismen, keine unautorisierten Logins und keine verdeckte Browsersteuerung.
Wann Puppeteer für CAPTCHA-QA die richtige Wahl ist
Puppeteer spielt seine Stärken in der QA immer dann aus, wenn Sie Browserzustand, Timing und DOM-Verhalten präzise beobachten müssen. Der Headless-Browser liefert reproduzierbare Läufe, und jede Interaktion – vom Laden des Widgets bis zur Formularantwort – lässt sich protokollieren. Für einen publish-tauglichen Workflow sollte sich Puppeteer dabei auf Aufgaben beschränken, die Sie in eigenen Umgebungen kontrollieren:
- ein CAPTCHA-Widget auf einer Staging-Seite erkennen
- Lade-, Fehler- und Timeout-Zustände dokumentieren
- CaptchaAI in eine bestehende Test-Suite integrieren
- die Antwort eines eigenen Prüf-Endpoints verifizieren
- Regressionen nach einem Deployment reproduzierbar nachstellen
So entsteht Mehrwert durch Transparenz und Teststabilität – nicht durch verdeckte Steuerung fremder Seiten.
Puppeteer für den QA-Lauf einrichten
Für QA genügt ein bewusst schlichtes Setup. Installieren Sie Puppeteer als Abhängigkeit Ihres Testprojekts:
npm install puppeteer
Eine kleine Hilfsfunktion öffnet die Staging-Seite und wartet, bis das Netzwerk zur Ruhe gekommen ist:
import puppeteer from "puppeteer";
async function openQaPage(url) {
const browser = await puppeteer.launch({ headless: "new" });
const page = await browser.newPage();
await page.goto(url, { waitUntil: "networkidle2" });
return { browser, page };
}
Wichtiger als Spezialflags ist Reproduzierbarkeit: dieselbe Staging-URL, dieselben Testdaten und dieselben Assertions bei jedem Lauf. Genau diese Konstanz macht eine Abweichung später eindeutig einem Deployment oder einer Konfigurationsänderung zuordenbar.
CAPTCHA-Widget auf der Staging-Seite bestimmen
Der erste Schritt jedes Testlaufs ist die Diagnose: Welcher CAPTCHA-Typ ist aktiv, welcher Sitekey wurde geladen, und in welchem Formularschritt erscheint das Widget? Die folgende Funktion unterscheidet reCAPTCHA v2 und Cloudflare Turnstile und liest den zugehörigen Sitekey direkt aus dem DOM:
async function detectCaptchaWidget(page) {
return page.evaluate(() => {
const recaptcha = document.querySelector(".g-recaptcha[data-sitekey]");
if (recaptcha) {
return {
kind: "recaptcha_v2",
sitekey: recaptcha.getAttribute("data-sitekey"),
step: recaptcha.closest("form")?.getAttribute("data-step") || "unknown",
};
}
const turnstile = document.querySelector(".cf-turnstile[data-sitekey]");
if (turnstile) {
return {
kind: "turnstile",
sitekey: turnstile.getAttribute("data-sitekey"),
step: turnstile.closest("form")?.getAttribute("data-step") || "unknown",
};
}
return null;
});
}
Archivieren Sie zusätzlich Screenshots, Konsolenlogs und Netzwerkmetadaten, wird derselbe Lauf später deutlich leichter nachvollziehbar. Gerade bei Regressionen ist ein festgehaltener Ausgangszustand Gold wert.
Token über CaptchaAI anfordern
Steht der Widget-Zustand fest, erzeugt der QA-Lauf eine CaptchaAI-Aufgabe und fragt das Ergebnis per Polling ab. CaptchaAI verarbeitet dabei reCAPTCHA v2, reCAPTCHA v3 und Cloudflare Turnstile über dieselbe in.php/res.php-Schnittstelle:
async function solveWithCaptchaAi(apiKey, widget, pageUrl) {
const body = new URLSearchParams({
key: apiKey,
method: widget.kind === "turnstile" ? "turnstile" : "userrecaptcha",
pageurl: pageUrl,
json: "1",
});
if (widget.kind === "turnstile") {
body.set("sitekey", widget.sitekey);
} else {
body.set("googlekey", widget.sitekey);
}
const submit = await fetch("https://ocr.captchaai.com/in.php", {
method: "POST",
body,
});
const submitJson = await submit.json();
if (submitJson.status !== 1) {
throw new Error(`CaptchaAI submit failed: ${submitJson.request}`);
}
for (let attempt = 0; attempt < 30; attempt += 1) {
await new Promise((resolve) => setTimeout(resolve, 5000));
const poll = await fetch(
`https://ocr.captchaai.com/res.php?key=${apiKey}&action=get&id=${submitJson.request}&json=1`
);
const pollJson = await poll.json();
if (pollJson.status === 1) {
return pollJson.request;
}
}
throw new Error("CaptchaAI polling timed out during QA test");
}
Das zurückgegebene Token ist im QA-Kontext ein Diagnoseartefakt: Es wird geloggt, gegen die eigene Umgebung geprüft und mit dem jeweiligen Testlauf verknüpft. Beachten Sie, dass ein Token nur rund 120 Sekunden gültig ist – fordern Sie es deshalb unmittelbar vor dem Verifikationsschritt an, nicht auf Vorrat.
Den eigenen QA-Endpoint verifizieren
Ein sauberer Testlauf endet nicht beim CAPTCHA-Ergebnis, sondern bei Ihrer eigenen Verifikation. Senden Sie das Token an einen dedizierten Staging-Endpoint, der die erwarteten Felder prüft:
async function verifyQaRun(token, widget, testRunId) {
const response = await fetch("https://staging.example-app.test/qa/captcha/verify", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
token,
widgetType: widget.kind,
sitekey: widget.sitekey,
expectedStep: widget.step,
testRunId,
}),
});
if (!response.ok) {
throw new Error(`QA verification returned ${response.status}`);
}
return response.json();
}
Sinnvolle Assertions in der Test-Suite sind zum Beispiel:
- der erwartete Widget-Typ wurde erkannt
- der Staging-Sitekey stimmt mit der Deployment-Konfiguration überein
- der QA-Endpoint bestätigt den erwarteten Formularschritt
- die Antwortzeit bleibt innerhalb Ihres internen Budgets
In die CI-Pipeline einbinden
Seinen vollen Wert entfaltet der Workflow erst in der CI-Pipeline. Der Headless-Browser läuft in GitLab CI – in vielen DACH-Teams die erste Wahl – ebenso wie in GitHub Actions ohne zusätzliche Anzeige. Ein paar Punkte haben sich in der Praxis bewährt:
- den API-Schlüssel als maskiertes CI-Secret hinterlegen, nie im Repository
- pro Merge-Request nur die betroffenen CAPTCHA-Strecken testen, um Threads zu schonen
- Screenshots und Logs als Build-Artefakte aufbewahren
- Läufe mit personenbezogenen Daten auf Staging-Testdaten beschränken (IP-Adressen zählen laut DSGVO dazu) und die Rechtsgrundlage der eigenen Testdaten prüfen
Der letzte Punkt ist keine Formalie: Wer in Deutschland oder Österreich mit realistischen Testdaten arbeitet, sollte deren Herkunft und Verarbeitung sauber dokumentieren – das erspart später Rückfragen aus Datenschutz und Compliance.
Threads für parallele QA-Läufe
CaptchaAI rechnet Thread-basiert ab: Ein Thread entspricht einer gleichzeitig laufenden CAPTCHA-Aufgabe, die Zahl der Lösungen pro Monat ist nicht gedeckelt. Für QA-Zwecke reicht meist der Einstiegstarif BASIC (15 $/Monat, 5 Threads); wenn Sie mehr Teststrecken gleichzeitig parallelisieren, schafft STANDARD (30 $/Monat, 15 Threads) Luft. Da nicht pro Lösung abgerechnet wird, verteuert ein zusätzlicher Testlauf innerhalb eines Tarifs nichts – begrenzend wirkt allein die Zahl der parallelen Threads. Die Preise sind in US-Dollar ausgewiesen; die aktuelle Übersicht steht auf der Preisseite von CaptchaAI.
Logging und Fehlerdiagnose
| Problem | Ursache | Lösung |
|---|---|---|
| Widget wird nicht erkannt | DOM-Selektor veraltet | Selektoren gegen die aktuelle Staging-Seite prüfen |
| Falscher Sitekey in QA | Konfigurationsdrift | Environment-Variablen und Frontend-Config vergleichen |
| CaptchaAI-Aufgabe läuft in Timeout | Testlast oder Queue-Spitze | Polling-Timeout und Parallelität dokumentiert anpassen |
| QA-Verify-Endpoint liefert 422 | Erwartete Felder fehlen | Request-Schema mit dem Backend-Team abgleichen |
| Ergebnisse schwer reproduzierbar | Testdaten wechseln zwischen Läufen | feste Testkonten und feste Staging-Fixtures verwenden |
Häufige Fragen
Welche CAPTCHA-Typen deckt dieser QA-Workflow ab?
reCAPTCHA v2, reCAPTCHA v3 und Cloudflare Turnstile. Die Widget-Erkennung liest den jeweiligen Sitekey aus dem DOM und wählt automatisch die passende API-Methode (userrecaptcha oder turnstile).
Wie viele Threads brauche ich für parallele QA-Läufe?
Einen Thread pro gleichzeitig laufender CAPTCHA-Aufgabe. Für einzelne Teststrecken genügt BASIC (15 $/Monat, 5 Threads); starten mehrere Suites parallel, planen Sie entsprechend mehr Threads ein.
Wie lange ist ein CAPTCHA-Token gültig?
Rund 120 Sekunden. Fordern Sie das Token daher erst unmittelbar vor dem Verifikationsschritt an und übermitteln Sie es sofort – ein vorab erzeugtes Token ist beim Absenden oft schon abgelaufen.
Lässt sich der Workflow in GitLab CI oder GitHub Actions ausführen?
Ja. Der Headless-Browser läuft ohne Anzeige, der API-Schlüssel kommt als maskiertes CI-Secret, und Screenshots wie Logs bleiben als Build-Artefakte erhalten.
Ersetzt CaptchaAI meine eigene QA-Verifikation?
Nein. Das Token ist ein Diagnoseartefakt; die maßgebliche Prüfung bleibt Ihr eigener Staging-Endpoint mit den Assertions Ihrer Test-Suite.
Sichere verwandte Leitfäden
- CaptchaAI in wenigen Minuten einrichten
- CAPTCHA-QA in autorisierten Testumgebungen
- Fehlerbild: API funktioniert, Browserlauf nicht
- CAPTCHA-Endpoints in eigenen Webformularen testen
Machen Sie Ihre Browser-Tests mit klaren QA-Metriken und reproduzierbaren Staging-Läufen nachvollziehbar – CaptchaAI unterstützt die CAPTCHA-Validierung in eigenen Workflows.