|
|
|
# Écrire un scénario d'audit pour Tanaguru Engine
|
|
|
|
|
|
|
|
## 1. Enregistrer un parcours avec UI Vision RPA
|
|
|
|
|
|
|
|
L'extension navigateur **UI Vision RPA** (éditeur a9t9) est l'outil recommandé pour produire le fichier de scénario. Gratuite, disponible pour Chrome et Firefox, aucune inscription cloud requise pour l'usage local décrit ici.
|
|
|
|
|
|
|
|
### Installation
|
|
|
|
|
|
|
|
- [extension UI Vision pour Chrome](https://chromewebstore.google.com/detail/uivision/gcbalfbdmfieckjlnblleoemohcganoc)
|
|
|
|
- [extension UI Vision pour Firefox](https://addons.mozilla.org/fr/firefox/addon/rpa)
|
|
|
|
|
|
|
|
### Enregistrement d'un parcours
|
|
|
|
|
|
|
|
1. Ouvrir la page de départ du parcours dans l'onglet.
|
|
|
|
2. Cliquer sur l'icône UI Vision dans la barre du navigateur.
|
|
|
|
3. Bouton **+** (New Macro) → nommer la macro.
|
|
|
|
4. Bouton **Record** → effectuer le parcours manuellement.
|
|
|
|
5. Bouton **Stop** quand le parcours est terminé. Vérifier la grille, Command / Target / Value ; éditer si besoin (ajouter un `waitForElementPresent`, corriger un sélecteur fragile…).
|
|
|
|
6. Bouton **Play** pour relire et valider que le scénario passe sans erreur dans UI Vision avant upload.
|
|
|
|
7. Sauvegarder les modifications: bouton **save**.
|
|
|
|
8. Récupérer le fichier à utiliser avec Tanaguru Engine: clic droit sur le scénario → **Export as JSON**.
|
|
|
|
|
|
|
|
### Pourquoi UI Vision et pas Selenium IDE officiel ?
|
|
|
|
|
|
|
|
Le Selenium IDE officiel dépend d'`initKeyEvent`, une API DOM obsolète que Firefox a retirée et que Chrome n'a jamais implémentée.
|
|
|
|
Résultat : la commande `type` échoue sur tout navigateur moderne — aucune saisie dans un champ n'est possible. Utiliser **UI Vision**, qui n'a pas ce problème.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
## 2. La règle centrale Tanaguru : la sémantique `store`
|
|
|
|
|
|
|
|
Tanaguru détourne la commande Selenese `store` pour en faire un **déclencheur d'audit d'accessibilité**.
|
|
|
|
Son comportement varie selon la présence ou non d'autres commandes `store` dans le fichier.
|
|
|
|
|
|
|
|
| Cas | Comportement | Usage typique |
|
|
|
|
|---|---|---|
|
|
|
|
| Scénario **sans aucun** `store` | Chaque `open` ou `click` qui change d'URL déclenche un audit automatique de la nouvelle page | Parcours court, toutes les pages sont d'intérêt |
|
|
|
|
| Scénario avec **au moins un** `store` | Les `open`/`click` ne déclenchent plus rien. **Seules** les pages marquées par `store` sont auditées | Parcours long (login, navigation, modales…) ; audit du seul point d'intérêt |
|
|
|
|
|
|
|
|
### Syntaxe du `store`
|
|
|
|
|
|
|
|
```
|
|
|
|
Command: store
|
|
|
|
Target: dashboard
|
|
|
|
Value: dashboard
|
|
|
|
```
|
|
|
|
|
|
|
|
Le `Value` est le label qui apparaîtra dans les résultats d'audit.
|
|
|
|
La convention Tanaguru est d'utiliser le **même texte** dans `Target` et `Value`.
|
|
|
|
|
|
|
|
### Piège fréquent : `store` Tanaguru ≠ `store` Selenese
|
|
|
|
|
|
|
|
En Selenese classique, `store <valeur> <variable>` stocke une valeur dans une variable (ex. `store 42 maReponse` crée `${maReponse} = 42`).
|
|
|
|
|
|
|
|
Chez Tanaguru, `store` est détourné pour l'audit. **Pour stocker une variable sans déclencher d'audit**, utiliser les variantes typées : `storeText`, `storeValue`, `storeAttribute`, `storeTitle`, `storeEval`, `storeJson`…
|
|
|
|
Toutes ces variantes restent fonctionnelles sans effet secondaire sur l'audit.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
## 3. Commandes essentielles
|
|
|
|
|
|
|
|
Le sous-ensemble suivant couvre ~90 % des scénarios réels.
|
|
|
|
|
|
|
|
### Navigation
|
|
|
|
|
|
|
|
| Commande | Effet |
|
|
|
|
|---|---|
|
|
|
|
| `open <chemin>` | Navigue vers l'URL (relative à `url` de base, ou absolue) |
|
|
|
|
| `click <sélecteur>` | Clic sur un élément |
|
|
|
|
|
|
|
|
### Saisie
|
|
|
|
|
|
|
|
| Commande | Effet |
|
|
|
|
|---|---|
|
|
|
|
| `type <sélecteur> \| <texte>` | Saisit du texte dans un input |
|
|
|
|
| `check <sélecteur>` | Coche une checkbox |
|
|
|
|
| `uncheck <sélecteur>` | Décoche une checkbox |
|
|
|
|
| `select <sélecteur> \| label=Option` | Choix dans un `<select>` (aussi `value=X` ou `index=N`) |
|
|
|
|
|
|
|
|
### Attentes
|
|
|
|
|
|
|
|
| Commande | Effet |
|
|
|
|
|---|---|
|
|
|
|
| `waitForElementPresent <sélecteur>` | Attend que l'élément apparaisse dans le DOM |
|
|
|
|
| `waitForElementVisible <sélecteur>` | Attend qu'il soit visible (display, opacity, position) |
|
|
|
|
| `pause <ms>` | Attente fixe. **À éviter** — préférer `waitFor*` |
|
|
|
|
|
|
|
|
### Audit explicite
|
|
|
|
|
|
|
|
| Commande | Effet |
|
|
|
|
|---|---|
|
|
|
|
| `store <label> \| <label>` | Déclenche l'audit Tanaguru de la page courante |
|
|
|
|
|
|
|
|
### Vérifications
|
|
|
|
|
|
|
|
| Commande | Effet |
|
|
|
|
|---|---|
|
|
|
|
| `verifyText <sélecteur> \| <texte>` | Logue un warning si pas égal, continue |
|
|
|
|
| `assertText <sélecteur> \| <texte>` | Interrompt le scénario si pas égal |
|
|
|
|
| `verifyElementPresent <sélecteur>` | Vérifie qu'un élément existe |
|
|
|
|
| `verifyTitle <titre>` | Vérifie le titre de la page |
|
|
|
|
|
|
|
|
Différence clé : `verify*` continue sur échec (logue juste un warning), `assert*` stoppe le scénario.
|
|
|
|
Utiliser `verify*` pour la plupart des contrôles de parcours.
|
|
|
|
|
|
|
|
### Scripts
|
|
|
|
|
|
|
|
| Commande | Effet |
|
|
|
|
|---|---|
|
|
|
|
| `executeScript <js> \| <varName>` | Exécute du JS et stocke le retour. `return X;` obligatoire pour retourner une valeur. |
|
|
|
|
| `executeScript <js>` | Exécute sans retour |
|
|
|
|
|
|
|
|
Exemple : `executeScript | document.getElementById('X').scrollIntoView({block:'center'});` — scroll avant un click.
|
|
|
|
|
|
|
|
### Sélecteurs acceptés dans le `target`
|
|
|
|
|
|
|
|
| Préfixe | Exemple | Quand utiliser |
|
|
|
|
|---|---|---|
|
|
|
|
| `id=` | `id=submit-btn` | **Le plus fiable**, à privilégier systématiquement |
|
|
|
|
| `name=` | `name=email` | Pour les inputs de formulaire |
|
|
|
|
| `css=` | `css=#main > .btn-primary` | Pour cibler par structure ou pseudo-classe |
|
|
|
|
| `xpath=` | `xpath=//button[@type='submit']` | En dernier recours |
|
|
|
|
| `linkText=` | `linkText=Contact` | pour cibler un lien par contenu textuel |
|
|
|
|
| *(sans préfixe)* | `submit-btn` | Essayé comme `id=` puis `name=` |
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
## 4. Problèmes connus
|
|
|
|
|
|
|
|
### 4.1. Encoding des accents — **bug confirmé côté API Engine**
|
|
|
|
|
|
|
|
- **Symptôme** : n'importe quel `verifyText` ou `type` avec un accent échoue côté Tanaguru. Exemples observés :
|
|
|
|
- `verifyText "Annulé"` → `Expected: [Annul��] / Result: [Annulé]`
|
|
|
|
- `type "téléchargement"` → la requête réelle envoyée au site cible est du charabia → 0 résultat → la suite du scénario casse par ricochet (clic sur un élément qui n'existe pas)
|
|
|
|
- **Cause** : l'API Engine lit les fichiers `.side`/JSON uploadés avec un charset ≠ UTF-8. Chaque octet UTF-8 multi-byte est décodé indépendamment, donnant un caractère de remplacement `�` par octet (donc 2 pour `é`, 3 pour `—`).
|
|
|
|
- **Remède** : écrire les caractères non-ASCII en **escapes JSON `\uXXXX`** dans tous les champs `target` et `value` (les `comment`/`Description` ne sont pas évalués, on peut y laisser les accents bruts pour la lisibilité).
|
|
|
|
|
|
|
|
### 4.2. Commandes listées ailleurs mais buggées — à ne pas utiliser
|
|
|
|
|
|
|
|
Plusieurs commandes de la syntaxe Selenese historique ne sont pas utilisables côté Tanaguru Engine (bugs, non enregistrées, ou sans effet utile) :
|
|
|
|
|
|
|
|
| Commande | Pourquoi l'éviter | Alternative |
|
|
|
|
|---|---|---|
|
|
|
|
| `debugger` | Lit `stdin` via `Scanner.nextLine()` et jette `NoSuchElementException` en contexte serveur non interactif | Ne pas utiliser |
|
|
|
|
| `setCursorPosition` | Bug : parse le locator comme entier et jette `Position is not a number` | idem |
|
|
|
|
| `storeCursorPosition` | `NullPointerException` dans `JSLibrary.getCursorPosition` | idem |
|
|
|
|
| `break` | Non enregistrée dans selenese-runner | `gotoIf <cond> <label-sortie>` + `label <label-sortie>` |
|
|
|
|
| `continue` | Non enregistrée | idem |
|
|
|
|
| `screenshot/captureEntirePageScreenshot` | Inutile côté Engine : le fichier est écrit dans le FS du conteneur, inaccessible à l'utilisateur | activer les captures d'écrans dans les paramètres de l'audit Tanaguru Engine |
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
## 5. Exemple complet annoté
|
|
|
|
|
|
|
|
Scénario « login puis audit du dashboard » :
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"version": "2.0",
|
|
|
|
"name": "audit-dashboard-apres-login",
|
|
|
|
"url": "http://mon-site.example",
|
|
|
|
"tests": [
|
|
|
|
{
|
|
|
|
"name": "login-et-dashboard",
|
|
|
|
"commands": [
|
|
|
|
{"command": "open", "target": "/login", "value": ""},
|
|
|
|
{"command": "type", "target": "id=email", "value": "user@example.com"},
|
|
|
|
{"command": "type", "target": "id=password", "value": "motdepasse"},
|
|
|
|
{"command": "click", "target": "id=submit", "value": ""},
|
|
|
|
{"command": "waitForElementPresent", "target": "id=dashboard-container", "value": ""},
|
|
|
|
{"command": "store", "target": "dashboard", "value": "dashboard"}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Commentaire pas-à-pas :
|
|
|
|
|
|
|
|
1. `open /login` → navigue vers `http://mon-site.example/login`. **Pas d'audit** ici : la présence d'un `store` plus loin bascule tout le fichier en mode explicite.
|
|
|
|
2. `type id=email` / `type id=password` → saisit les credentials.
|
|
|
|
3. `click id=submit` → soumet le formulaire, navigue vers `/dashboard`. Toujours **pas d'audit** (mode explicite + on n'a pas encore croisé la ligne `store`).
|
|
|
|
4. `waitForElementPresent id=dashboard-container` → attend que le DOM du dashboard soit rendu. Indispensable sur une SPA ou une page avec chargement asynchrone.
|
|
|
|
5. `store dashboard | dashboard` → **déclenche l'audit** de la page courante. Le rapport Tanaguru affichera le checkpoint sous le label « dashboard ».
|
|
|
|
|
|
|
|
### Variante « auto-audit »
|
|
|
|
|
|
|
|
Retirer la ligne `store`.
|
|
|
|
Chaque changement d'URL sera alors audité individuellement : ici, `/login` ET `/dashboard` seront dans le rapport.
|
|
|
|
Utile pour auditer un parcours complet.
|
|
|
|
|
|
|
|
### Variante « login + plusieurs pages auditées »
|
|
|
|
|
|
|
|
Ajouter plusieurs `store` à différents points du parcours :
|
|
|
|
|
|
|
|
```json
|
|
|
|
{"command": "click", "target": "linkText=Mon profil", "value": ""},
|
|
|
|
{"command": "waitForElementPresent", "target": "id=profil-form", "value": ""},
|
|
|
|
{"command": "store", "target": "profil", "value": "profil"},
|
|
|
|
|
|
|
|
{"command": "click", "target": "id=nav-parametres", "value": ""},
|
|
|
|
{"command": "waitForElementPresent", "target": "id=parametres", "value": ""},
|
|
|
|
{"command": "store", "target": "parametres", "value": "parametres"}
|
|
|
|
```
|
|
|
|
|
|
|
|
Résultat : trois pages auditées (`dashboard`, `profil`, `parametres`), les pages intermédiaires (login, transitions) ignorées.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
## 6. Référence : lib sous-jacente
|
|
|
|
|
|
|
|
Le moteur qui exécute les scénarios `.side` côté Tanaguru est `selenese-runner-java`, version 4.2.0.
|
|
|
|
|
|
|
|
- Référence officielle Selenium IDE (syntaxe `.side`) : [selenium.dev/selenium-ide/docs/en/api/commands](https://www.selenium.dev/selenium-ide/docs/en/api/commands)
|
|
|
|
- Lib sous-jacente : [github.com/vmi/selenese-runner-java](https://github.com/vmi/selenese-runner-java)
|
|
|
|
|
|
|
|
Les commandes listées dans ces ressources sont **globalement** supportées, sauf les exceptions notées au §4.2.
|
|
|
|
Si en doute, tester localement dans UI Vision d'abord, puis uploader. |