Passer au contenu principal

CI/CD

Écrit par Ines

Présentation

L'API CI de Thunders vous permet de mettre en file d'attente des exécutions de tests, d'interroger leur état et de récupérer des rapports structurés (JUnit XML ou JSON) — le tout via trois points de terminaison sous /api/ci/.

Points de terminaison API

POST  https://api.thunders.ai/api/ci/run 
GET https://api.thunders.ai/api/ci/run/{runId}
GET https://api.thunders.ai/api/ci/run/{runId}/report

Authentification

L'API nécessite une authentification par jeton Bearer :

Authorization: Bearer YOUR_THUNDER_TEST_TOKEN

Vous devez obtenir un jeton API valide depuis la plateforme Thunders. Ce jeton doit être stocké de manière sécurisée en tant que secret dans votre environnement ou votre dépôt GitHub.

En-têtes

En-tête

Valeur

Description

Authorization

Bearer YOUR_THUNDER_TEST_TOKEN

Jeton d'authentification

X-MS-API-ROLE

M2M

Indique un appel API machine-à-machine

Content-Type

application/json

Spécifie le format du corps de la requête

POST /api/ci/run — Mettre en file d'attente des tests

Met en file d'attente des exécutions de tests pour un ou plusieurs scénarios de test et/ou groupes de test. Toutes les exécutions sont regroupées sous un runId commun. Renvoie des URL permettant d'interroger l'état et de récupérer le rapport final.

Corps de la requête

Au moins un des paramètres testCaseIds ou testSetIds doit être fourni. Les deux peuvent être fournis dans la même requête.

{
"projectId": "c8e34ec4-2464-43c7-8db8-1b3a47a22337",
"testCaseIds": [
"a836fadc-377a-46fe-96b0-21f37c626bf9",
"61015c47-612f-47fa-82a6-41d910832c1b"
],
"testSetIds": [
"8eea2fd3-da6d-4434-a310-176be84c5646"
],
"environmentId": "eca24252-e566-40a8-b2b0-707b7efa85d8",
"personaId": "70d0ac52-fe94-4d89-aba9-8ef28dd8c04c",
"maxParallelism": 5,
"maxRetries": 1,
"browserSettings": {
"location": "Paris",
"resolution": "1440x900",
"deviceType": "Desktop"
}
}

Paramètre

Type

Obligatoire

Défaut

Description

projectId

string (UUID)

Oui

-

L'identifiant unique du projet.

testCaseIds

array (UUIDs)

Non*

-

Liste d'identifiants de scénarios de test à exécuter.

testSetIds

array (UUIDs)

Non*

-

Liste d'identifiants de groupes de test. Chaque groupe est étendu à ses scénarios de test.

environmentId

string (UUID)

Oui

-

L'environnement à utiliser.

personaId

string (UUID)

Oui

-

Le persona pour l'exécution des tests.

maxParallelism

int

Non

4

Nombre max de tests en parallèle. 0 = maximum.

maxRetries

int

Non

0

Tentatives de réessai pour les tests échoués (0-3).

testAssetReferences

array

Non

-

Références d'actifs de test pour l'exécution par lots.

browserSettings.location

string

Non

"Paris"

Cluster géographique : Paris, London, Amsterdam, SanFrancisco, NewYork.

browserSettings.browserType

string

Non

"Chromium"

Chromium, Chrome, Firefox ou Safari.

browserSettings.deviceType

string

Non

"Desktop"

Desktop, Mobile ou Tablet.

browserSettings.resolution

string

Non

"1280x720"

Résolution de la fenêtre (par ex. "1440x900").

browserSettings.javascript

boolean

Non

true

Activer/désactiver JavaScript.

browserSettings.highlightElements

boolean

Non

true

Mettre en surbrillance les éléments ciblés.

browserSettings.ignoreHttpsErrors

boolean

Non

false

Ignorer les erreurs HTTPS.

browserSettings.darkTheme

boolean

Non

false

Mode thème sombre.

browserSettings.avoidDetection

boolean

Non

false

Contournement de la détection de bot.

browserSettings.locale

string

Non

-

Locale du navigateur (par ex. "fr-FR").

browserSettings.proxy

string

Non

-

Configuration du serveur proxy.

browserSettings.headers

dictionary

Non

-

En-têtes HTTP personnalisés.

Réponse — 202 Accepted

{
"runId": "01966a3e-...",
"statusUrl": "/api/ci/run/01966a3e-...",
"reportUrl": "/api/ci/run/01966a3e-.../report"
}

Champ

Type

Description

runId

string (UUID)

Identifiant unique de l'exécution CI.

statusUrl

string

URL relative pour interroger l'état de l'exécution.

reportUrl

string

URL relative pour récupérer le rapport final.

GET /api/ci/run/{runId} — Interroger l'état d'exécution

