Files
bakery-ia/frontend/tests/operations/add-product.spec.ts

213 lines
7.0 KiB
TypeScript
Raw Permalink Normal View History

2025-11-14 07:46:29 +01:00
import { test, expect } from '@playwright/test';
2025-11-15 21:21:06 +01:00
import { generateTestId, acceptCookieConsent } from '../helpers/utils';
2025-11-14 07:46:29 +01:00
test.describe('Add New Product/Recipe', () => {
// Use authenticated state
test.use({ storageState: 'tests/.auth/user.json' });
2025-11-15 21:21:06 +01:00
test.beforeEach(async ({ page }) => {
// Accept cookie consent if present
await acceptCookieConsent(page);
});
2025-11-14 07:46:29 +01:00
test('should open Add wizard from dashboard', async ({ page }) => {
await page.goto('/app/dashboard');
2025-11-15 21:21:06 +01:00
await acceptCookieConsent(page);
2025-11-14 07:46:29 +01:00
// 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');
}
}
}
});
});