Release 0.4.0
This commit is contained in:
1 parent
7590be66a5
commit
4042fe6a64
24 files changed
+3570
-290
No files matched your search
+142
-7
@@ -37,6 +37,12 @@ async function login(page: Page, email = adminEmail, password = adminPassword) {
|
||||
await expect(page).toHaveURL(/\/fundus$/);
|
||||
}
|
||||
|
||||
async function openSeededShow(page: Page) {
|
||||
await page.goto('/sendungen');
|
||||
await page.getByRole('link', { name: /Herbstsendung: Kleine Welten/ }).click();
|
||||
await expect(page).toHaveURL(/\/sendungen\/show-october$/);
|
||||
}
|
||||
|
||||
function latestMailLink(subject: string): string {
|
||||
const outbox = process.env.SENDEWERK_E2E_OUTBOX_DIR;
|
||||
if (!outbox) throw new Error('E2E-Outbox ist nicht konfiguriert.');
|
||||
@@ -203,11 +209,10 @@ test('desktop builder keeps the fundus beside the wider run sheet', async ({ pag
|
||||
await page.setViewportSize({ width: 1280, height: 900 });
|
||||
await page.goto('/fundus');
|
||||
await setTheme(page, 'dark');
|
||||
await page.goto('/sendungen');
|
||||
await openSeededShow(page);
|
||||
|
||||
await expect(page.locator('html')).toHaveAttribute('data-theme', 'dark');
|
||||
await expect(page.getByRole('heading', { name: 'Sendungen', exact: true })).toBeVisible();
|
||||
await expect(page.getByText('Herbstsendung: Kleine Welten', { exact: true })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: 'Herbstsendung: Kleine Welten' })).toBeVisible();
|
||||
await expect(page.locator('.source-pane')).toBeVisible();
|
||||
await expect(page.locator('.run-pane')).toBeVisible();
|
||||
await expect(page.locator('.mobile-pane-switch')).toBeHidden();
|
||||
@@ -228,7 +233,7 @@ test('desktop builder keeps the fundus beside the wider run sheet', async ({ pag
|
||||
|
||||
test('narrow desktop retains the sidebar and switches the builder panes', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 960, height: 850 });
|
||||
await page.goto('/sendungen');
|
||||
await openSeededShow(page);
|
||||
|
||||
await expect(page.locator('.sidebar')).toBeVisible();
|
||||
await expect(page.locator('.mobile-navigation')).toBeHidden();
|
||||
@@ -246,7 +251,7 @@ test('mobile and tablet navigation do not obscure switchable content', async ({
|
||||
}, testInfo) => {
|
||||
for (const width of [390, 768]) {
|
||||
await page.setViewportSize({ width, height: 900 });
|
||||
await page.goto('/sendungen');
|
||||
await openSeededShow(page);
|
||||
|
||||
await expect(page.locator('.sidebar')).toBeHidden();
|
||||
await expect(page.locator('.mobile-navigation')).toBeVisible();
|
||||
@@ -266,10 +271,139 @@ test('mobile and tablet navigation do not obscure switchable content', async ({
|
||||
}
|
||||
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
await page.goto('/sendungen');
|
||||
await openSeededShow(page);
|
||||
await page.screenshot({ path: testInfo.outputPath('sendungen-mobile.png'), fullPage: true });
|
||||
});
|
||||
|
||||
test('a show can be planned from a template with independent usages and reserve', async ({
|
||||
page
|
||||
}, testInfo) => {
|
||||
await page.setViewportSize({ width: 1440, height: 1000 });
|
||||
await page.goto('/sendungen');
|
||||
await page.getByLabel('Titel').fill('E2E Planung Spiele und JC');
|
||||
await page.getByLabel('Ausgangspunkt').selectOption('template-default');
|
||||
await page.getByRole('button', { name: 'Sendung anlegen' }).click();
|
||||
await expect(page).toHaveURL(/\/sendungen\/[a-f0-9-]+$/);
|
||||
const showUrl = page.url();
|
||||
await expect(page.locator('.run-section')).toHaveCount(5);
|
||||
const firstSection = page.locator('.run-section').first();
|
||||
const sectionTransfer = await page.evaluateHandle(() => new DataTransfer());
|
||||
await firstSection.locator('.section-drag-handle').dispatchEvent('dragstart', {
|
||||
dataTransfer: sectionTransfer
|
||||
});
|
||||
await page.locator('.run-section').nth(1).dispatchEvent('dragover', {
|
||||
dataTransfer: sectionTransfer
|
||||
});
|
||||
await expect(page.locator('[data-drop-preview="section"]')).toContainText('Start');
|
||||
await expect(firstSection).toHaveClass(/is-dragging/);
|
||||
await firstSection.locator('.section-drag-handle').dispatchEvent('dragend', {
|
||||
dataTransfer: sectionTransfer
|
||||
});
|
||||
await sectionTransfer.dispose();
|
||||
await expect(page.locator('[data-drop-preview="section"]')).toHaveCount(0);
|
||||
|
||||
await page.getByPlaceholder('Fundus durchsuchen').fill('kleine Konsole');
|
||||
await page.getByRole('button', { name: 'Filtern' }).click();
|
||||
const source = page
|
||||
.locator('.builder-source-card')
|
||||
.filter({ hasText: 'Die kleine Konsole mit dem großen Dreh' });
|
||||
await expect(page.locator('.builder-source-card')).toHaveCount(1);
|
||||
const reactionSection = page
|
||||
.locator('.run-section')
|
||||
.filter({ has: page.getByRole('heading', { name: 'JC / Reaction' }) });
|
||||
await page.locator('body').evaluate((body) => (body.dataset.builderDocument = 'stable'));
|
||||
const sourceDragHandle = source.locator('.source-drag-copy');
|
||||
const emptyReactionTarget = reactionSection.locator('.section-placeholder');
|
||||
const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
|
||||
await sourceDragHandle.dispatchEvent('dragstart', { dataTransfer });
|
||||
await emptyReactionTarget.dispatchEvent('dragover', { dataTransfer });
|
||||
const insertionPreview = reactionSection.locator('[data-drop-preview="usage"]');
|
||||
await expect(insertionPreview).toContainText('Die kleine Konsole mit dem großen Dreh');
|
||||
await expect(source).toHaveClass(/is-dragging/);
|
||||
await expect(source).toHaveCSS('opacity', '0.45');
|
||||
await emptyReactionTarget.dispatchEvent('drop', { dataTransfer });
|
||||
await sourceDragHandle.dispatchEvent('dragend', { dataTransfer });
|
||||
await dataTransfer.dispose();
|
||||
await expect(reactionSection.locator('.editable-usage')).toHaveCount(1);
|
||||
await expect(page.locator('body')).toHaveAttribute('data-builder-document', 'stable');
|
||||
await sourceDragHandle.dragTo(reactionSection.locator('.editable-usage'));
|
||||
|
||||
let usages = page
|
||||
.locator('.run-section')
|
||||
.filter({ has: page.getByRole('heading', { name: 'JC / Reaction' }) })
|
||||
.locator('.editable-usage');
|
||||
await expect(usages).toHaveCount(2);
|
||||
await usages.nth(0).locator('summary').click();
|
||||
await usages.nth(0).getByLabel('Titel').fill('Konsole als Auftakt');
|
||||
await usages.nth(0).getByLabel('Dauer in Minuten').fill('5');
|
||||
await usages.nth(0).getByLabel('Eigene Notizen').fill('Kurbel zuerst zeigen');
|
||||
await usages.nth(0).getByRole('button', { name: 'Verwendung speichern' }).click();
|
||||
await expect(reactionSection).toContainText('Konsole als Auftakt');
|
||||
|
||||
usages = page
|
||||
.locator('.run-section')
|
||||
.filter({ has: page.getByRole('heading', { name: 'JC / Reaction' }) })
|
||||
.locator('.editable-usage');
|
||||
await usages.nth(1).locator('summary').click();
|
||||
await usages.nth(1).getByLabel('Titel').fill('Konsole als Rückblick');
|
||||
await usages.nth(1).getByLabel('Dauer in Minuten').fill('15');
|
||||
await usages.nth(1).getByLabel('Eigene Notizen').fill('Andere Perspektive');
|
||||
await usages.nth(1).getByRole('button', { name: 'Verwendung speichern' }).click();
|
||||
await expect(page.locator('.show-summary')).toContainText('2 Std. 25 Min.');
|
||||
|
||||
const planTimeBeforeReserve = await page.locator('.show-summary').textContent();
|
||||
await source.getByLabel(/Ziel für/).selectOption('');
|
||||
await source.getByRole('button', { name: 'Hinzufügen' }).click();
|
||||
await expect(page.locator('.reserve-usage')).toHaveCount(1);
|
||||
expect(await page.locator('.show-summary').textContent()).toBe(planTimeBeforeReserve);
|
||||
|
||||
const moveUp = page.getByRole('button', { name: 'Konsole als Rückblick nach oben' });
|
||||
await moveUp.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
await expect(
|
||||
page
|
||||
.locator('.run-section')
|
||||
.filter({ has: page.getByRole('heading', { name: 'JC / Reaction' }) })
|
||||
.locator('.editable-usage strong')
|
||||
.first()
|
||||
).toHaveText('Konsole als Rückblick');
|
||||
|
||||
const reserveUsage = page.locator('.reserve-usage');
|
||||
const reserveHandle = reserveUsage.locator('.usage-drag-copy');
|
||||
const finalSectionTarget = page.locator('.run-section').last().locator('.section-placeholder');
|
||||
const reserveTransfer = await page.evaluateHandle(() => new DataTransfer());
|
||||
await reserveHandle.dispatchEvent('dragstart', { dataTransfer: reserveTransfer });
|
||||
await finalSectionTarget.dispatchEvent('dragover', { dataTransfer: reserveTransfer });
|
||||
await expect(page.locator('[data-drop-preview="usage"]')).toContainText(
|
||||
'Die kleine Konsole mit dem großen Dreh'
|
||||
);
|
||||
await expect(reserveUsage).toHaveClass(/is-dragging/);
|
||||
await finalSectionTarget.dispatchEvent('drop', { dataTransfer: reserveTransfer });
|
||||
await reserveHandle.dispatchEvent('dragend', { dataTransfer: reserveTransfer });
|
||||
await reserveTransfer.dispose();
|
||||
await expect(page.locator('.reserve-usage')).toHaveCount(0);
|
||||
await expect(page.locator('body')).toHaveAttribute('data-builder-document', 'stable');
|
||||
await page.reload();
|
||||
await expect(page.locator('.editable-usage')).toHaveCount(3);
|
||||
const savedUsage = page.locator('.editable-usage').filter({ hasText: 'Konsole als Auftakt' });
|
||||
await savedUsage.locator('summary').click();
|
||||
await expect(savedUsage.getByLabel('Eigene Notizen')).toHaveValue('Kurbel zuerst zeigen');
|
||||
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
await page.getByRole('button', { name: 'Ablauf', exact: true }).click();
|
||||
await page.getByPlaceholder('Neuer Abschnitt').fill('Finales Spiel');
|
||||
await page.getByRole('button', { name: 'Abschnitt hinzufügen' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Finales Spiel' })).toBeVisible();
|
||||
await expectNoHorizontalOverflow(page);
|
||||
await page.screenshot({ path: testInfo.outputPath('sendungsbau-mobile.png'), fullPage: true });
|
||||
|
||||
await page.goto('/fundus?q=kleine+Konsole');
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Die kleine Konsole mit dem großen Dreh' })
|
||||
).toBeVisible();
|
||||
await page.goto(showUrl);
|
||||
});
|
||||
|
||||
test('all work areas fit at required widths in light and dark mode', async ({ page }, testInfo) => {
|
||||
for (const viewport of viewports) {
|
||||
await page.setViewportSize({ width: viewport.width, height: viewport.height });
|
||||
@@ -391,7 +525,7 @@ test('pieces autosave safely, detect conflicts and protect uploaded images', asy
|
||||
.getByLabel('Kurzbeschreibung')
|
||||
.fill('Persistiert nach Neuladen und ist gezielt suchbar.');
|
||||
await page.getByLabel('Status').selectOption('ready');
|
||||
await page.getByLabel('Dauer in Sekunden').fill('615');
|
||||
await page.getByLabel('Dauer in Minuten').fill('10.25');
|
||||
await page.getByLabel('Gaming').check();
|
||||
await page.getByLabel('Private Recherche').fill('Nur intern: **Hintergrund prüfen**.');
|
||||
await page
|
||||
@@ -409,6 +543,7 @@ test('pieces autosave safely, detect conflicts and protect uploaded images', asy
|
||||
await expect(page.locator('.markdown-preview').last()).toContainText('Sichere Vorschau');
|
||||
await page.reload();
|
||||
await expect(page.getByLabel('Titel')).toHaveValue('E2E Fundstück mit Markdown');
|
||||
await expect(page.getByLabel('Dauer in Minuten')).toHaveValue('10.25');
|
||||
await expect(page.getByLabel('Private Recherche')).toHaveValue(
|
||||
'Nur intern: **Hintergrund prüfen**.'
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user