Add an own-HTML block, and build the DEEG offers page on the embed block
Umut asked for a block that takes custom HTML, and for an iframe on a new DEEG offers page. Only one of those was missing. New core block "Eigenes HTML" (document schema v24): one property, the markup, up to 20.000 characters, written to the page unchanged. Changing it is reserved for administrators and compared against what is stored - on saving, on saving an area, and on restoring an older revision - exactly like an own script. <script> and <iframe> are refused with the way to the right place instead of being swallowed by the content security policy: scripts belong in the script field, frames in the "Externer Inhalt" block, because only that one asks for consent and puts the host into frame-src (ADR 106). DEEG: /angebote existed as a draft with placeholder text. It is now built like the legal pages - small caps line, large light heading, lead on the tinted band - with the IS24 result list below it and a line pointing to the portal and to the contact form. Navigation and the offers band on the home page point there. The consent question is switched on, so the frame loads only after the visitor agrees, and both the banner and the placeholder carry the site's own shapes and colours. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6b1aa50d02
commit
59a40157a4
15 files changed
+465
-8
No files matched your search
@@ -940,6 +940,48 @@ try {
|
||||
await page.locator('.notice.ok').waitFor();
|
||||
checks.push({ name: 'plugin switched on, block inserted from the toolbox, schema panel, assets on the public page, switched off keeps the block', passed: true });
|
||||
|
||||
// --- Der Baustein „Eigenes HTML“ (ADR 106) -------------------------------------------------
|
||||
// Markup des Betreibers, unveraendert bis auf die oeffentliche Seite. Geprueft wird der Weg,
|
||||
// den ein Administrator geht: einfuegen, eintippen, Vorschau, veroeffentlichen - und dass
|
||||
// <script> und <iframe> mit einer Meldung abgewiesen werden statt still zu verschwinden.
|
||||
await page.goto(origin + '/admin/pages/test-home');
|
||||
await treeSelect('headline');
|
||||
await addFromLibrary('[data-add="html"]');
|
||||
await page.locator('#properties-title').filter({ hasText: 'Eigenes HTML' }).waitFor();
|
||||
await page.getByLabel('HTML', { exact: true }).fill('<table class="preise"><tbody><tr><td>Miete</td><td>ab 8 €/m²</td></tr></tbody></table>');
|
||||
// Erst der Fokuswechsel schickt den Wert ins Dokument; die Vorschau folgt kurz darauf.
|
||||
await page.locator('#preview-status').click();
|
||||
await page.waitForFunction(() => Boolean(document.querySelector('#preview').contentDocument.querySelector('.block-html table.preise')), null, { timeout: 20000 });
|
||||
await page.locator('#save').click();
|
||||
await page.locator('#save-status').filter({ hasText: 'Entwurf gespeichert' }).waitFor();
|
||||
await page.locator('#publish').click(); await page.locator('#confirm-publish').click();
|
||||
await page.locator('#save-status').filter({ hasText: 'Veröffentlicht' }).waitFor();
|
||||
{
|
||||
const html = await (await page.request.get(origin + '/')).text();
|
||||
assert.match(html, /class="block-html"><table class="preise">/, 'Eigenes HTML unverändert auf der Website');
|
||||
// Der Baustein selbst bringt kein Skript auf die Seite - die Tabelle steht da, wie sie
|
||||
// eingegeben wurde, und sonst nichts. (Dass eine Seite ohne Skript weiterhin
|
||||
// script-src 'none' sendet, prüft CmsTest; hier trägt das Plugin von vorhin schon eines bei.)
|
||||
assert.equal(html.includes('<table class="preise"><tbody><tr><td>Miete</td>'), true, 'Markup Zeichen für Zeichen');
|
||||
}
|
||||
for (const [markup, meldung] of [
|
||||
['<script>alert(1)</script>', /Eigenes HTML führt keine Skripte aus/],
|
||||
['<iframe src="https://example.com"></iframe>', /Externer Inhalt/],
|
||||
]) {
|
||||
await page.getByLabel('HTML', { exact: true }).fill(markup);
|
||||
await page.locator('#preview-status').click();
|
||||
await page.locator('#save').click();
|
||||
// Abgewiesen wird schon die Vorschau, und das Speichern meldet es in der Leiste über dem
|
||||
// Editor - die Seite bleibt, wie sie veröffentlicht ist.
|
||||
await page.locator('#message').filter({ hasText: meldung }).waitFor();
|
||||
}
|
||||
await page.getByLabel('HTML', { exact: true }).fill('<p class="notiz">Wieder gut.</p>');
|
||||
await page.locator('#preview-status').click();
|
||||
await page.locator('#save').click();
|
||||
await page.locator('#save-status').filter({ hasText: 'Entwurf gespeichert' }).waitFor();
|
||||
await page.screenshot({ path: 'reports/editor/own-html.png', fullPage: true });
|
||||
checks.push({ name: 'own HTML block: inserted, previewed, published unchanged, script and iframe refused', passed: true });
|
||||
|
||||
// Every management screen, not just the page list: they carry tables, disclosures and now the
|
||||
// media grid, and none of that was ever checked automatically before.
|
||||
for (const [name, path] of [
|
||||
|
||||
Reference in new issue
Block a user