Files
Luncher/e2e/tests/pizza-day.spec.ts
T
batmanisko fe6bb3290e
ci/woodpecker/push/workflow Pipeline was canceled
ci/woodpecker/pr/workflow Pipeline was canceled
feat: přidání testů – Jest unit testy + Playwright E2E + CI pipeline
Server:
- Jest unit testy (88 testů): auth, utils, restaurants, service, voting, pizza
- in-memory storage mock pro izolaci testů
- oprava race condition při inicializaci Redis (storageReady promise)
- dev route dostupná i pro NODE_ENV=test
- getStatsMock deterministický (nahrazení Math.random)
- exporty interních helperů pro testovatelnost
- /api/health endpoint pro Playwright readiness check
- tsconfig vylučuje test soubory z produkčního buildu

E2E (e2e/):
- Playwright s Firefoxem + Chromiem
- testy: login, menu, výběr jídla, pizza day životní cyklus, QR/nastavení
- trusted-header auth bypass pro testy, video + trace při selhání

CI (Woodpecker):
- pipeline spouštěna na všech větvích a PR (nejen master)
- redis-stack-server service pro E2E – čistý Redis per větev automaticky
- kroky: unit testy, build, E2E testy (parallel kde možné)
- Docker build zůstává pouze pro master

Co-Authored-By: Claude Opus (extra usage) 4.7 <noreply@anthropic.com>
2026-04-29 00:25:22 +02:00

66 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test';
// Pizza day testy musí běžet sekvenčně (sdílejí stav mock dne)
test.describe.serial('pizza day životní cyklus', () => {
test.beforeEach(async ({ request }) => {
// Vyčistíme data mock dne před každým testem
await request.post('/api/dev/clear', { data: { dayIndex: 4 } });
});
test('zobrazí sekci Pizza Day bez aktivního dne', async ({ page }) => {
await page.goto('/');
await page.waitForLoadState('networkidle');
const pizzaSection = page.locator('.pizza-section');
await expect(pizzaSection).toBeVisible({ timeout: 10_000 });
await expect(pizzaSection.locator('text=není aktuálně založen')).toBeVisible();
});
test('vytvoří, uzamkne a dokončí pizza day', async ({ page }) => {
await page.goto('/');
await page.waitForLoadState('networkidle');
// --- CREATED ---
const createBtn = page.locator('.pizza-section button', { hasText: 'Založit Pizza day' });
await expect(createBtn).toBeVisible({ timeout: 10_000 });
await createBtn.click();
await page.waitForLoadState('networkidle');
await expect(page.locator('.pizza-section')).toContainText('spravován uživatelem', { timeout: 5_000 });
// Přidáme pizzu přes API (obejde komplex SelectSearch)
const token = await page.evaluate(() => localStorage.getItem('token'));
const addResp = await page.request.post('/api/pizza/add', {
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
data: { pizzaIndex: 0, pizzaSizeIndex: 0 },
});
expect(addResp.ok()).toBeTruthy();
// Reload server aktualizoval data přes WebSocket, ale reload je jistější
await page.reload();
await page.waitForLoadState('networkidle');
// --- LOCK ---
const lockBtn = page.locator('.pizza-section button', { hasText: 'Uzamknout' });
await expect(lockBtn).toBeEnabled({ timeout: 5_000 });
await lockBtn.click();
await page.waitForLoadState('networkidle');
await expect(page.locator('.pizza-section')).toContainText('uzamčeny', { timeout: 5_000 });
// --- ORDERED ---
const orderBtn = page.locator('.pizza-section button', { hasText: 'Objednáno' });
await expect(orderBtn).toBeEnabled({ timeout: 5_000 });
await orderBtn.click();
await page.waitForLoadState('networkidle');
await expect(page.locator('.pizza-section')).toContainText('objednány', { timeout: 5_000 });
// --- DELIVERED ---
const deliverBtn = page.locator('.pizza-section button', { hasText: 'Doručeno' });
await expect(deliverBtn).toBeVisible({ timeout: 5_000 });
// window.confirm dialog Playwright automaticky potvrdí
page.on('dialog', dialog => dialog.accept());
await deliverBtn.click();
await page.waitForLoadState('networkidle');
await expect(page.locator('.pizza-section')).toContainText('doručeny', { timeout: 5_000 });
});
});