Regressions-Register
Jeder behobene Fehler mit dem Test, der ihn festhält. Wer einen Eintrag löscht, nimmt die Absicherung mit.
REG-0024 — Jedes Modal riss fremde Auslöser an sich
Symptom. Standen zwei Modal-Blöcke auf einer Seite, öffnete ein Button den falschen Dialog — auch dann, wenn er ausdrücklich auf einen anderen eingestellt war.
Ursache. Der Block verbindet verwaiste Auslöser, deren Ziel auf der Seite fehlt, mit seinem eigenen Modal. Geprüft wurde das so:
CSS.escape maskiert alles, was kein Bezeichnerzeichen ist — auch die führende Raute. Aus #cms-modal-b wird \#cms-modal-b, und das ist kein Verweis auf eine Kennung mehr, sondern ein Elementname, den es nicht gibt. Die Abfrage lieferte also nie etwas, die Bedingung war immer wahr, und jeder Auslöser galt als verwaist.
Fix. Nur der Bezeichner wird maskiert, die Raute bleibt stehen. Zusätzlich wird ein Auslöser ohne Ziel oder ohne data-bs-toggle="modal" übersprungen, statt in die Prüfung zu laufen.
Eine Falle beim Testen, die festgehalten gehört. Der Fehler tritt in jsdom nicht auf: dessen CSS.escape gibt die Zeichenkette unverändert zurück, während ein Browser der Spezifikation folgt und maskiert. Die ersten Tests waren deshalb grün, obwohl der Defekt vorlag — sie hätten vor und nach dem Fix bestanden. Die Spec installiert nun in beforeEach eine spezifikationskonforme CSS.escape und stellt sie danach zurück. Wer diese Zeilen für überflüssig hält und entfernt, macht die Tests wieder blind.
Test. src/Resources/app/storefront/test/everything-modal.spec.ts
REG-0025 — Ein CMS-Element ohne Umsetzung stand zur Auswahl
Symptom. Im Layout-Editor ließ sich das Element »Modal Button« einfügen. Danach war es defekt.
Ursache. Das Element war beim cmsService angemeldet und verwies auf drei Komponenten — everything-modal-button-component, -config und -preview. Keine davon war je registriert, und es gab auch keine Quelldateien dafür. Shopware nimmt eine solche Anmeldung klaglos an; auffällig wird sie erst, wenn jemand das Element wählt. Selbst die Beschriftung fehlte: der Schlüssel plugin.leoparden.CmsEverythingModal.button.label stand in keiner der beiden Snippet-Dateien.
Fix. Die Anmeldung ist entfernt. Ein Element, das es nicht gibt, wird nicht angeboten. Der Test vergleicht jeden referenzierten Komponentennamen gegen die tatsächlichen Registrierungen — eine solche Lücke fällt künftig auf, statt bis in eine Auslieferung zu überleben.
Mit entfernt wurden drei Bau-Artefakte aus der Zeit vor der Präfigierung des technischen Namens (cms-everything-modal.js, dessen Karte und die zugehörige CSS-Datei). Sie wurden nie geladen — var/plugins.json führt leoparden-cms-everything-modal—, enthielten das entfernte Element aber weiterhin und wurden mit ausgeliefert. Auf dieser Linie gibt es sie nicht: der Adminbereich wird hier mit Vite gebaut, die Artefakte liegen unter assets/.
Für beide Linien gilt dasselbe: ohne Neubau wirkt das Entfernen nicht. Die eingecheckten Bündel tragen das Element sonst weiter, und im Layout-Editor bliebe es sichtbar.
Test. src/Test/CmsRegistrationTest.php
REG-0026 — Englische Beschriftung und eine Angabe an der falschen Stelle
Symptom. Das Schließen-Symbol des Dialogs trug aria-label="Close" — fest eingebautes Englisch, das ein Screenreader auch in einem deutschen Shop vorliest.
Ursache und Fix. Die Beschriftung kommt jetzt aus dem Kern-Snippet general.close.
Im selben Zug entfernt: data-bs-backdrop="false" saß am Auslöse-Button. Bootstrap liest diese Angabe am Modal, nicht am Auslöser — sie war also wirkungslos. Da der Block gar keine Backdrop-Einstellung anbietet, ist sie ersatzlos entfallen; am Verhalten ändert sich nichts.
Test. src/Test/ModalTemplateTest.php
REG-0027 — Der Schließen-Knopf hieß »general.close«, und ein Test schrieb das fest
Symptom. Eine Vorlesehilfe sagte am Schließen-Knopf des Modals wörtlich »general.close«. Bei einem Dialog ist dieser Knopf der einzige benannte Ausgang.
Ursache. Die Vorlage übersetzte 'general.close'. Diesen Schlüssel gibt es nicht — die Suche über den gesamten Schnipselbestand der Installation ergab null Treffer. Twig gibt dann den Schlüssel selbst aus. Das Plugin brachte gar keine Storefront-Schnipsel mit.
Woher er kam und was ihn am Leben hielt: REG-0026 ersetzte eine fest verdrahtete englische Beschriftung durch general.close — richtig gedacht, nur gibt es den Schlüssel nicht. ModalTemplateTest verlangte ihn danach ausdrücklich, mit der Begründung »the core has a snippet for exactly this«. Die Annahme war falsch, und der Test hat den Mangel dadurch festgeschrieben statt ihn zu fangen.
Fix. Eigene Schnipsel unter plugin.leoparden.CmsEverythingModal.close, dem Präfix, das die Administration des Plugins bereits verwendet. Der Test nennt keinen Schlüssel mehr, sondern hält jeden übersetzten Schlüssel der Vorlage gegen das, was das Plugin liefert.
Test. src/Test/ModalTemplateTest::testEveryTranslatedKeyExistsInThePluginSnippets und ::testTheSnippetsCoverBothShippedLanguages.
REG-0028 — Die Storefront-Tests liefen nur im CI-Abbild
Symptom. npm test im Storefront-Verzeichnis brach lokal ab: »Test suite failed to run«, Cannot find module 'src/plugin-system/plugin.class', daraus folgend ein Dutzend Typfehler. Null Tests wurden ausgeführt — auf beiden Linien.
Ursache. tsconfig.json verwies fest auf /opt/shopware/…, den Pfad im CI-Abbild. Dort stimmt er, deshalb war die Pipeline grün und niemandem fiel etwas auf; lokal gab es keine Rückmeldung aus diesen Tests. Die jest.config.js daneben war für genau dieses Problem bereits repariert worden — sie sucht beide Layouts —, die tsconfig.json blieb dabei liegen. Eine halbe Reparatur, die dadurch wirkungslos war.
Fix. Jeder betroffene paths-Eintrag führt jetzt beide Möglichkeiten: den Pfad des CI-Abbilds zuerst, danach den der Produktionsvorlage. TypeScript nimmt den ersten, den es findet.
Test. Die Suite selbst — sie führt jetzt ihre drei Tests aus statt abzubrechen.
REG-0029 — Die Deinstallation ließ platzierte Blöcke stehen
Symptom. Wurde das Plugin entfernt, blieben seine Blöcke in den Layouts liegen. Der Shop brach dadurch nicht — der Kern bindet Blockvorlagen mit ignore missing ein, ein verwaister Block stellt also nichts dar. Er saß aber als unsichtbare Lücke im Layout und tauchte bei einer Neuinstallation wieder auf.
Ursache. Die Plugin-Klasse war leer: keine uninstall(), keine Migration, kein PHP, das je etwas anlegte. Block und Element werden im Admin-JavaScript registriert; die Zeilen in cms_block entstehen erst, wenn ein Händler den Block platziert — und niemand räumte sie wieder weg.
Fix. uninstall() löscht die Blöcke des eigenen Typs, wenn der Händler seine Daten nicht behalten will. Die Einstellungs-Slots hängen per CASCADE am Block und gehen mit; sie werden deshalb nicht eigens gelöscht. Dazu fehlte der Klasse declare(strict_types=1).
Test. src/Test/UninstallTest — drei Prüfungen: die eigenen Blöcke verschwinden bei keepUserData=false, sie bleiben bei true, und Blöcke anderer Plugins werden nicht mitgelöscht. Aufgeworfen vom User am 06.09.2026.
REG-0030 — Kaputtes Vorschaubild und ein roher Schlüssel im Blockauswahl-Dialog
Symptom. Im Dialog »Block hinzufügen« zeigte die Kachel des Blocks ein Bild-nicht-gefunden-Symbol, und im Kategorie-Menü stand wörtlich apps.sw-cms.detail.label.blockCategory.custom-blocks statt eines Namens.
Ursache 1 — Bundle-Name. Die Vorschau-Vorlage fragte asset('/cmseverythingmodal/static/preview.png'). Das Bundle heißt nach der Plugin-Klasse, also leopardencmseverythingmodal — das Präfix fehlte. Gemessen: alter Pfad 404, richtiger Pfad 200. Die Datei lag die ganze Zeit da.
Ursache 2 — fehlendes Schnipsel. Shopware kennt neun Blockkategorien; custom-blocks ist keine davon. Für jede unbekannte Kategorie bildet der Kern den Schlüssel apps.sw-cms.detail.label.blockCategory.<name> und übersetzt ihn. Kein Plugin dieser Installation nutzt die Kategorie, also lieferte auch keines den Schlüssel — $t() druckte ihn. Das Plugin liefert ihn jetzt in beiden Sprachen.
Fix. Bundle-Name berichtigt, Schnipsel ergänzt, Admin-Bündel neu gebaut und mitcommittet — die Pipeline baut keine Admin-Assets, ausgeliefert wird das Eingecheckte.
Test. Kein automatischer — beides ist im gebauten Bündel und im Admin-Verhalten sichtbar, nicht im Quelltext prüfbar. Vom User im Browser bestätigt (06.09.2026): Bild wird angezeigt, Kategorie-Menü korrekt.