- Unit (12+9): conversion.js (rawToCooked/cookedToRaw, edge case, inversa) e storage.js (save/load, round-trip, default fallback) - Integration (17+12+14): Converter (ricerca, selezione, calcolo, swap, reset), MealPlanner (rendering, add/remove, generateShopping, deduplicazione), ShoppingList (add, toggle, remove, clearAll, contatore) - E2E Playwright (6+6+7+10): navigation, meal-planner, converter, shopping-list - Configurazione: vitest.config.js + playwright.config.js + tests/setup.js - Script: test, test:coverage, test:e2e, test:e2e:ui Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
79 lines
3.0 KiB
JavaScript
79 lines
3.0 KiB
JavaScript
import { test, expect } from '@playwright/test'
|
||
|
||
test.describe('Piano Pasti', () => {
|
||
test.beforeEach(async ({ page }) => {
|
||
// Pulisce localStorage per partire da uno stato noto
|
||
await page.goto('/')
|
||
await page.evaluate(() => localStorage.clear())
|
||
await page.reload()
|
||
})
|
||
|
||
test('mostra 7 card giornaliere', async ({ page }) => {
|
||
const cards = page.locator('.meal-card')
|
||
await expect(cards).toHaveCount(7)
|
||
})
|
||
|
||
test('il giorno corrente è espanso di default', async ({ page }) => {
|
||
// Almeno una card deve essere aperta (class "open")
|
||
await expect(page.locator('.meal-card.open')).toHaveCount(1)
|
||
})
|
||
|
||
test('si può espandere e chiudere una card con tap', async ({ page }) => {
|
||
const firstHeader = page.locator('.card-header').first()
|
||
const firstCard = page.locator('.meal-card').first()
|
||
|
||
// Se la prima card è già aperta, chiudila prima
|
||
const isOpen = await firstCard.evaluate(el => el.classList.contains('open'))
|
||
await firstHeader.click()
|
||
if (isOpen) {
|
||
await expect(firstCard).not.toHaveClass(/open/)
|
||
} else {
|
||
await expect(firstCard).toHaveClass(/open/)
|
||
}
|
||
})
|
||
|
||
test('aggiunge un alimento al pranzo del giorno corrente', async ({ page }) => {
|
||
const openCard = page.locator('.meal-card.open')
|
||
const pranzoInput = openCard.locator('.meal-slot').nth(1).locator('input[type="text"]')
|
||
await pranzoInput.fill('pasta al pomodoro')
|
||
await pranzoInput.press('Enter')
|
||
|
||
await expect(openCard.locator('.item-text', { hasText: 'pasta al pomodoro' })).toBeVisible()
|
||
})
|
||
|
||
test('rimuove un alimento con il pulsante ×', async ({ page }) => {
|
||
const openCard = page.locator('.meal-card.open')
|
||
const pranzoInput = openCard.locator('.meal-slot').nth(1).locator('input[type="text"]')
|
||
await pranzoInput.fill('riso')
|
||
await pranzoInput.press('Enter')
|
||
|
||
const itemRow = openCard.locator('.item-row', { hasText: 'riso' })
|
||
await expect(itemRow).toBeVisible()
|
||
await itemRow.locator('.btn-remove').click()
|
||
await expect(itemRow).not.toBeVisible()
|
||
})
|
||
|
||
test('genera la lista della spesa e passa alla tab Spesa', async ({ page }) => {
|
||
const openCard = page.locator('.meal-card.open')
|
||
const cenahInput = openCard.locator('.meal-slot').nth(2).locator('input[type="text"]')
|
||
await cenahInput.fill('pollo')
|
||
await cenahInput.press('Enter')
|
||
|
||
await page.locator('.btn-generate').click()
|
||
|
||
// Deve essere passato alla tab Spesa
|
||
await expect(page.locator('.page-title')).toContainText('Lista della spesa')
|
||
await expect(page.locator('.item-name', { hasText: 'pollo' })).toBeVisible()
|
||
})
|
||
|
||
test('i dati persistono dopo il reload', async ({ page }) => {
|
||
const openCard = page.locator('.meal-card.open')
|
||
const colazioneInput = openCard.locator('.meal-slot').first().locator('input[type="text"]')
|
||
await colazioneInput.fill('caffè')
|
||
await colazioneInput.press('Enter')
|
||
|
||
await page.reload()
|
||
await expect(page.locator('.meal-card.open .item-text', { hasText: 'caffè' })).toBeVisible()
|
||
})
|
||
})
|