Retour au blog
OutilsTestsPrestaFlow

PrestaFlow : tester une preprod derrière un htpasswd

PrestaEdit
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 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 un it — le login programmatique classique

Ordre dans lequel PrestaFlow les applique :

  1. before() pose le header Basic Auth avant toute navigation
  2. before() pose ensuite les cookies avant toute navigation
  3. 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 via setExtraHTTPHeaders() dans un override de before(), 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