import { test, expect } from '@playwright/test'; import { generateTestId } from '../helpers/utils'; test.describe('Add New Product/Recipe', () => { // Use authenticated state test.use({ storageState: 'tests/.auth/user.json' }); test('should open Add wizard from dashboard', async ({ page }) => { await page.goto('/app/dashboard'); // Click unified Add button const addButton = page.getByRole('button', { name: /^add$|^añadir$|^\+$/i }).first(); if (await addButton.isVisible().catch(() => false)) { await addButton.click(); // Wait for wizard/modal to open await page.waitForTimeout(500); // Should show options (Recipe, Order, Production, etc.) await expect(page.locator('body')).toContainText(/recipe|receta|product|producto/i); } }); test('should successfully add a new product', async ({ page }) => { await page.goto('/app/operations/recipes'); await page.waitForLoadState('networkidle'); // Look for Add/Create button const addButton = page.getByRole('button', { name: /add|create|new|añadir|crear|nuevo/i }).first(); if (await addButton.isVisible().catch(() => false)) { await addButton.click(); await page.waitForTimeout(500); // Fill in product details const productName = `Test Product ${generateTestId()}`; const nameInput = page.getByLabel(/product.*name|name|nombre.*producto|nombre/i); if (await nameInput.isVisible().catch(() => false)) { await nameInput.fill(productName); // Fill in price const priceInput = page.getByLabel(/price|precio|cost|costo/i); if (await priceInput.isVisible().catch(() => false)) { await priceInput.fill('9.99'); } // Select category if available const categorySelect = page.getByLabel(/category|categoría|type|tipo/i); if (await categorySelect.isVisible().catch(() => false)) { await categorySelect.click(); // Select first option const firstOption = page.getByRole('option').first(); if (await firstOption.isVisible({ timeout: 2000 }).catch(() => false)) { await firstOption.click(); } } // Submit form const submitButton = page.getByRole('button', { name: /save|create|submit|guardar|crear|enviar/i }); await submitButton.click(); // Should show success message await expect(page.locator('body')).toContainText(/success|created|éxito|creado/i, { timeout: 5000, }); // Product should appear in list await expect(page.locator('body')).toContainText(productName, { timeout: 5000 }); } } }); test('should show validation errors for missing required fields', async ({ page }) => { await page.goto('/app/operations/recipes'); await page.waitForLoadState('networkidle'); // Look for Add button const addButton = page.getByRole('button', { name: /add|create|new|añadir|crear|nuevo/i }).first(); if (await addButton.isVisible().catch(() => false)) { await addButton.click(); await page.waitForTimeout(500); // Try to submit without filling fields const submitButton = page.getByRole('button', { name: /save|create|submit|guardar|crear|enviar/i }); if (await submitButton.isVisible().catch(() => false)) { await submitButton.click(); // Should show validation errors await expect(page.locator('body')).toContainText(/required|obligatorio|necesario/i, { timeout: 3000, }); } } }); test('should add ingredients to a recipe', async ({ page }) => { await page.goto('/app/operations/recipes'); await page.waitForLoadState('networkidle'); const addButton = page.getByRole('button', { name: /add|create|new|añadir|crear|nuevo/i }).first(); if (await addButton.isVisible().catch(() => false)) { await addButton.click(); await page.waitForTimeout(500); // Fill basic info const nameInput = page.getByLabel(/product.*name|name|nombre.*producto|nombre/i); if (await nameInput.isVisible().catch(() => false)) { await nameInput.fill(`Test Recipe ${generateTestId()}`); // Look for "Add Ingredient" button const addIngredientButton = page.getByRole('button', { name: /add.*ingredient|añadir.*ingrediente/i }); if (await addIngredientButton.isVisible().catch(() => false)) { await addIngredientButton.click(); // Fill ingredient details const ingredientInput = page.getByLabel(/ingredient|ingrediente/i).first(); if (await ingredientInput.isVisible().catch(() => false)) { await ingredientInput.fill('Flour'); // Fill quantity const quantityInput = page.getByLabel(/quantity|cantidad/i).first(); if (await quantityInput.isVisible().catch(() => false)) { await quantityInput.fill('500'); } // Ingredient should be added await expect(page.locator('body')).toContainText(/flour|harina/i); } } } } }); test('should upload product image', async ({ page }) => { await page.goto('/app/operations/recipes'); await page.waitForLoadState('networkidle'); const addButton = page.getByRole('button', { name: /add|create|new|añadir|crear|nuevo/i }).first(); if (await addButton.isVisible().catch(() => false)) { await addButton.click(); await page.waitForTimeout(500); // Look for file upload const fileInput = page.locator('input[type="file"]'); if (await fileInput.isVisible().catch(() => false)) { // File upload is available await expect(fileInput).toBeAttached(); } } }); test('should cancel product creation', async ({ page }) => { await page.goto('/app/operations/recipes'); await page.waitForLoadState('networkidle'); const addButton = page.getByRole('button', { name: /add|create|new|añadir|crear|nuevo/i }).first(); if (await addButton.isVisible().catch(() => false)) { await addButton.click(); await page.waitForTimeout(500); // Fill some data const nameInput = page.getByLabel(/product.*name|name|nombre.*producto|nombre/i); if (await nameInput.isVisible().catch(() => false)) { await nameInput.fill('Test Product to Cancel'); // Look for Cancel button const cancelButton = page.getByRole('button', { name: /cancel|cancelar|close|cerrar/i }); if (await cancelButton.isVisible().catch(() => false)) { await cancelButton.click(); // Should close form/modal await page.waitForTimeout(500); // Should not show the test product const bodyText = await page.locator('body').textContent(); expect(bodyText).not.toContain('Test Product to Cancel'); } } } }); });