Retour au blog
OutilsTestsPrestaFlow

PrestaFlow : gérer les scénarios sur plusieurs locales

PrestaEdit
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 en isNotEmpty() — 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. Un goToPage('login') sait aller sur /login en anglais et sur /connexion en 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 est fr.

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" si PRESTAFLOW_LOCALE=en (ou si aucun catalogue ne connaît cette clé — c’est l’identité)
  • "Vous êtes bien abonné à la newsletter." si PRESTAFLOW_LOCALE=fr et 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