PrestaFlow : gérer les scénarios sur plusieurs locales
Le problème
Plusieurs annexes de cette série ont contourné un même sujet en le repoussant à plus tard :
- Dans Tester un module tiers, l’assertion
contains('subscription')a été volontairement affaiblie enisNotEmpty()— parce que sur une boutique française le message contient « inscription », pas « subscription », et qu’aucune assertion en dur ne peut couvrir les deux. - Dans Un scénario qui tient de PS 1.7 à 9, on a noté que multi-versions rime souvent avec multi-locale et qu’il faudrait “paramétrer le texte attendu selon la locale du run”.
Dès qu’une boutique existe en plusieurs langues — ou qu’on la teste en anglais aujourd’hui puis dans sa version localisée demain — l’assertion en dur casse. Il faut un mécanisme.
Il en existe deux dans PrestaFlow, distincts et complémentaires : URLs friendly (navigation) et Translations (assertions).
Deux mécanismes, deux dossiers
src/Urls/{locale}.json— mappe les slugs canoniques (anglais) vers leur variante localisée. UngoToPage('login')sait aller sur/loginen anglais et sur/connexionen français.src/Translations/{locale}.json— mappe les messages canoniques (anglais) vers leur traduction.$this->translate('The employee does not exist...')retourne la version française si la locale courante estfr.
Les deux systèmes sont pilotés par la même variable d’environnement : PRESTAFLOW_LOCALE.
URLs friendly : la partie déjà gérée pour vous
Les URLs friendly des pages standard PrestaShop sont déjà cataloguées côté lib. Extrait de src/Urls/fr.json :
{
"guest-tracking": "suivi-commande-invite",
"login": "connexion",
"cart": "panier?action=show",
"order": "commande"
}
Un scénario qui écrit :
$frontOfficeCartPage->goToPage('cart');
atterrit sur /cart avec PRESTAFLOW_LOCALE=en et sur /panier?action=show avec PRESTAFLOW_LOCALE=fr. Rien à faire côté scénario.
Traductions : le vrai travail
Reprenons la Page Modules\PsEmailsubscription\NewsletterBlock de l’annexe Tester un module tiers. Le point qui coinçait, c’est cette assertion :
Expect::that($page->getResultMessage())
->contains('subscription'); // ← casse en français
La solution PrestaFlow tient en deux ingrédients : la méthode defineMessages() de la Page et la fonction translate() du parent.
Déclarer les messages attendus
Sur la Page, on ajoute :
public function defineMessages(): array
{
return [
'successText' => $this->translate('You have successfully subscribed'),
];
}
translate('You have successfully subscribed') consulte le catalogue de la locale courante et retourne :
"You have successfully subscribed"siPRESTAFLOW_LOCALE=en(ou si aucun catalogue ne connaît cette clé — c’est l’identité)"Vous êtes bien abonné à la newsletter."siPRESTAFLOW_LOCALE=fret que ce message est dans le catalogue français.
Les messages résolus sont pré-calculés au chargement de la Page et disponibles via getMessage('successText').
Exposer une assertion sémantique
Toujours sur la Page, on ajoute une méthode qui compare le message affiché au message attendu :
public function subscriptionSucceeded(): bool
{
return str_contains(
$this->getResultMessage(),
(string) $this->getMessage('successText')
);
}
Le scénario devient enfin lisible :
Expect::that($modulesPsEmailsubscriptionNewsletterBlockPage->subscriptionSucceeded())
->isTheSameAs(true);
Il passe en français, en anglais, et sur toute locale pour laquelle le catalogue contient la traduction. Une seule chaîne canonique (l’anglaise) dans le code, la traduction vit à côté dans un JSON — même modèle mental que la traduction PrestaShop elle-même.
Ajouter ses propres traductions
Le catalogue de la lib couvre ses propres Pages (Login, Product, Listing, etc.). Pour un message qui vous appartient ("You have successfully subscribed" n’est pas un texte PrestaShop, c’est celui du module tiers ou de votre wrapper), vous ajoutez un catalogue custom à la racine de votre projet :
<racine-projet>/
├─ tests/prestaflow/ ← code PHP (Pages, Suites) — inchangé
├─ Tests/
│ └─ Translations/
│ ├─ fr.json
│ └─ en.json
├─ composer.json
└─ .env
Contenu de Tests/Translations/fr.json :
{
"You have successfully subscribed": "Vous êtes bien abonné à la newsletter."
}
Le fichier en.json peut rester {} (l’identité) ou vous permettre d’overrider des messages de la lib si nécessaire.
La lib merge les catalogues dans cet ordre : default → major → minor → patch → custom. Vos traductions gagnent toujours sur celles de la lib, ce qui vous permet aussi bien de compléter que de corriger.
Tester la même suite contre plusieurs locales, en local
Même approche que le script multi-versions de l’annexe précédente : boucle shell, override d’une variable d’environnement, la suite ne change pas.
#!/usr/bin/env bash
set -e
for locale in fr en de it es; do
echo "=== Locale $locale ==="
PRESTAFLOW_LOCALE=$locale ./vendor/bin/prestaflow run tests/prestaflow
done
Prérequis : que votre boutique de test ait bien les langues installées et activées. Sinon vos navigations aboutissent en 404, et vos assertions traduites tombent sur un message resté en anglais.
En CI, le pattern est identique à la matrice multi-versions de l’article 2 — on ajoute simplement une dimension :
strategy:
fail-fast: false
matrix:
ps-version: ['8.1.7', '9.0.0']
locale: ['fr', 'en']
Quatre combinaisons parallèles.
Notes
Dans la Série Prestaflow — article 11 sur 14