98 lines
5.5 KiB
TypeScript
98 lines
5.5 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
||
import { readFile } from 'node:fs/promises';
|
||
import { exportRecipes } from '../../src/lib/import';
|
||
import { pasta } from '../fixtures';
|
||
test('admin creates and edits recipes with recoverable drafts and image upload', async ({
|
||
page,
|
||
}) => {
|
||
await page.goto('/admin');
|
||
await page.getByRole('textbox', { name: 'Benutzername' }).fill('testadmin');
|
||
await page.getByLabel('Passwort', { exact: true }).fill(process.env.TEST_PASSWORD!);
|
||
await page.getByRole('button', { name: 'Anmelden', exact: true }).click();
|
||
await expect(page.getByRole('heading', { name: 'Hallo, testadmin.' })).toBeVisible();
|
||
await page.getByRole('link', { name: 'Neues Rezept' }).click();
|
||
await page
|
||
.getByRole('textbox', { name: 'Rezepttitel', exact: true })
|
||
.fill('Browser-Küchenrezept');
|
||
await page
|
||
.getByRole('textbox', { name: 'Beschreibung', exact: true })
|
||
.fill('Ein echtes Rezept aus dem grafischen Editor.');
|
||
page.on('dialog', (d) => d.accept());
|
||
await page.reload();
|
||
await expect(page.getByRole('textbox', { name: 'Rezepttitel', exact: true })).toHaveValue(
|
||
'Browser-Küchenrezept',
|
||
);
|
||
await page.getByLabel('Titelbild hochladen').setInputFiles('public/images/garden.jpg');
|
||
await expect(page.getByRole('img', { name: 'Titelbild', exact: true })).toBeVisible();
|
||
await page.getByRole('checkbox', { name: /Rezept veröffentlichen/ }).check();
|
||
await page.getByRole('button', { name: 'Zutaten', exact: true }).click();
|
||
await page.getByRole('textbox', { name: 'Zutat 1', exact: true }).fill('Kartoffeln');
|
||
await page.getByRole('spinbutton', { name: 'Menge 1', exact: true }).fill('400');
|
||
await page.getByRole('button', { name: 'Zutat hinzufügen' }).click();
|
||
await page.getByRole('textbox', { name: 'Zutat 2', exact: true }).fill('Salz');
|
||
await page.getByRole('combobox', { name: 'Einheit 2', exact: true }).selectOption('');
|
||
await page.getByRole('button', { name: 'Zubereitung', exact: true }).click();
|
||
await page.getByRole('textbox', { name: 'Schritttitel 1' }).fill('Kartoffeln kochen');
|
||
await page.getByRole('textbox', { name: 'Anleitung 1' }).fill('In Salzwasser weich kochen.');
|
||
await page.getByRole('button', { name: 'Kartoffeln', exact: true }).click();
|
||
await page.getByRole('button', { name: 'Timer hinzufügen' }).click();
|
||
await page.getByRole('button', { name: 'Live-Vorschau', exact: true }).click();
|
||
await expect(page.locator('.editor-preview')).toContainText('400 g Kartoffeln');
|
||
await page.screenshot({ path: 'docs/screenshots/editor-desktop.png', fullPage: true });
|
||
await page.getByRole('button', { name: 'Rezept speichern' }).click();
|
||
await expect(page).toHaveURL(/\/admin\/rezepte\/[a-f0-9-]{36}$/);
|
||
await page.getByRole('button', { name: 'Das Rezept', exact: true }).click();
|
||
await page
|
||
.getByRole('textbox', { name: 'Rezepttitel', exact: true })
|
||
.fill('Browser-Küchenrezept verbessert');
|
||
await page.getByRole('button', { name: 'Rezept speichern' }).click();
|
||
await expect(page.getByRole('status')).toContainText('erfolgreich gespeichert');
|
||
await page.goto('/admin');
|
||
await expect(
|
||
page.getByRole('heading', { name: 'Browser-Küchenrezept verbessert' }),
|
||
).toBeVisible();
|
||
const downloadPromise = page.waitForEvent('download');
|
||
await page
|
||
.getByRole('link', { name: 'Browser-Küchenrezept verbessert als JSON exportieren' })
|
||
.click();
|
||
const download = await downloadPromise;
|
||
const data = JSON.parse(await readFile((await download.path())!, 'utf8'));
|
||
expect(data.recipes[0].title).toBe('Browser-Küchenrezept verbessert');
|
||
await page.getByRole('button', { name: 'Browser-Küchenrezept verbessert löschen' }).click();
|
||
await page.getByRole('button', { name: 'Endgültig löschen' }).click();
|
||
await expect(page.getByRole('heading', { name: 'Browser-Küchenrezept verbessert' })).toHaveCount(
|
||
0,
|
||
);
|
||
await page.getByRole('button', { name: 'Abmelden' }).click();
|
||
await expect(page.getByRole('heading', { name: 'Willkommen zurück.' })).toBeVisible();
|
||
});
|
||
test('JSON and XML import with a real preview, duplicate prevention and export', async ({
|
||
page,
|
||
}) => {
|
||
await page.goto('/admin');
|
||
await page.getByLabel('Benutzername').fill('testadmin');
|
||
await page.getByLabel('Passwort', { exact: true }).fill(process.env.TEST_PASSWORD!);
|
||
await page.getByRole('button', { name: 'Anmelden', exact: true }).click();
|
||
for (const format of ['json', 'xml'] as const) {
|
||
await page.getByRole('button', { name: 'Importieren', exact: true }).click();
|
||
await page.getByLabel('Importformat').selectOption(format);
|
||
const recipe = {
|
||
...pasta,
|
||
id: undefined,
|
||
title: `Importierte ${format.toUpperCase()} Pasta`,
|
||
published: false,
|
||
};
|
||
await page.getByLabel('Rezeptdaten').fill(exportRecipes([recipe], format));
|
||
await page.getByRole('button', { name: 'Importvorschau prüfen' }).click();
|
||
await expect(page.locator('.import-preview')).toContainText(recipe.title);
|
||
await expect(page.locator('.import-preview')).toContainText('200 g Pasta');
|
||
await page.getByRole('button', { name: '1 Rezept(e) jetzt importieren' }).click();
|
||
await expect(page.getByRole('heading', { name: recipe.title })).toBeVisible();
|
||
}
|
||
await page.getByRole('button', { name: 'Importieren', exact: true }).click();
|
||
await page.getByLabel('Rezeptdaten').fill(exportRecipes([pasta], 'json'));
|
||
await page.getByRole('button', { name: 'Importvorschau prüfen' }).click();
|
||
await expect(page.getByText('Duplikat – Import gesperrt')).toBeVisible();
|
||
await expect(page.getByRole('button', { name: '1 Rezept(e) jetzt importieren' })).toBeDisabled();
|
||
});
|