Tutorials

État de session pour des workers QA distribués avec CaptchaAI

Pour que des workers QA distribués produisent des résultats CAPTCHA comparables, chacun doit partir du même état de session documenté — pas d'un « contexte live » commun, mais d'un instantané rattaché à une exécution de test précise. Sinon, un écart peut venir aussi bien de l'application testée que d'un cookie resté en mémoire.

Périmètre : ce guide s'applique à vos propres environnements QA ou explicitement autorisés. Il décrit comment des workers de test distribués coordonnent un état reproductible — jamais de reprise de session sur des sites tiers ni d'accès non autorisés.


Pourquoi l'état de session fait dérailler les tests CAPTCHA distribués

Des workers de test distribués rejouent souvent la même fonctionnalité sous des conditions volontairement différentes :

  • première visite d'un compte de test,
  • session active avec un feature flag activé,
  • session expirée jouée comme test négatif,
  • régression parallèle sur plusieurs rôles utilisateur.

Sans état coordonné, ces workers ne comparent pas les mêmes scénarios : on voit des erreurs CAPTCHA difficiles à interpréter, alors que la cause réelle est un point de départ divergent.


Ce qui se partage entre workers, et ce qui ne se partage jamais

En QA, seules les données qui servent la reproductibilité d'un cas de test circulent entre workers.

Type d'état Partageable ? Note
Identifiant d'exécution de test Oui Relie logs, captures et backend
Métadonnées de compte de test Oui Rôle, tenant, feature flags
Snapshot de cookies staging Oui, si prévu par le cas de test Documenter et versionner avant
Snapshot de stockage local Oui, si prévu par le cas de test Pour des états d'interface stables
Journal d'une vérification CAPTCHA Oui Diagnostic et rapports
Données d'utilisateurs réels Non Jamais dans un artefact QA

Note RGPD : vos snapshots ne doivent contenir que des comptes de test et des données synthétiques, jamais de données personnelles réelles.


Documenter un état de session dans Redis

On ne partage pas un navigateur vivant, mais un instantané sérialisé : cookies et stockage local, sous une clé combinant l'identifiant d'exécution et celui du worker.

from __future__ import annotations

import json
import redis


r = redis.Redis(host="localhost", port=6379, decode_responses=True)


def session_key(test_run_id: str, worker_id: str) -> str:
    return f"qa:session:{test_run_id}:{worker_id}"


def save_session_snapshot(*, test_run_id: str, worker_id: str, cookies: dict, storage: dict) -> None:
    payload = {
        "test_run_id": test_run_id,
        "worker_id": worker_id,
        "cookies": cookies,
        "storage": storage,
    }
    r.set(session_key(test_run_id, worker_id), json.dumps(payload), ex=3600)


def load_session_snapshot(test_run_id: str, worker_id: str) -> dict:
    raw = r.get(session_key(test_run_id, worker_id))
    if not raw:
        return {"cookies": {}, "storage": {}}
    return json.loads(raw)

L'important n'est pas Redis, mais la structure : chaque worker reçoit des données rattachées à une exécution QA connue. Le ex=3600 évite qu'un ancien snapshot ne pollue l'exécution suivante — voir la gestion du TTL des tokens dans Redis.


Lancer une vérification CAPTCHA par worker

Une fois l'état de départ et l'identifiant d'exécution figés, chaque worker suit le même chemin : la résolution passe par l'API CaptchaAI, puis le token est corrélé à l'exécution en cours.

import requests
import time


API_KEY = "YOUR_API_KEY"


def solve_for_worker(page_url: str, sitekey: str) -> str:
    submit = requests.post(
        "https://ocr.captchaai.com/in.php",
        data={
            "key": API_KEY,
            "method": "userrecaptcha",
            "googlekey": sitekey,
            "pageurl": page_url,
            "json": 1,
        },
        timeout=30,
    )
    submit.raise_for_status()
    submit_json = submit.json()
    if submit_json.get("status") != 1:
        raise RuntimeError(submit_json.get("request", "submit failed"))

    task_id = submit_json["request"]
    for _ in range(30):
        time.sleep(5)
        result = requests.get(
            "https://ocr.captchaai.com/res.php",
            params={"key": API_KEY, "action": "get", "id": task_id, "json": 1},
            timeout=30,
        )
        result.raise_for_status()
        result_json = result.json()
        if result_json.get("status") == 1:
            return result_json["request"]

    raise TimeoutError("CaptchaAI result timed out for QA worker")

Ici userrecaptcha cible reCAPTCHA v2/v3. Côté déploiement, un pool de workers sur OVHcloud ou Scaleway, ou des fonctions serverless en région eu-west-3 (Paris), conviennent bien. La vérification reste une étape QA contre votre environnement, corrélée à l'exécution et au worker.


Vérifier la réponse backend de chaque worker

Le token ne suffit pas : votre backend de staging doit l'accepter. Chaque worker renvoie donc son résultat avec son test_run_id.

def verify_worker_run(*, test_run_id: str, worker_id: str, token: str) -> dict:
    response = requests.post(
        "https://staging.example-app.test/qa/captcha/verify",
        json={
            "testRunId": test_run_id,
            "workerId": worker_id,
            "token": token,
            "environment": "staging",
        },
        timeout=30,
    )
    response.raise_for_status()
    return response.json()

Vous savez alors, par worker, quel état de départ était actif et si un écart entre exécutions parallèles vient de l'état de session ou de l'application.


Dépannage

Problème Cause Solution
Deux workers donnent des résultats différents États de session de départ différents Documenter explicitement les snapshots de départ par worker
Les résultats ne se corrèlent pas Identifiant d'exécution manquant Utiliser le même test_run_id côté navigateur, backend et Redis
Un worker démarre avec un état vide Snapshot non chargé Vérifier la lecture Redis avant le test
Le backend n'accepte que des exécutions isolées Données de test qui se chevauchent Utiliser des comptes et des identifiants de worker uniques
Les erreurs n'apparaissent qu'en parallèle Fixtures partagées modifiées Garder les fixtures en lecture seule ou les cloner par worker

Questions fréquentes

Comment éviter que deux exécutions QA parallèles se mélangent ?

Faites du test_run_id la racine de toutes vos clés Redis et de vos logs : deux campagnes simultanées travaillent alors sur des espaces de clés disjoints.

Peut-on stocker de vraies données utilisateurs dans les artefacts QA ?

Non. Les snapshots ne contiennent que des comptes de test et des données synthétiques — reproductibilité et bonne pratique RGPD à la fois.

Quels types de CAPTCHA CaptchaAI peut-il vérifier dans ces workers ?

reCAPTCHA v2 et v3, Cloudflare Turnstile et Challenge, GeeTest v3, l'image/OCR, la grille et BLS ; CaptchaFox, Friendly Captcha et Lemin en bêta. hCaptcha, FunCaptcha et GeeTest v4 ne sont pas pris en charge.


Guides connexes sûrs

Coordonnez vos workers QA avec un état de session clair et des vérifications reproductibles — CaptchaAI accompagne des tests CAPTCHA fiables dans vos environnements.

Les commentaires sont désactivés pour cet article.