test(e2e): helper condivisi e refactor degli spec di gioco
- nuovo tests/e2e/helpers.cjs: openController (viewport portrait per il layout mobile), openDisplay, resetGame, addPoints - resetGame gestisce il dialog di vittoria persistente e reimposta i nomi di default (lo stato è condiviso e persistente: serve per il determinismo) - full-match/game-simulation: gestito il dialog SET VINTO automatico a 25/15 - basic-flow/game-operations: migrati agli helper condivisi
This commit is contained in:
@@ -1,26 +1,19 @@
|
|||||||
const { test, expect } = require('@playwright/test');
|
const { test, expect } = require('@playwright/test');
|
||||||
|
const { openController, openDisplay, resetGame } = require('./helpers.cjs');
|
||||||
|
|
||||||
test.describe('Basic Flow: Controller ↔ Display', () => {
|
test.describe('Basic Flow: Controller ↔ Display', () => {
|
||||||
|
|
||||||
test('dovrebbe caricare Display e Controller con i titoli corretti', async ({ context }) => {
|
test('dovrebbe caricare Display e Controller con i titoli corretti', async ({ context }) => {
|
||||||
const displayPage = await context.newPage();
|
const displayPage = await openDisplay(context);
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
|
|
||||||
await displayPage.goto('http://localhost:3000');
|
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
|
|
||||||
await expect(displayPage).toHaveTitle(/Segnapunti/);
|
await expect(displayPage).toHaveTitle(/Segnapunti/);
|
||||||
await expect(controllerPage).toHaveTitle(/Controller/);
|
await expect(controllerPage).toHaveTitle(/Controller/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('il punteggio iniziale dovrebbe essere 0-0', async ({ context }) => {
|
test('il punteggio iniziale dovrebbe essere 0-0', async ({ context }) => {
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
await resetGame(controllerPage);
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
|
|
||||||
// Attende la connessione WebSocket
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
const homeScore = controllerPage.locator('.team-score.home-bg .team-pts');
|
const homeScore = controllerPage.locator('.team-score.home-bg .team-pts');
|
||||||
const guestScore = controllerPage.locator('.team-score.guest-bg .team-pts');
|
const guestScore = controllerPage.locator('.team-score.guest-bg .team-pts');
|
||||||
@@ -29,28 +22,10 @@ test.describe('Basic Flow: Controller ↔ Display', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('click +1 Home sul Controller dovrebbe aggiornare il Display', async ({ context }) => {
|
test('click +1 Home sul Controller dovrebbe aggiornare il Display', async ({ context }) => {
|
||||||
const displayPage = await context.newPage();
|
const displayPage = await openDisplay(context);
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
|
|
||||||
await displayPage.goto('http://localhost:3000');
|
await resetGame(controllerPage);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
|
|
||||||
// Attende la connessione WebSocket del controller
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
// Reset per stato pulito
|
|
||||||
await controllerPage.getByText(/Reset/i).first().click();
|
|
||||||
const btnConfirm = controllerPage.locator('.dialog .btn-confirm');
|
|
||||||
if (await btnConfirm.isVisible()) {
|
|
||||||
await btnConfirm.click();
|
|
||||||
}
|
|
||||||
// doReset apre automaticamente il dialog di configurazione: chiudilo
|
|
||||||
const cfgCancel = controllerPage.locator('.dialog-config .btn-cancel');
|
|
||||||
if (await cfgCancel.isVisible()) {
|
|
||||||
await cfgCancel.click();
|
|
||||||
}
|
|
||||||
await controllerPage.waitForTimeout(200);
|
|
||||||
|
|
||||||
// Click +1 Home
|
// Click +1 Home
|
||||||
await controllerPage.locator('.team-score.home-bg').click();
|
await controllerPage.locator('.team-score.home-bg').click();
|
||||||
@@ -64,27 +39,10 @@ test.describe('Basic Flow: Controller ↔ Display', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('click +1 Guest sul Controller dovrebbe aggiornare il Display', async ({ context }) => {
|
test('click +1 Guest sul Controller dovrebbe aggiornare il Display', async ({ context }) => {
|
||||||
const displayPage = await context.newPage();
|
const displayPage = await openDisplay(context);
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
|
|
||||||
await displayPage.goto('http://localhost:3000');
|
await resetGame(controllerPage);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
// Reset
|
|
||||||
await controllerPage.getByText(/Reset/i).first().click();
|
|
||||||
const btnConfirm = controllerPage.locator('.dialog .btn-confirm');
|
|
||||||
if (await btnConfirm.isVisible()) {
|
|
||||||
await btnConfirm.click();
|
|
||||||
}
|
|
||||||
// doReset apre automaticamente il dialog di configurazione: chiudilo
|
|
||||||
const cfgCancel = controllerPage.locator('.dialog-config .btn-cancel');
|
|
||||||
if (await cfgCancel.isVisible()) {
|
|
||||||
await cfgCancel.click();
|
|
||||||
}
|
|
||||||
await controllerPage.waitForTimeout(200);
|
|
||||||
|
|
||||||
// Click +1 Guest
|
// Click +1 Guest
|
||||||
await controllerPage.locator('.team-score.guest-bg').click();
|
await controllerPage.locator('.team-score.guest-bg').click();
|
||||||
@@ -98,27 +56,10 @@ test.describe('Basic Flow: Controller ↔ Display', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('la sincronizzazione dovrebbe funzionare con punti alternati', async ({ context }) => {
|
test('la sincronizzazione dovrebbe funzionare con punti alternati', async ({ context }) => {
|
||||||
const displayPage = await context.newPage();
|
const displayPage = await openDisplay(context);
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
|
|
||||||
await displayPage.goto('http://localhost:3000');
|
await resetGame(controllerPage);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
// Reset
|
|
||||||
await controllerPage.getByText(/Reset/i).first().click();
|
|
||||||
const btnConfirm = controllerPage.locator('.dialog .btn-confirm');
|
|
||||||
if (await btnConfirm.isVisible()) {
|
|
||||||
await btnConfirm.click();
|
|
||||||
}
|
|
||||||
// doReset apre automaticamente il dialog di configurazione: chiudilo
|
|
||||||
const cfgCancel = controllerPage.locator('.dialog-config .btn-cancel');
|
|
||||||
if (await cfgCancel.isVisible()) {
|
|
||||||
await cfgCancel.click();
|
|
||||||
}
|
|
||||||
await controllerPage.waitForTimeout(200);
|
|
||||||
|
|
||||||
// Home +1, Guest +1, Home +1
|
// Home +1, Guest +1, Home +1
|
||||||
await controllerPage.locator('.team-score.home-bg').click();
|
await controllerPage.locator('.team-score.home-bg').click();
|
||||||
|
|||||||
@@ -1,49 +1,10 @@
|
|||||||
const { test, expect } = require('@playwright/test');
|
const { test, expect } = require('@playwright/test');
|
||||||
|
const { openController, resetGame, addPoints } = require('./helpers.cjs');
|
||||||
// Helper: reset dal controller
|
|
||||||
async function resetGame(controllerPage) {
|
|
||||||
await controllerPage.getByText(/Reset/i).first().click();
|
|
||||||
const btnConfirm = controllerPage.locator('.dialog .btn-confirm');
|
|
||||||
if (await btnConfirm.isVisible()) {
|
|
||||||
await btnConfirm.click();
|
|
||||||
}
|
|
||||||
// doReset apre automaticamente il dialog di configurazione: chiudilo
|
|
||||||
const cfgCancel = controllerPage.locator('.dialog-config .btn-cancel');
|
|
||||||
if (await cfgCancel.isVisible()) {
|
|
||||||
await cfgCancel.click();
|
|
||||||
}
|
|
||||||
await controllerPage.waitForTimeout(300);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper: incrementa punti per una squadra N volte
|
|
||||||
async function addPoints(controllerPage, team, count) {
|
|
||||||
const selector = team === 'home' ? '.team-score.home-bg' : '.team-score.guest-bg';
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
await controllerPage.locator(selector).click();
|
|
||||||
await controllerPage.waitForTimeout(30);
|
|
||||||
}
|
|
||||||
await controllerPage.waitForTimeout(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper: assegna un set a una squadra (25 punti + click SET)
|
|
||||||
async function winSet(controllerPage, team) {
|
|
||||||
await addPoints(controllerPage, team, 25);
|
|
||||||
// Clicca bottone SET
|
|
||||||
const setSelector = team === 'home' ? '.btn-set.home-bg' : '.btn-set.guest-bg';
|
|
||||||
await controllerPage.locator(setSelector).click();
|
|
||||||
await controllerPage.waitForTimeout(100);
|
|
||||||
// Reset punti per il prossimo set
|
|
||||||
// (in questo gioco i punti non si resettano automaticamente, serve reset manuale
|
|
||||||
// o il controller gestisce il prossimo set manualmente)
|
|
||||||
}
|
|
||||||
|
|
||||||
test.describe('Full Match Simulation', () => {
|
test.describe('Full Match Simulation', () => {
|
||||||
|
|
||||||
test('Partita 2/3: Home vince 2 set a 0', async ({ context }) => {
|
test('Partita 2/3: Home vince il primo set', async ({ context }) => {
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
await resetGame(controllerPage);
|
await resetGame(controllerPage);
|
||||||
|
|
||||||
@@ -60,19 +21,19 @@ test.describe('Full Match Simulation', () => {
|
|||||||
// Verifica punteggio 25
|
// Verifica punteggio 25
|
||||||
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('25');
|
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('25');
|
||||||
|
|
||||||
// Incrementa set Home
|
// A 25-0 compare automaticamente il dialog "SET VINTO": vai al set successivo
|
||||||
await controllerPage.locator('.btn-set.home-bg').click();
|
await controllerPage.waitForSelector('.dialog-winner');
|
||||||
await controllerPage.waitForTimeout(100);
|
await controllerPage.getByText('VAI AL SET SUCCESSIVO').click();
|
||||||
|
// doNuovoSet riapre il dialog di configurazione: chiudilo
|
||||||
|
await controllerPage.locator('.dialog-config .btn-cancel').click();
|
||||||
|
await controllerPage.waitForTimeout(200);
|
||||||
|
|
||||||
// Verifica set 1 per Home
|
// Verifica set 1 per Home
|
||||||
await expect(controllerPage.locator('.team-score.home-bg .team-set')).toContainText('SET 1');
|
await expect(controllerPage.locator('.team-score.home-bg .team-set')).toContainText('SET 1');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Set decisivo 2/3: vittoria a 15 punti', async ({ context }) => {
|
test('Set decisivo 2/3: vittoria a 15 punti', async ({ context }) => {
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
await resetGame(controllerPage);
|
await resetGame(controllerPage);
|
||||||
|
|
||||||
@@ -99,18 +60,12 @@ test.describe('Full Match Simulation', () => {
|
|||||||
// Verifica punteggio 15 (e il set è decisivo: dopo 15 punti il gioco è vinto)
|
// Verifica punteggio 15 (e il set è decisivo: dopo 15 punti il gioco è vinto)
|
||||||
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('15');
|
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('15');
|
||||||
|
|
||||||
// Verifica che non si possono aggiungere altri punti (vittoria)
|
// A 15 nel set decisivo scatta la vittoria: compare il dialog (PARTITA FINITA)
|
||||||
await controllerPage.locator('.team-score.home-bg').click();
|
await expect(controllerPage.locator('.dialog-winner')).toBeVisible();
|
||||||
await controllerPage.waitForTimeout(100);
|
|
||||||
// Dovrebbe restare 15 (checkVittoria blocca incPunt)
|
|
||||||
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('15');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Set normale: punti oltre 25 fino ai vantaggi', async ({ context }) => {
|
test('Set normale: punti oltre 25 fino ai vantaggi', async ({ context }) => {
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
await resetGame(controllerPage);
|
await resetGame(controllerPage);
|
||||||
|
|
||||||
@@ -131,9 +86,7 @@ test.describe('Full Match Simulation', () => {
|
|||||||
await controllerPage.waitForTimeout(100);
|
await controllerPage.waitForTimeout(100);
|
||||||
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('26');
|
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('26');
|
||||||
|
|
||||||
// 26-24 è vittoria → non si possono più aggiungere punti
|
// 26-24 è vittoria → compare automaticamente il dialog SET VINTO
|
||||||
await controllerPage.locator('.team-score.home-bg').click();
|
await expect(controllerPage.locator('.dialog-winner')).toBeVisible();
|
||||||
await controllerPage.waitForTimeout(100);
|
|
||||||
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('26');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,28 +1,10 @@
|
|||||||
const { test, expect } = require('@playwright/test');
|
const { test, expect } = require('@playwright/test');
|
||||||
|
const { openController, openDisplay, resetGame } = require('./helpers.cjs');
|
||||||
// Helper: reset dal controller
|
|
||||||
async function resetGame(controllerPage) {
|
|
||||||
await controllerPage.getByText(/Reset/i).first().click();
|
|
||||||
const btnConfirm = controllerPage.locator('.dialog .btn-confirm');
|
|
||||||
if (await btnConfirm.isVisible()) {
|
|
||||||
await btnConfirm.click();
|
|
||||||
}
|
|
||||||
// doReset apre automaticamente il dialog di configurazione: chiudilo
|
|
||||||
const cfgCancel = controllerPage.locator('.dialog-config .btn-cancel');
|
|
||||||
if (await cfgCancel.isVisible()) {
|
|
||||||
await cfgCancel.click();
|
|
||||||
}
|
|
||||||
await controllerPage.waitForTimeout(300);
|
|
||||||
}
|
|
||||||
|
|
||||||
test.describe('Game Operations', () => {
|
test.describe('Game Operations', () => {
|
||||||
|
|
||||||
test('Undo: dovrebbe annullare l\'ultimo punto', async ({ context }) => {
|
test('Undo: dovrebbe annullare l\'ultimo punto', async ({ context }) => {
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
await resetGame(controllerPage);
|
await resetGame(controllerPage);
|
||||||
|
|
||||||
// Incrementa Home a 1
|
// Incrementa Home a 1
|
||||||
@@ -37,10 +19,8 @@ test.describe('Game Operations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Reset: dovrebbe azzerare tutto dopo conferma', async ({ context }) => {
|
test('Reset: dovrebbe azzerare tutto dopo conferma', async ({ context }) => {
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
await resetGame(controllerPage);
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
// Imposta qualche punto
|
// Imposta qualche punto
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
@@ -57,13 +37,9 @@ test.describe('Game Operations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Config: dovrebbe cambiare i nomi dei team', async ({ context }) => {
|
test('Config: dovrebbe cambiare i nomi dei team', async ({ context }) => {
|
||||||
const displayPage = await context.newPage();
|
const displayPage = await openDisplay(context);
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
|
await resetGame(controllerPage);
|
||||||
await displayPage.goto('http://localhost:3000');
|
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
// Apri config
|
// Apri config
|
||||||
await controllerPage.getByText('Config').click();
|
await controllerPage.getByText('Config').click();
|
||||||
@@ -88,13 +64,9 @@ test.describe('Game Operations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Toggle Formazione: dovrebbe mostrare la formazione sul display', async ({ context }) => {
|
test('Toggle Formazione: dovrebbe mostrare la formazione sul display', async ({ context }) => {
|
||||||
const displayPage = await context.newPage();
|
const displayPage = await openDisplay(context);
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
|
await resetGame(controllerPage);
|
||||||
await displayPage.goto('http://localhost:3000');
|
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
// Inizialmente mostra punteggio, non formazione
|
// Inizialmente mostra punteggio, non formazione
|
||||||
await expect(displayPage.locator('.punteggio-container')).toBeVisible();
|
await expect(displayPage.locator('.punteggio-container')).toBeVisible();
|
||||||
@@ -108,13 +80,9 @@ test.describe('Game Operations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Toggle Striscia: dovrebbe nascondere/mostrare la striscia', async ({ context }) => {
|
test('Toggle Striscia: dovrebbe nascondere/mostrare la striscia', async ({ context }) => {
|
||||||
const displayPage = await context.newPage();
|
const displayPage = await openDisplay(context);
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
|
await resetGame(controllerPage);
|
||||||
await displayPage.goto('http://localhost:3000');
|
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
// Inizialmente la striscia è visibile
|
// Inizialmente la striscia è visibile
|
||||||
await expect(displayPage.locator('.striscia')).toBeVisible();
|
await expect(displayPage.locator('.striscia')).toBeVisible();
|
||||||
@@ -131,13 +99,8 @@ test.describe('Game Operations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Cambi: dovrebbe effettuare una sostituzione giocatore', async ({ context }) => {
|
test('Cambi: dovrebbe effettuare una sostituzione giocatore', async ({ context }) => {
|
||||||
const displayPage = await context.newPage();
|
const displayPage = await openDisplay(context);
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
|
|
||||||
await displayPage.goto('http://localhost:3000');
|
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
await resetGame(controllerPage);
|
await resetGame(controllerPage);
|
||||||
|
|
||||||
@@ -167,10 +130,7 @@ test.describe('Game Operations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Cambi: dovrebbe mostrare errore per giocatore non in formazione', async ({ context }) => {
|
test('Cambi: dovrebbe mostrare errore per giocatore non in formazione', async ({ context }) => {
|
||||||
const controllerPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
await controllerPage.waitForSelector('.conn-bar.connected');
|
|
||||||
|
|
||||||
await resetGame(controllerPage);
|
await resetGame(controllerPage);
|
||||||
|
|
||||||
|
|||||||
@@ -1,66 +1,16 @@
|
|||||||
const { test, expect } = require('@playwright/test');
|
const { test, expect } = require('@playwright/test');
|
||||||
|
const { openController, openDisplay, resetGame, addPoints } = require('./helpers.cjs');
|
||||||
|
|
||||||
test.describe('Game Simulation', () => {
|
test.describe('Game Simulation', () => {
|
||||||
test('Simulazione Partita: Controller aggiunge punti finché non cambia il set', async ({ context }) => {
|
test('Simulazione Partita: Controller aggiunge punti finché non cambia il set', async ({ context }) => {
|
||||||
// 1. Setup Pagine
|
const displayPage = await openDisplay(context);
|
||||||
const displayPage = await context.newPage();
|
const controllerPage = await openController(context);
|
||||||
const controllerPage = await context.newPage();
|
|
||||||
|
|
||||||
await displayPage.goto('http://localhost:3000');
|
await resetGame(controllerPage);
|
||||||
await controllerPage.setViewportSize({ width: 390, height: 844 });
|
|
||||||
await controllerPage.goto('http://localhost:3000/controller');
|
|
||||||
|
|
||||||
// Selettori (basati su ID ipotetici o classi, adattali al tuo HTML reale)
|
// Porta Home a 25: in ControllerPage il click su .team-score.home-bg
|
||||||
// Assumo che nel DOM ci siano elementi con ID o classi riconoscibili
|
// incrementa i punti home. A 25-0 scatta la vittoria del set.
|
||||||
// E che i punteggi siano visibili.
|
await addPoints(controllerPage, 'home', 25);
|
||||||
|
|
||||||
// Pulisco lo stato iniziale (reset)
|
|
||||||
const btnReset = controllerPage.getByText(/Reset/i).first();
|
|
||||||
if (await btnReset.isVisible()) {
|
|
||||||
await btnReset.click();
|
|
||||||
// La modale di conferma ha un bottone "SI" con classe .btn-confirm
|
|
||||||
const btnConfirmReset = controllerPage.locator('.dialog .btn-confirm').getByText('SI');
|
|
||||||
if (await btnConfirmReset.isVisible()) {
|
|
||||||
await btnConfirmReset.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// doReset apre automaticamente il dialog di configurazione: chiudilo
|
|
||||||
const cfgCancel = controllerPage.locator('.dialog-config .btn-cancel');
|
|
||||||
if (await cfgCancel.isVisible()) {
|
|
||||||
await cfgCancel.click();
|
|
||||||
}
|
|
||||||
await controllerPage.waitForTimeout(200);
|
|
||||||
|
|
||||||
// 2. Loop per vincere il primo set (25 punti)
|
|
||||||
// In ControllerPage.vue, il click su .team-score.home-bg incrementa i punti home
|
|
||||||
const btnHomeScore = controllerPage.locator('.team-score.home-bg');
|
|
||||||
|
|
||||||
for (let i = 0; i < 25; i++) {
|
|
||||||
await btnHomeScore.click();
|
|
||||||
// Piccola pausa per lasciare tempo al server di processare e broadcastare
|
|
||||||
//await displayPage.waitForTimeout(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Verifica Vittoria Set
|
|
||||||
// I punti dovrebbero essere tornati a 0 (o mostrare 25 prima del reset manuale?)
|
|
||||||
// Il codice gameState dice: checkVittoria -> resetta solo se qualcuno chiama resetta?
|
|
||||||
// No, checkVittoria è boolean. applyAction('incPunt') incrementa.
|
|
||||||
// Se vince, il set incrementa? 'incPunt' non incrementa i set in automatico nel codice gameState checkato prima!
|
|
||||||
// Controllo applyAction:
|
|
||||||
// "s.sp.punt[team]++" ... POI "checkVittoria(s)" all'inizio del prossimo incPunt?
|
|
||||||
// NO: "if (checkVittoria(s)) break" all'inizio di incPunt impedisce di andare oltre 25 se già vinto.
|
|
||||||
// MA 'incSet' è un'azione separata!
|
|
||||||
|
|
||||||
// Aspetta, la logica standard è: arrivo a 25 -> vinco set?
|
|
||||||
// In questo codice `gameState.js` NON c'è automatismo "arrivo a 25 -> set++ e palla al centro".
|
|
||||||
// L'utente deve cliccare "SET Antoniana" manualmente?
|
|
||||||
// Guardiamo ControllerPage.vue:
|
|
||||||
// C'è un bottone "SET {{ state.sp.nomi.home }}" che manda { type: 'incSet', team: 'home' }
|
|
||||||
|
|
||||||
// QUINDI: Il test deve:
|
|
||||||
// 1. Arrivare a 25 pt.
|
|
||||||
// 2. Cliccare "SET HOME".
|
|
||||||
// 3. Verificare che Set Home = 1.
|
|
||||||
|
|
||||||
// A 25-0 compare automaticamente il dialog "SET VINTO"
|
// A 25-0 compare automaticamente il dialog "SET VINTO"
|
||||||
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('25');
|
await expect(controllerPage.locator('.team-score.home-bg .team-pts')).toHaveText('25');
|
||||||
@@ -68,6 +18,8 @@ test.describe('Game Simulation', () => {
|
|||||||
|
|
||||||
// Procedi al set successivo: registra il set vinto da Home
|
// Procedi al set successivo: registra il set vinto da Home
|
||||||
await controllerPage.getByText('VAI AL SET SUCCESSIVO').click();
|
await controllerPage.getByText('VAI AL SET SUCCESSIVO').click();
|
||||||
|
// doNuovoSet riapre il dialog di configurazione: chiudilo
|
||||||
|
await controllerPage.locator('.dialog-config .btn-cancel').click();
|
||||||
await controllerPage.waitForTimeout(300);
|
await controllerPage.waitForTimeout(300);
|
||||||
|
|
||||||
// Verifica che il set Home sia incrementato a 1
|
// Verifica che il set Home sia incrementato a 1
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
// Helper condivisi per gli E2E.
|
||||||
|
// Nota: lo stato di gioco è UNICO e persistente sul server, quindi ogni test
|
||||||
|
// deve riportarlo a zero (resetGame) e gestire eventuali dialog rimasti aperti
|
||||||
|
// dal test precedente.
|
||||||
|
|
||||||
|
const CONTROLLER_URL = 'http://localhost:3000/controller';
|
||||||
|
const DISPLAY_URL = 'http://localhost:3000';
|
||||||
|
|
||||||
|
// Apre il controller in viewport portrait (layout "mobile", su cui si basano i
|
||||||
|
// selettori dei test) e attende la connessione WebSocket.
|
||||||
|
async function openController(context) {
|
||||||
|
const page = await context.newPage();
|
||||||
|
await page.setViewportSize({ width: 390, height: 844 });
|
||||||
|
await page.goto(CONTROLLER_URL);
|
||||||
|
await page.waitForSelector('.conn-bar.connected');
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apre il display.
|
||||||
|
async function openDisplay(context) {
|
||||||
|
const page = await context.newPage();
|
||||||
|
await page.goto(DISPLAY_URL);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chiude l'eventuale dialog di fine set / fine partita (può essersi aperto in
|
||||||
|
// automatico al caricamento se lo stato persistito era già "vinto").
|
||||||
|
async function chiudiDialogVittoria(page) {
|
||||||
|
if (await page.locator('.dialog-winner').isVisible().catch(() => false)) {
|
||||||
|
const chiudi = page.getByRole('button', { name: 'CHIUDI' });
|
||||||
|
if (await chiudi.isVisible().catch(() => false)) {
|
||||||
|
await chiudi.click();
|
||||||
|
} else {
|
||||||
|
await page.getByText('INDIETRO').click();
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(150);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset completo dello stato dal controller:
|
||||||
|
// 1) chiude un eventuale dialog di vittoria, 2) azzera, 3) nel dialog di
|
||||||
|
// configurazione che doReset riapre, reimposta nomi di default e conferma.
|
||||||
|
// Reimpostare i nomi rende lo stato deterministico (lo stato è condiviso e
|
||||||
|
// persistente: senza questo i nomi di un test precedente "sporcano" gli altri,
|
||||||
|
// in particolare gli screenshot di visual-regression).
|
||||||
|
async function resetGame(page) {
|
||||||
|
await chiudiDialogVittoria(page);
|
||||||
|
await page.getByText(/Reset/i).first().click();
|
||||||
|
const btnConfirm = page.locator('.dialog .btn-confirm');
|
||||||
|
if (await btnConfirm.isVisible().catch(() => false)) {
|
||||||
|
await btnConfirm.click();
|
||||||
|
}
|
||||||
|
const cfg = page.locator('.dialog-config');
|
||||||
|
if (await cfg.isVisible().catch(() => false)) {
|
||||||
|
const inputs = page.locator('.dialog-config .input-field');
|
||||||
|
await inputs.first().fill('Antoniana');
|
||||||
|
await inputs.nth(1).fill('Guest');
|
||||||
|
await page.locator('.dialog-config .btn-confirm').click();
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Incrementa N punti per una squadra cliccando il punteggio.
|
||||||
|
async function addPoints(page, team, count) {
|
||||||
|
const selector = team === 'home' ? '.team-score.home-bg' : '.team-score.guest-bg';
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
await page.locator(selector).click();
|
||||||
|
await page.waitForTimeout(30);
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
CONTROLLER_URL,
|
||||||
|
DISPLAY_URL,
|
||||||
|
openController,
|
||||||
|
openDisplay,
|
||||||
|
chiudiDialogVittoria,
|
||||||
|
resetGame,
|
||||||
|
addPoints,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user