Erscheinungsbild
Was geprüft ist
Ein Fehler in dieser Kette ist unsichtbar: Die Website sieht richtig aus und überträgt trotzdem Daten, für die niemand eingewilligt hat. Deshalb wird das Verhalten auf drei Ebenen belegt.
Unit — die Entscheidung
tests/unit/tracking/ prüft die reinen Funktionen: die Übersetzung von Kategorien in Consent-Mode-Signale, den Ausgangszustand, die Registry der Verbraucher, den Ladeplan in allen Kombinationen aus Modus, Umgebung und Feature-Flags sowie die Bannertexte.
Weil die gesamte Entscheidung zur Bauzeit fällt und als JSON in der Seite landet, deckt diese Ebene jede Kombination ab — auch die, die in keiner Fixture gebaut wird.
Post-Build — was ausgeliefert wird
tests/dist/tracking.test.ts läuft über alle drei Ausgaben und prüft auf dem fertigen HTML:
- Der Ladeplan in der Seite ist die Ausgabe von
planTracking()für diese Konfiguration. Stimmt das nicht, wäre die gesamte Unit-Abdeckung wertlos. - Der Ausgangszustand steht vor der Auswertung einer gespeicherten Entscheidung.
- Kein
<script src="…googletagmanager…">und kein<noscript>-iframe im HTML — die Adresse darf nur als Zeichenkette im Ladeplan vorkommen. - Jede Seite bietet einen Weg zum Widerruf.
- In einer Ausgabe ohne Consent-Schicht kommen weder
dataLayernochgtagnoch ein Schalter vor, und das Stylesheet des Banners wird nicht verlinkt.
End-to-End — was im Browser passiert
tests/e2e/consent.spec.ts läuft im Playwright-Projekt consent gegen die Fixture „full" — die einzige Ausgabe des Repositories mit aktivem Tracking. Das Skript des Tag Managers wird abgefangen und durch eine Attrappe ersetzt: Eine Testkette darf nichts an Google senden, und geprüft wird ohnehin nicht, was Google tut, sondern ob und wann wir es fragen.
| Szenario | Zusage |
|---|---|
| keine Entscheidung | keine Anfrage an Google, überhaupt keine Fremdanfrage |
| Ausgangszustand | jedes Signal denied außer denen der notwendigen Kategorie |
| nur notwendige | kein Container, Ablehnung als Update übertragen |
| Statistik erlaubt | Container genau einmal, analytics_storage erteilt, Werbung nicht |
| alles erlaubt | alle vier Werbe-Signale erteilt |
| Widerruf | Rücknahme übertragen, Container kein zweites Mal geladen |
| Widerruf | die Cookies der widerrufenen Kategorie sind gelöscht |
| zweiter Besuch | keine erneute Frage; das Update steht vor dem Container |
| neue Fassungsnummer | erneute Frage, bis dahin lädt nichts |
| Barrierefreiheit | Banner und Einstellungsdialog ohne axe-Verstöße |
Die Zusage „keine doppelten Seitenaufrufe" steckt in zwei Prüfungen: Der Container wird je Seitenaufruf höchstens einmal geladen, und das Ereignis gtm.js kommt im dataLayer genau einmal vor — auch nachdem die Auswahl mehrfach gewechselt hat.
Die Gegenprobe steht in tests/e2e/smoke.spec.ts: Der Starter selbst hat cookieConsent an, aber kein Tracking. dist ist ein Entwicklungsstand, dort erscheint der Dialog also als Vorschau — und muss dann „Statistik" und „Marketing" weglassen und im Text sagen, dass es nichts abzuwählen gibt.
Alle übrigen Prüfungen des Projekts starter laufen mit bereits getroffener Entscheidung (tests/e2e/support/consent.ts). Der Dialog liegt sonst über dem Seitenfuß und blendet sich noch ein, während axe schon misst. Der Cookie wird dabei vollständig nachgebaut — CookieConsent prüft mehr als categories und revision, und ein unvollständiger Cookie würde stillschweigend verworfen.
Was nicht geprüft ist
Der Advanced Mode wird nicht im Browser gefahren. Im Repository wird nur eine Ausgabe mit Tracking gebaut, und die benutzt den Basic Mode — das Verhalten, das jedes Kundenprojekt bekommt. Der Unterschied im ausgelieferten HTML ist ein Feld im Ladeplan und über die Unit-Tests abgedeckt; wer Advanced einschaltet, prüft die Ausgabe von Hand.
Ebenso nicht geprüft ist, was im Container passiert. Ob ein GA4-Tag seine Consent-Prüfung gesetzt hat, entscheidet sich in GTM und nicht in diesem Repository — siehe Tag Manager.