Renvoie l'état agrégé de toutes les exécutions de tests. Interrogez jusqu'à ce que le status soit terminal (passed, failed, stopped, cancelled).

Réponse — 200 OK

{
"runId": "01966a3e-...",
"status": "running",
"testCount": 5,
"passedCount": 2,
"failedCount": 0,
"runningCount": 2,
"queuedCount": 1,
"startedAt": "2026-03-20T14:30:00Z",
"endedAt": null,
"durationMs": null
}

Champ

Type

Description

runId

string (UUID)

L'identifiant de l'exécution CI.

status

string

queued, running, stopping, stopped, cancelled, failed, passed.

testCount

int

Nombre total d'exécutions de tests.

passedCount

int

Tests réussis.

failedCount

int

Tests échoués.

runningCount

int

Tests en cours d'exécution.

queuedCount

int

Tests en file d'attente.

startedAt

datetime?

Date de début du premier test.

endedAt

datetime?

Date de fin du dernier test.

durationMs

long?

Durée totale en millisecondes.

GET /api/ci/run/{runId}/report — Récupérer le rapport

Renvoie le rapport d'exécution des tests. Le format dépend de l'en-tête Accept :

  • Par défaut (ou application/xml) : JUnit XML — compatible avec Jenkins, GitHub Actions (dorny/test-reporter), GitLab, etc.

  • Accept: application/json : Rapport JSON avec données structurées.

Exemple de réponse JSON

{
"tests": 3,
"failures": 1,
"skipped": 0,
"time": 45.2,
"testSuites": [
{
"name": "Mon Groupe de Test",
"tests": 2,
"failures": 1,
"skipped": 0,
"time": 30.1,
"timestamp": "2026-03-20T14:30:00Z",
"testCases": [
{
"name": "Flux de connexion",
"className": "Mon Groupe de Test",
"time": 15.0,
"status": "passed",
"failure": null
},
{
"name": "Flux de paiement",
"className": "Mon Groupe de Test",
"time": 15.1,
"status": "failed",
"failure": {
"message": "Élément introuvable",
"type": "AssertionFailure",
"body": "Étape 3 : Cliquer sur Ajouter au panier — élément introuvable."
}
}
]
}
]
}

Champ

Type

Description

tests

int

Nombre total de cas de test dans toutes les suites.

failures

int

Nombre total de cas de test échoués.

skipped

int

Nombre total de cas de test ignorés.

time

double

Durée totale d'exécution en secondes.

testSuites

array

Liste des rapports de suites de tests.

testSuites[].testCases[].failure

object?

message, type, body. null si le test est réussi.

Gestion des erreurs

L'API utilise les codes d'état HTTP standard :

  • 202 Accepted : POST /api/ci/run — les tests ont été mis en file d'attente avec succès

  • 200 OK : Points de terminaison GET — la requête a abouti

  • 400 Bad Request : Requête mal formée ou paramètres obligatoires manquants

  • 401 Unauthorized : Échec de l'authentification ou jeton invalide

  • 403 Forbidden : Permissions insuffisantes

  • 404 Not Found : Aucune exécution trouvée pour le runId donné

  • 500 Internal Server Error : Erreur inattendue du serveur

Utilisation avec GitHub Actions

Intégrez l'API CI de Thunders à vos workflows GitHub Actions pour automatiser l'exécution des tests dans votre pipeline CI/CD.

Exemple de workflow GitHub Action

name: Run Thunders Tests

on:
workflow_dispatch:

permissions:
contents: read
checks: write

jobs:
run-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Queue Thunders CI Run
id: trigger
run: |
set -euo pipefail
TMPFILE=$(mktemp)
curl --no-buffer -s -X POST https://api.thunders.ai/api/ci/run \
-H "Authorization: Bearer $\{{ secrets.THUNDER_TEST_TOKEN }}" \
-H "X-MS-API-ROLE: M2M" \
-H "Content-Type: application/json" \
-d '{
"projectId": "YOUR_PROJECT_ID",
"testSetIds": ["YOUR_TEST_SET_ID"],
"environmentId": "YOUR_ENVIRONMENT_ID",
"personaId": "YOUR_PERSONA_ID",
"maxParallelism": 5,
"maxRetries": 1,
"browserSettings": {
"location": "Paris",
"resolution": "1920x1080",
"deviceType": "Desktop"
}
}' \
-w '\n%{http_code}' 2>&1 | tee "$TMPFILE"
HTTP_CODE=$(tail -1 "$TMPFILE")
BODY=$(head -n -1 "$TMPFILE")
if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
echo "Failed (HTTP $HTTP_CODE): $BODY"; exit 1
fi
echo "status_url=$(echo $BODY | jq -r '.statusUrl')" >> $GITHUB_OUTPUT
echo "report_url=$(echo $BODY | jq -r '.reportUrl')" >> $GITHUB_OUTPUT

