Qu'est-ce qu'une étape JavaScript ?
Une étape JavaScript vous permet d'exécuter votre propre code JavaScript à un moment précis d'un test. Utilisez-la lorsqu'une étape en langage naturel ou une étape Web ne permet pas d'exprimer ce dont vous avez besoin : lire une valeur calculée, combiner deux lectures du DOM, appeler une API pour vérifier l'état du backend ou générer des données de test dynamiques.
Vous écrivez le corps d’une fonction Step(). Celle-ci vous fournit un contexte prêt à l’emploi (vos variables, la page, un client API, la console, le réseau et les étapes précédentes), et vous renvoyez un résultat : l’étape réussit ou échoue.
Quand l’utiliser
Capturer une valeur : lire une valeur sur la page (ou en calculer une) et la stocker dans une variable pour les étapes suivantes.
Valider l’état du backend : appeler une API interne ou externe en cours de test et comparer le résultat à ce qu’affiche l’interface utilisateur.
Vérifier le trafic réseau : s’assurer que la page a envoyé la bonne requête avec la bonne charge utile.
Générer des données dynamiques : générer des dates, des références ou des valeurs composites afin que les tests ne reposent pas sur des données codées en dur.
Débloquer la page : fermer une bannière de cookies ou définir une valeur
dans localStoragedont dépend une étape ultérieure.
Quand utiliser une étape dédiée à la place
Pour les actions courantes, les étapes pré-conçues sont plus simples. Optez pour une étape JavaScript lorsque vous avez besoin d’une véritable logique.
Si vous souhaitez… | Préférez |
Cliquer, taper, sélectionner, survoler, attendre un élément | Une étape en langage naturel ou uneétape Web |
Appeler une API et vérifier sa réponse en tant qu’étape à part entière | Une étape d’appel d’API |
Dériver ou arrêter l'exécution en fonction d'une condition simple | Une étape conditionnelle (IF) |
Exécuter une logique personnalisée qu'aucune des étapes ci-dessus ne permet d'exprimer | Une étape JavaScript |
Comment ajouter une étape JavaScript
Ouvrez votre scénario de test.
Cliquez sur « Ajouter une nouvelle étape ».
Dans le champ « Type d’étape », sélectionnez « Étape JavaScript ».
Ajoutez une description: un résumé concis et compréhensible par l'utilisateur expliquant ce que fait l'étape. Ce champ est obligatoire et permet d'identifier l'étape dans la vue d'exécution.
Écrivez votre code dans l'éditeur.
La fonction Step()
L'éditeur s'ouvre avec un squelette. Vous écrivez le corps de la fonction ; la signature et l'accolade de fermeture restent en place.
function Step(response, variables, DOM, api_client, console, network, test_steps) {
// Write your logic here.
return response.Success();
}Chaque étape renvoie un résultat: response.Success() en cas de réussite, ou response.Fail('motif') en cas d'échec.
Les objets de contexte
Votre fonction Step() reçoit sept objets. Ils sont prêts à l'emploi, sans qu'il soit nécessaire de les importer ou de les configurer.
Objet | Ce qu’il vous apporte |
| Le générateur de résultat. Renvoyez |
| Lire et écrire les variables Thunders. |
|
|
| Un client HTTP permettant d'appeler des API depuis l'étape. Voir Appel d'API. |
|
|
| Une vue en lecture seule des requêtes effectuées par la page. |
| Une liste en lecture seule des étapes déjà exécutées. Chacune comporte |
Méthodes de réponse
Renvoyez exactement l’une de ces méthodes.
Méthode | Comportement |
| L'étape est réussie et l'exécution passe à l'étape suivante. |
| Réussit et associe |
| L'étape échoue. La chaîne de caractères indiquant la raison s'affiche dans le récapitulatif de l'exécution, et celle-ci s'arrête (comme pour les autres échecs d'étape). |
Utilisation des variables
Il existe deux façons d’utiliser les variables, qui se complètent :
Interpolation avec
[VARIABLE]: Thunders remplace tout token[MY_VAR]dans votre code par la valeur de la variable avant l'exécution du script, comme dans les autres étapes.L’objet
variables:variables['MY_VAR']lit la valeur actuelle au moment de l’exécution, et une affectation (variables['MY_VAR'] = 'nouvelle valeur') met à jour la variable pour le reste du test.
Appel d’API avec api_client
api_client vous permet d’appeler une API depuis l’étape et de vérifier le résultat, par exemple pour confirmer que le backend correspond bien à ce qu’affiche l’interface utilisateur.
Méthode | Description |
| Envoie une requête GET. |
| Envoie une requête POST avec un |
| Envoie une requête PUT avec un |
| Envoie une requête PATCH avec un |
| Envoie une requête DELETE. |
Chaque appel est asynchrone, il faut donc l'attendre. Transmettez des en-têtes personnalisés via opts, par exemple { headers: { 'X-Env': 'staging' } }. Chaque appel vous renvoie une réponse que vous pouvez lire :
{
status, // HTTP status code, e.g. 200
ok, // true when status is 2xx
data, // the parsed response body
headers // response headers
}function Step(response, variables, DOM, api_client, console, network, test_steps) {
const res = await api_client.get(`/api/carts/${variables['CART_ID']}`);
if (!res.ok) {
return response.Fail(`Cart lookup failed with status ${res.status}`);
}
return response.Success(res.data);
}Lecture des requêtes réseau
network.requests est une liste en lecture seule des requêtes effectuées par la page pendant l’exécution de l’étape, chacune contenant { url, method, status, headers, body } (les corps JSON sont analysés pour vous). Utilisez-la pour confirmer qu’une requête a bien été envoyée, vérifier un code d’état ou lire le contenu d’une réponse.
function Step(response, variables, DOM, api_client, console, network, test_steps) {
const analytics = network.requests.find(r => r.url.includes('/analytics/event'));
if (!analytics) {
return response.Fail('No analytics event was fired');
}
if (analytics.body.event_name !== 'checkout_completed') {
return response.Fail(`Wrong event name: ${analytics.body.event_name}`);
}
return response.Success();
}Boucles et attente
Votre code s'exécute comme une fonction asynchrone : await fonctionne partout dans le corps de la fonction, et les structures de contrôle JavaScript habituelles, for, while, try/catch, se comportent comme prévu. Le squelette affiche function Step(...) pour plus de lisibilité, mais l'exécution est bien asynchrone.
Cela rend possibles deux usages courants.
Répéter une action plusieurs fois :
function Step(response, variables, DOM, api_client, console, network, test_steps) {
for (let i = 1; i <= 10; i++) {
DOM.querySelector('#add-item').click();
await new Promise(r => setTimeout(r, 100));
}
return response.Success();
}Attendre qu'une condition soit remplie (polling) :
function Step(response, variables, DOM, api_client, console, network, test_steps) {
let rows = 0;
for (let i = 0; i < 10; i++) {
rows = DOM.querySelectorAll('.result-row').length;
if (rows >= 5) break;
await new Promise(r => setTimeout(r, 500));
}
console.log('rows found:', rows);
if (rows < 5) return response.Fail(`Only ${rows} rows after 5 seconds`);
return response.Success({ rows });
}
Une boucle répète du travail à l'intérieur d'une seule étape. Répéter des étapes Thunders elles-mêmes — réexécuter les étapes 3 à 7 jusqu'à ce qu'une condition soit remplie — n'est pas possible aujourd'hui. Une étape conditionnelle peut sauter vers une étape ultérieure ou arrêter l'exécution, mais elle ne peut pas revenir en arrière.
Bon à savoir
Limite de 90 secondes : Une étape JavaScript est interrompue au bout de 90 secondes et signalée comme un dépassement de délai : gardez le temps d'attente total d'une boucle bien en dessous de cette limite.
Renvoyez toujours une réponse : Une étape qui se termine sans renvoyer
response.Success()ouresponse.Fail('motif')est signalée comme un échec.Les variables secrètes ne sont pas exposées : Les variables marquées comme secrètes ne peuvent pas être lues via
variables[...], et leurs valeurs sont masquées dans le script comme dans la sortie console affichée dans la vue d'exécution.Ni
importni paquets npm :Il n'y a pas de système de modules dans l'étape. Vous disposez de tout l'environnement du navigateur (fetch,JSON,Date,localStorage, etc.) ainsi que des bibliothèques que votre propre application charge déjà sur la page.Les URL relatives dans
api_clientsont résolues par rapport à l'origine de la page courante :/api/carts/123fonctionne. Les URL absolues sont utilisées telles quelles.Les itérations d'une boucle ne sont pas détaillées : L'étape entière constitue un seul succès ou échec dans la vue d'exécution ; utilisez
console.logpour voir ce qui s'y est passé.
Exemples
1. Capturer une valeur de la page dans une variable
function Step(response, variables, DOM, api_client, console, network, test_steps) {
const orderId = DOM.querySelector('[data-order-id]').textContent;
variables['ORDER_ID'] = orderId;
return response.Success();
}Après avoir validé une commande, l’ID de commande s’affiche sur la page de confirmation. Enregistrez-le afin que les étapes suivantes puissent accéder à /orders/[ORDER_ID] ou appeler une API avec cette valeur.
2. Valider l’interface utilisateur par rapport au backend
function Step(response, variables, DOM, api_client, console, network, test_steps) {
const uiTotal = parseFloat(DOM.querySelector('.cart-total').textContent.replace('$', ''));
const res = await api_client.get(`/api/carts/${variables['CART_ID']}`);
if (res.data.total !== uiTotal) {
return response.Fail(`Cart mismatch: UI ${uiTotal}, API ${res.data.total}`);
}
return response.Success();
}Détecte les bogues d’intégrité des données que les tests d’interface utilisateur purs ne repèrent pas. La page s’affiche correctement, mais le backend ne valide pas les données.
3. Créer des données de test dynamiques
function Step(response, variables, DOM, api_client, console, network, test_steps) {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
variables['BILLING_PERIOD'] = `${year}-${month}`;
variables['INVOICE_REF'] = `INV-${variables['CUSTOMER_ID']}-${year}${month}`;
return response.Success();
}Évitez les dates codées en dur qui ne fonctionneront plus le mois prochain, et générez des valeurs composites à partir de variables existantes.
4. Débloquer la page
function Step(response, variables, DOM, api_client, console, network, test_steps) {
// A cookie banner intercepts the login button on staging, so dismiss it.
const banner = DOM.querySelector('.cookie-banner');
if (banner) banner.remove();
return response.Success();
}5. Réagir à une étape précédente
function Step(response, variables, DOM, api_client, console, network, test_steps) {
const login = test_steps.find(s => s.name.includes('Log in'));
if (login && login.duration > 5000) {
variables['USE_RECOVERY_FLOW'] = 'true';
console.warn('Login was slow, switching to the recovery flow');
}
return response.Success();
}Enregistrez un indicateur dans une variable, puis effectuez une branche en fonction de celui-ci à l’aide d’une étape conditionnelle suivante.
Affichage des résultats dans une exécution de test
Dans la vue d'exécution, sélectionnez l'étape JavaScript pour ouvrir son onglet JavaScript. Celui-ci affiche :
Un bloc « Résultat », la valeur renvoyée par votre étape (le cas échéant) et la sortie
devotreconsole. Si le code a rencontré une erreur, vous verrez également le message et le numéro de ligne; cliquez dessus pour ouvrir l'éditeur à cette ligne.
Résultat | Signification |
Succès | L'étape a renvoyé |
Échec | L'étape a renvoyé |
Erreur | Une erreur s'est produite dans votre code (par exemple, une faute de frappe ou un élément manquant). Le message d'erreur et le numéro de ligne s'affichent pour vous permettre de corriger l'erreur. |



