- 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>
90 lines
3.5 KiB
JavaScript
90 lines
3.5 KiB
JavaScript
import { test, expect } from '@playwright/test'
|
||
|
||
test.describe('Lista della spesa', () => {
|
||
test.beforeEach(async ({ page }) => {
|
||
await page.goto('/')
|
||
await page.evaluate(() => localStorage.clear())
|
||
await page.locator('.nav-btn', { hasText: 'Spesa' }).click()
|
||
})
|
||
|
||
test('mostra stato vuoto con lista vuota', async ({ page }) => {
|
||
await expect(page.locator('.empty-state')).toBeVisible()
|
||
})
|
||
|
||
test('aggiunge un elemento tramite il pulsante +', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('latte')
|
||
await page.locator('.btn-add').click()
|
||
await expect(page.locator('.item-name', { hasText: 'latte' })).toBeVisible()
|
||
})
|
||
|
||
test('aggiunge un elemento con il tasto Invio', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('burro')
|
||
await page.locator('input[type="text"]').press('Enter')
|
||
await expect(page.locator('.item-name', { hasText: 'burro' })).toBeVisible()
|
||
})
|
||
|
||
test('svuota il campo dopo l\'aggiunta', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('olio')
|
||
await page.locator('.btn-add').click()
|
||
await expect(page.locator('input[type="text"]')).toHaveValue('')
|
||
})
|
||
|
||
test('spunta un elemento e lo sposta nei completati', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('pasta')
|
||
await page.locator('.btn-add').click()
|
||
|
||
await page.locator('.checkbox-item').first().locator('input[type="checkbox"]').click()
|
||
await expect(page.locator('.section-divider')).toBeVisible()
|
||
await expect(page.locator('.muted .item-name', { hasText: 'pasta' })).toBeVisible()
|
||
})
|
||
|
||
test('rimuove un singolo elemento con ×', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('farina')
|
||
await page.locator('.btn-add').click()
|
||
await page.locator('.checkbox-item').first().locator('.btn-remove').click()
|
||
await expect(page.locator('.item-name', { hasText: 'farina' })).not.toBeVisible()
|
||
await expect(page.locator('.empty-state')).toBeVisible()
|
||
})
|
||
|
||
test('svuota lista con conferma del dialog', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('test')
|
||
await page.locator('.btn-add').click()
|
||
|
||
page.once('dialog', dialog => dialog.accept())
|
||
await page.locator('.btn-clear').click()
|
||
|
||
await expect(page.locator('.empty-state')).toBeVisible()
|
||
})
|
||
|
||
test('non svuota lista se si annulla il dialog', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('test')
|
||
await page.locator('.btn-add').click()
|
||
|
||
page.once('dialog', dialog => dialog.dismiss())
|
||
await page.locator('.btn-clear').click()
|
||
|
||
await expect(page.locator('.item-name', { hasText: 'test' })).toBeVisible()
|
||
})
|
||
|
||
test('il contatore mostra elementi completati / totale', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('a')
|
||
await page.locator('.btn-add').click()
|
||
await page.locator('input[type="text"]').fill('b')
|
||
await page.locator('.btn-add').click()
|
||
|
||
await page.locator('.checkbox-item').first().locator('input[type="checkbox"]').click()
|
||
const subtitle = await page.locator('.page-subtitle').textContent()
|
||
expect(subtitle).toMatch(/1/)
|
||
expect(subtitle).toMatch(/2/)
|
||
})
|
||
|
||
test('i dati persistono dopo il reload', async ({ page }) => {
|
||
await page.locator('input[type="text"]').fill('yogurt')
|
||
await page.locator('.btn-add').click()
|
||
|
||
await page.reload()
|
||
await page.locator('.nav-btn', { hasText: 'Spesa' }).click()
|
||
await expect(page.locator('.item-name', { hasText: 'yogurt' })).toBeVisible()
|
||
})
|
||
})
|