Files
Luncher/e2e/tests/pick-food.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

71 lines
2.9 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';
import { clearPizzaDay } from './helpers';
test.beforeEach(async ({ page, request }) => {
// Vyčistíme volby dne, aby testy neovlivnily navzájem
await request.post('/api/dev/clear', {
data: { dayIndex: 4 },
});
await page.goto('/');
await page.waitForLoadState('networkidle');
// Počkáme, až se zobrazí volba stravování
await expect(page.locator('.choice-section select').first()).toBeVisible({ timeout: 10_000 });
});
test('výběr restaurace zobrazí seznam jídel', async ({ page }) => {
const locationSelect = page.locator('.choice-section select').first();
// Vybereme Sladovnickou mock menu existuje
await locationSelect.selectOption('SLADOVNICKA');
// Po výběru restaurace se zobrazí druhý select s jídly
const foodSelect = page.locator('.choice-section select').nth(1);
await expect(foodSelect).toBeVisible({ timeout: 5_000 });
// Select musí obsahovat alespoň 2 možnosti (empty + ≥1 jídlo)
const options = foodSelect.locator('option');
expect(await options.count()).toBeGreaterThan(1);
});
test('výběr jídla se uloží a přetrvá po reload', async ({ page }) => {
const locationSelect = page.locator('.choice-section select').first();
await locationSelect.selectOption('SLADOVNICKA');
const foodSelect = page.locator('.choice-section select').nth(1);
await expect(foodSelect).toBeVisible({ timeout: 5_000 });
// Vybereme první nenulovou možnost
const options = await foodSelect.locator('option:not([value=""])').all();
if (options.length === 0) {
test.skip(); // Mock data nejsou dostupná pro tuto restauraci
}
const firstValue = await options[0].getAttribute('value');
await foodSelect.selectOption({ value: firstValue! });
// Počkáme, až se volba přenese na server
await page.waitForLoadState('networkidle');
// Po reload musí volba přetrvat v tabulce choices
await page.reload();
await page.waitForLoadState('networkidle');
const choicesTable = page.locator('.choices-table');
await expect(choicesTable).toBeVisible({ timeout: 5_000 });
await expect(choicesTable.locator('text=Sladovnická')).toBeVisible();
});
test('přepnutí na NEOBEDVAM odstraní výběr restaurace', async ({ page }) => {
// Nejprve zvolíme restauraci
const locationSelect = page.locator('.choice-section select').first();
await locationSelect.selectOption('SLADOVNICKA');
await page.waitForLoadState('networkidle');
// Přepneme na "Neobědvám"
await locationSelect.selectOption('NEOBEDVAM');
await page.waitForLoadState('networkidle');
// Tabulka choices musí zobrazovat "Neobědvám"
const choicesTable = page.locator('.choices-table');
await expect(choicesTable).toBeVisible({ timeout: 5_000 });
await expect(choicesTable.locator('text=Neobědvám')).toBeVisible();
});