PrestaFlow : tester une preprod derrière un htpasswd
Décor
Cas typique : votre préproduction PrestaShop est planquée derrière un htpasswd (Basic Auth nginx ou Apache), pour empêcher les crawlers, les curieux, ou un client qui découvrirait un module en avant-première. Vos scénarios PrestaFlow, en l’état, se prennent un 401 à la première requête — Chrome bascule sur chrome-error://net::ERR_INVALID_AUTH_CREDENTIALS, plus rien ne fonctionne.
Cette annexe montre comment passer l’auth Basic à PrestaFlow proprement, et explique pourquoi la solution qui vient d’abord à l’esprit (mettre les creds dans l’URL) est cassée.
La fausse bonne idée : https://user:pass@preprod.example.com
Le premier réflexe, c’est d’incorporer les identifiants directement dans les URLs du .env :
PRESTAFLOW_FO_URL=https://preview:supersecret@preprod.example.com/
PRESTAFLOW_BO_URL=https://preview:supersecret@preprod.example.com/admin-dev/
Ça marche pour la navigation top-level. Un goToPage('home') charge la home sans souci, Chrome décode les creds inline et pose le header pour cette requête.
Ça ne marche pas pour :
- Les requêtes XHR — Chrome n’applique pas l’auth inline sur les requêtes AJAX. Un scénario qui déclenche un ajout au panier via AJAX (parcours d’achat, cargador de pagination catalogue) se prend un 401 sur le XHR — la home avait chargé, mais l’action métier tombe silencieusement.
- Les redirections — pas toujours suivies avec les creds. Une redirection front → BO peut perdre l’auth en cours de route.
- Les sous-ressources — images, CSS, JS. Les captures de régression visuelle ressemblent à une page cassée parce que les assets manquent.
Résultat : le scénario semble démarrer, il tombe sur une erreur qui n’a rien à voir avec le vrai problème métier. Vous cherchez pendant une heure avant de suspecter l’auth.
La bonne mécanique : PRESTAFLOW_BASIC_*
PrestaFlow expose deux variables d’environnement dédiées :
PRESTAFLOW_FO_URL=https://preprod.example.com/
PRESTAFLOW_BO_URL=https://preprod.example.com/admin-dev/
PRESTAFLOW_BASIC_USER=preview
PRESTAFLOW_BASIC_PASS=un-mot-de-passe-partagé
Au boot de chaque suite, PrestaFlow calcule le header Authorization: Basic <base64(user:pass)> et le pose au niveau de la connexion navigateur. Chaque page créée ensuite hérite du header — navigation top-level, XHR, sous-ressources, tout.
Rien à changer côté scénarios. Vos suites tournent comme si la boutique était accessible sans htpasswd.
Le code de référence vit dans TestsSuite.php:526-563.
Pourquoi ça bat l’URL avec creds inline
Le point clef est où le header est attaché. L’approche URL pose l’auth au niveau d’une requête. Chrome décode, pose l’auth pour cette requête, oublie ensuite. Toute nouvelle requête part vierge, à charge à Chrome de re-décoder l’URL — ce qu’il ne fait pas pour les XHR.
L’approche PrestaFlow pose l’auth au niveau du navigateur via Browser::setConnectionHttpHeaders(). Chaque nouvelle page créée par le browser factory hérite de ce header. Et comme goToPage() en front ferme la page courante pour en créer une neuve, PrestaFlow réapplique explicitement le header sur la nouvelle page. C’est ceinture et bretelles — mais c’est indispensable, sinon la première navigation partirait sans auth.
Résultat : une seule config .env, tous les cas couverts, y compris ceux qui cassaient avec l’URL inline.
En CI : passer par des secrets
Standard GitHub Actions. Ajoutez PRESTAFLOW_BASIC_USER et PRESTAFLOW_BASIC_PASS en secrets du dépôt (Settings → Secrets and variables → Actions), puis dans votre workflow :
- name: Run PrestaFlow (preprod protégée)
env:
PRESTAFLOW_FO_URL: https://preprod.example.com/
PRESTAFLOW_BO_URL: https://preprod.example.com/admin-dev/
PRESTAFLOW_BASIC_USER: ${{ secrets.PRESTAFLOW_BASIC_USER }}
PRESTAFLOW_BASIC_PASS: ${{ secrets.PRESTAFLOW_BASIC_PASS }}
run: ./vendor/bin/prestaflow run tests/prestaflow
Notez qu’avec l’Action officielle, le cas Flashlight ne se pose pas — Flashlight lance sa propre boutique dans un conteneur, sans htpasswd. PRESTAFLOW_BASIC_* est utile quand vous testez une preprod hébergée ailleurs — un serveur staging, une Netlify PR preview, un environnement client.
Combiner les trois couches d’auth
Les annexes précédentes ont introduit deux autres mécanismes d’auth qui se cumulent avec Basic Auth :
- HTTP Basic (cette annexe) — l’accès au domaine
- Cookies pré-injectés — la session BO déjà ouverte
login()dans unit— le login programmatique classique
Ordre dans lequel PrestaFlow les applique :
before()pose le header Basic Auth avant toute navigationbefore()pose ensuite les cookies avant toute navigation- Vos scénarios peuvent choisir de faire un
login()ou pas — les cookies pré-injectés ayant potentiellement rendu cette étape inutile
Les trois cohabitent sans conflit. Cas pratique : testez une preprod protégée par htpasswd, avec un cookie de session admin BO déjà valide → vos suites vont directement à l’action métier, sans htpasswd form ni login form.
Cas particulier : creds différents front vs BO
Parfois le htpasswd n’est appliqué qu’au BO (le front est public), ou l’inverse. Deux configurations possibles :
- Le plus courant — le htpasswd couvre l’ensemble du domaine, mêmes creds partout,
PRESTAFLOW_BASIC_*suffit tel quel. - Cas plus rare — creds différents front / BO, ou htpasswd sur un seul des deux. Il faut alors renoncer à
PRESTAFLOW_BASIC_*(qui est global) et gérer soi-même viasetExtraHTTPHeaders()dans un override debefore(), en conditionnant selon l’URL cible. Solution qu’on ne détaille pas ici — c’est un cas de bord suffisamment rare pour justifier un peu de code custom quand il se présente.
Notes
Dans la Série Prestaflow — article 8 sur 14