- name: Wait for completion
id: run-tests
run: |
set -euo pipefail
MAX_WAIT=5400; INTERVAL=30; ELAPSED=0
while [ $ELAPSED -lt $MAX_WAIT ]; do
RESP=$(curl -sS --fail-with-body \
"https://api.thunders.ai$\{{ steps.trigger.outputs.status_url }}" \
-H "Authorization: Bearer $\{{ secrets.THUNDER_TEST_TOKEN }}" \
-H "X-MS-API-ROLE: M2M")
STATUS=$(echo "$RESP" | jq -r '.status')
echo "[$ELAPSED s] status=$STATUS"
case "$STATUS" in
passed|failed|stopped|cancelled)
echo "final_status=$STATUS" >> $GITHUB_OUTPUT; break;;
esac
sleep $INTERVAL; ELAPSED=$((ELAPSED+INTERVAL))
done
[ $ELAPSED -ge $MAX_WAIT ] && echo "Timed out" && exit 1

- name: Download JUnit report
if: always() && steps.run-tests.conclusion == 'success'
run: |
curl -sS --fail-with-body \
"https://api.thunders.ai$\{{ steps.trigger.outputs.report_url }}" \
-H "Authorization: Bearer $\{{ secrets.THUNDER_TEST_TOKEN }}" \
-H "X-MS-API-ROLE: M2M" \
-o test-results.xml

- name: Publish test results
uses: dorny/test-reporter@v1
if: always() && steps.run-tests.conclusion == 'success'
continue-on-error: true
with:
name: Thunders CI Results
path: test-results.xml
reporter: java-junit

- name: Fail if tests did not pass
if: steps.run-tests.outputs.final_status != 'passed'
run: exit 1

Configuration des secrets GitHub

  1. Accédez à votre dépôt GitHub

  2. Accédez à Paramètres > Secrets et variables > Actions

  3. Cliquez sur « Nouveau secret de dépôt »

  4. Nom : THUNDER_TEST_TOKEN

  5. Valeur : votre jeton API Thunders

  6. Cliquez sur « Ajouter un secret »

Personnalisation du workflow

Vous pouvez personnaliser le workflow en :

  1. Modifiant les événements déclencheurs (par ex., sur push, sur planification)

  2. Modifiant les paramètres de test (projectId, testCaseIds, testSetIds, environmentId, personaId)

  3. Ajustant l'intervalle d'interrogation (INTERVAL) et le délai d'attente (MAX_WAIT)

  4. Ajoutant des étapes supplémentaires pour traiter les résultats des tests

Lot d'actifs de test

La fonctionnalité Lot d'actifs de test vous permet d'exécuter plusieurs fois le même scénario de test avec différentes variations de données en téléchargeant des fichiers CSV en tant que ressources de test. Chaque ligne du fichier CSV devient un test distinct, ce qui permet d'effectuer des tests basés sur les données à grande échelle.

Comment ça marche

  1. Téléchargez des fichiers CSV en tant qu'actifs de test dans votre projet (via l'application web Thunders ou l'API)

  2. Référencez les fichiers CSV dans votre requête API à l'aide du paramètre testAssetReferences

  3. Chaque ligne CSV génère un test distinct avec ses propres remplacements de variables et paramètres de navigateur

  4. Tous les tests d'un même lot sont regroupés sous un batchId commun

Le paramètre testAssetReferences

Ajoutez le champ testAssetReferences au corps de votre requête :

{
"projectId": "your-project-id",
"testCaseIds": ["your-test-case-id"],
"environmentId": "your-environment-id",
"personaId": "your-persona-id",
"testAssetReferences": ["FILE_MYDATA_CSV", "FILE_USERS_CSV"]
}

Format de référence : lorsque vous téléchargez un fichier nommé mydata.csv, sa référence devient FILE_MYDATA_CSV. La convention de nommage est FILE__, où le nom du fichier est en majuscules et les caractères spéciaux sont remplacés par des traits de soulignement.

Les références peuvent également être placées entre crochets : [FILE_MYDATA_CSV].

Pour en savoir plus sur la fonctionnalité de traitement par lots, consultez cette documentation

Combinaison de plusieurs fichiers CSV

Vous pouvez passer plusieurs références CSV dans le tableau testAssetReferences. Les lignes de tous les fichiers sont fusionnées séquentiellement en un seul lot avec un indexage continu.

"testAssetReferences": ["FILE_BROWSERS_CSV", "FILE_MOBILE_CSV"]

Si browsers.csv comporte 3 lignes et mobile.csv 2 lignes, le lot contiendra au total 5 exécutions indexées de 1 à 5.

Avez-vous trouvé la réponse à votre question ?