Integrationen

Puppeteer + CaptchaAI für QA-Tests in eigenen Browser-Workflows

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

Machen Sie Ihre Browser-Tests mit klaren QA-Metriken und reproduzierbaren Staging-Läufen nachvollziehbar – CaptchaAI unterstützt die CAPTCHA-Validierung in eigenen Workflows.

Kommentare sind für diesen Artikel deaktiviert.