Commit Graph
3 Commits
Author SHA1 Message Date
Kevin L'Hereec 29cc728f09 feat: distinction visuelle "achat en attente" avant résolution du tour
Après avoir cliqué sur ACHETER, aucune indication ne montrait que l'achat
était pris en compte avant que la mini-carte définitive n'apparaisse à
côté de la main (à la résolution du tour, plusieurs secondes plus tard).
Le serveur exposait déjà pendingBuyItemId/pendingBuyBuildingId via
getStateFor(), mais rien côté client ne les utilisait.

- ItemBoardToken.js : nouveau paramètre `pending`. Quand actif, le jeton
  compact affiche un halo doré pulsant (tween alpha 1<->0.25 en boucle) et
  un texte "En attente..." sous l'icône, tant que l'achat n'est pas résolu.
  Le bouton ACHETER de la carte détaillée passe alors sur un libellé
  distinct "EN ATTENTE..." (au lieu de "INSUFFISANT", qui suggérerait à
  tort un problème de jauge) et devient non-cliquable, cohérent avec le
  refus déjà appliqué côté serveur pour une seconde tentative le même tour.
  Le tween est proprement arrêté dans destroy() (les jetons sont détruits/
  recréés à chaque game-state).
- GameScene.js : _buildItemTokens()/_buildBuildingTokens() déterminent
  `pending` à partir de state.pendingBuyItemId/pendingBuyBuildingId (déjà
  reçus du serveur, jamais consommés auparavant) et le passent au jeton
  correspondant, désactivant aussi son affordabilité pendant l'attente.
  shopChanged/buildingShopChanged comparent désormais aussi ces deux champs
  pour déclencher la reconstruction dès le clic sur ACHETER (avant, seul
  un changement de myItems/availableItems/jauges provoquait un rebuild).
- Nouveau test E2E (item-shop.spec.js) : après achat, vérifie que le jeton
  correspondant a pending=true, affordable=false et un tween actif chez
  l'acheteur, que l'ADVERSAIRE ne voit PAS cet état "pending" (propre au
  joueur), et qu'après résolution du tour le jeton disparaît normalement
  de la boutique (comportement de stock unique déjà existant, inchangé).

54 tests unitaires client + 166 tests unitaires serveur + suite
item-shop.spec.js (4 tests) au vert.
2026-08-25 15:29:17 +02:00
Kevin L'Hereec 9139989fa7 feat: bâtiments achetables (Église, Château Royal) avec synergie objets
- Nouveau server/src/game/buildings.js : 2 bâtiments, chacun couvrant 2
  attributs, coût réparti sur les deux jauges, garantit +1 par tour sur
  chaque attribut, avec bonus de synergie +1 si l'objet correspondant est
  aussi possédé (Église+Trousse/Sceau, Château+Charrue/Trébuchet).
- Room.js : buyBuilding() (validation coût multi-jauges), résolution des
  achats en attente avec la même priorité/stock unique que les objets,
  _applyBuildingEffects() (garantie de base + synergie, jamais de recul par
  rapport aux gains déjà boostés par un objet). getStateFor/getPlayersInfo
  exposent buildings/myBuildings/availableBuildings/pendingBuyBuildingId.
- Nouvel event socket 'buy-building', boughtBuildings inclus dans round-result.
- Client : buildings.js (miroir), BootScene génère les textures portrait des
  bâtiments (méthode _generatePortraitTexture généralisée, réutilisée avec
  les objets). ItemBoardToken généralisé (kind='item'|'building', hAnchor
  'left'|'right') pour afficher indifféremment un objet ou un bâtiment, avec
  coût détaillé par jauge affiché sur la carte agrandie pour les bâtiments.
- GameScene : boutique de bâtiments en colonne à DROITE du plateau
  (symétrique à la boutique d'objets à gauche), mes bâtiments possédés
  affichés à GAUCHE de ma main (symétrique à mes objets à droite), bâtiments
  des adversaires affichés sous leurs objets au niveau de leur slot.
- Fix : la carte détaillée héritait par défaut d'un ancrage "s'étend vers la
  droite" adapté à la boutique d'objets (bord gauche du canvas) mais cassait
  la boutique de bâtiments (bord droit) — le bouton ACHETER se retrouvait
  hors du canvas et donc injoignable au clic. Ajout du paramètre hAnchor.
- 26 nouveaux tests unitaires serveur (buildings.js + Room.js : validations
  d'achat multi-jauges, priorité/stock unique, effets de base et synergie).
- 6 nouveaux tests E2E Playwright (boutique bâtiments : affichage, position,
  carte détaillée dans les limites du canvas, coût affiché, achat complet).
- Fix flakiness des tests E2E d'achat (item-shop + building-shop) : le mode
  'min' de playCard garantit désormais que l'adversaire joue sa carte la
  plus faible sur l'attribut ciblé, au lieu de simplement jouer un autre
  attribut (insuffisant, le gain dépend de la comparaison au voisin gauche).
2026-08-21 16:19:18 +02:00
Kevin L'Hereec 11cba0467b feat: écran de fin de partie + tests unitaires client et E2E Playwright
- Fix: UIScene n'était jamais lancée (active: false, jamais scene.launch)
  donc l'event 'game-over' du serveur n'était jamais affiché — la partie
  semblait ne pas avoir de fin. Remplacé par un panneau Vue dans GameView
  (vainqueur, classement trié, bouton Quitter via vue-router). UIScene.js
  supprimée (code mort).
- Extraction de client/src/utils/hudUtils.js (constantes ATTRS/couleurs et
  gaugePercent) depuis GameView.vue pour les rendre testables isolément.
- Tests unitaires client (Vitest) : store Pinia (game.js) et hudUtils
  (24 tests, client/test/unit/).
- Tests d'intégration E2E (Playwright, e2e/) avec de vrais clients
  Socket.io et rendu Phaser réel dans Chromium :
  * game-flow.spec.js : lobby → démarrage → main de 4 cartes → résolution
  * item-shop.spec.js : boutique, bouton désactivé si jauge insuffisante,
    achat retire l'objet pour tous + effet appliqué + affiché sur la table
  * game-over.spec.js : partie complète (12 tours) → panneau de fin
  webServer démarre automatiquement client+serveur ; ajout d'une route
  GET /health côté Express pour permettre à Playwright de détecter un
  serveur déjà démarré.
- README : documentation des 3 niveaux de tests (unitaires serveur,
  unitaires client, intégration E2E) et de la nouvelle arborescence.
2026-08-21 15:27:44 +02:00