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.
This commit is contained in:
1 parent
6a1c800253
commit
11cba0467b
20 files changed
+3447
-100
No files matched your search
@@ -1,52 +0,0 @@
|
||||
import Phaser from 'phaser'
|
||||
|
||||
// Scène superposée pour les effets UI (notifications, fin de partie)
|
||||
export class UIScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'UIScene', active: false })
|
||||
}
|
||||
|
||||
create() {
|
||||
this.socket = this.registry.get('socket')
|
||||
|
||||
this.socket.on('game-over', (results) => {
|
||||
this.showEndScreen(results)
|
||||
})
|
||||
}
|
||||
|
||||
showEndScreen(results) {
|
||||
const { width, height } = this.scale
|
||||
|
||||
// Fond semi-transparent
|
||||
this.add.rectangle(width / 2, height / 2, width, height, 0x000000, 0.85)
|
||||
|
||||
this.add.text(width / 2, height / 2 - 150, 'FIN DE PARTIE', {
|
||||
fontSize: '40px',
|
||||
color: '#d4a732',
|
||||
fontFamily: 'Georgia'
|
||||
}).setOrigin(0.5)
|
||||
|
||||
const sorted = [...results].sort((a, b) => b.score - a.score)
|
||||
sorted.forEach((p, i) => {
|
||||
const y = height / 2 - 80 + i * 50
|
||||
const medal = i === 0 ? '👑 ' : `${i + 1}. `
|
||||
this.add.text(width / 2, y, `${medal}${p.name} — ${p.score} pts`, {
|
||||
fontSize: '22px',
|
||||
color: i === 0 ? '#d4a732' : '#f5e6c8',
|
||||
fontFamily: 'Georgia'
|
||||
}).setOrigin(0.5)
|
||||
})
|
||||
|
||||
const btn = this.add.text(width / 2, height / 2 + 150, '[ RETOUR AU MENU ]', {
|
||||
fontSize: '18px',
|
||||
color: '#1a0a00',
|
||||
backgroundColor: '#d4a732',
|
||||
padding: { x: 20, y: 10 },
|
||||
fontFamily: 'Georgia'
|
||||
}).setOrigin(0.5).setInteractive({ cursor: 'pointer' })
|
||||
|
||||
btn.on('pointerdown', () => {
|
||||
window.location.href = '/'
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user