fix: bouton de confirmation désactivé après avoir sélectionné une carte, si une autre action réseau survient entretemps

Cause : le listener 'game-state' de GameScene se déclenche à CHAQUE action
de N'IMPORTE QUEL joueur dans la salle (jouer une carte, acheter un objet
ou un bâtiment, piocher/jouer un événement) — pas seulement au vrai
changement de tour. À chaque déclenchement, dès que phase==='selecting',
_deactivateBtn() était appelé INCONDITIONNELLEMENT, même si le joueur avait
déjà sélectionné une carte de sa main (this.selectedCard non-null) sans
encore l'avoir confirmée.

Conséquence concrète : sélectionner une carte, PUIS effectuer n'importe
quelle autre action (typiquement piocher une carte Événement) désactivait
visuellement le bouton "CONFIRMER MA CARTE" (fond terne, texte grisé) alors
que la carte restait réellement sélectionnée en mémoire ET visuellement
surélevée sur le plateau (CardObject._selected reste true, jamais
désélectionnée par ce chemin). Un premier clic sur la carte la
DÉSÉLECTIONNAIT alors (CardObject._onDown bascule select/deselect selon
_selected, déjà à true), obligeant à cliquer une seconde fois pour la
vraiment resélectionner — exactement le symptôme rapporté.

Fix : ne réinitialiser visuellement le bouton (_deactivateBtn()) que si
aucune carte n'est actuellement sélectionnée (),
respectant l'état réel de sélection au lieu de le réinitialiser à chaque
game-state reçu.

Nouveau test E2E de régression (e2e/tests/card-selection-persistence.spec.js)
reproduisant précisément le scénario : sélectionner une carte, piocher un
événement, vérifier que selectedCard ET le pulse-tween du bouton restent
actifs, puis confirmer directement sans recliquer sur la carte. Confirmé
discriminant : échoue de façon reproductible (2/2 tentatives) quand le fix
est retiré isolément, passe systématiquement avec le fix en place.

Ajout des helpers e2e/tests/helpers.js: selectHandCard() et
confirmSelectedCard() (extraits de playCard(), qui reste inchangée en
façade — les 5 usages existants de playCard() dans la suite E2E restent
compatibles sans modification).

54 tests unitaires client + 166 tests unitaires serveur + suite
game-flow.spec.js (4 tests, non liés à ce fix) toujours au vert.
This commit is contained in:
Kevin L'Hereec committed 2026-08-25 15:01:55 +02:00
1 parent 4fe9cf4393
commit a5ecc23498
3 files changed
+142 -3

No files matched your search

+14 -1
View File
@@ -1186,7 +1186,20 @@ export class GameScene extends Phaser.Scene {
this._lastRoundResult = null
this.phaseText.setText('Choisissez une carte puis confirmez')
this.readyText.setText('')
this._deactivateBtn()
// Ne réinitialiser visuellement le bouton QUE si aucune carte n'est
// déjà sélectionnée. Ce listener 'game-state' se déclenche à chaque
// action de N'IMPORTE QUEL joueur (ex: un adversaire qui pioche un
// événement ou achète un objet), pas seulement au vrai changement de
// tour — sans cette garde, _deactivateBtn() désactivait visuellement
// le bouton "CONFIRMER MA CARTE" alors que this.selectedCard restait
// valide en mémoire (toujours sélectionnée, toujours surélevée
// visuellement), désynchronisant le bouton de l'état réel de la
// carte : un premier clic sur la carte la désélectionnait (elle
// était déjà _selected=true côté CardObject), il fallait alors
// recliquer une seconde fois pour la vraiment resélectionner.
if (!this.selectedCard) {
this._deactivateBtn()
}
// (Re)construire les slots si le nombre de joueurs a changé (premier
// tour), OU si la liste d'objets/bâtiments possédés par un adversaire
// a changé (leurs mini-cartes, affichées sous leur slot, doivent