import { test } from 'node:test' import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' const lies = (pfad) => readFileSync(new URL(`../${pfad}`, import.meta.url), 'utf8') const html = lies('public/auftrag.html') const css = lies('public/auftrag.css') test('auftrag.html: noindex, kein Referrer, Viewport mit Notch, Titel, ein Modul-Skript, kein Inline-Skript', () => { assert.match(html, //) assert.match(html, //) assert.match(html, //) assert.match(html, //) assert.match(html, /Auftragsbestätigung – WEBklar<\/title>/) assert.match(html, /<link rel="stylesheet" href="\/auftrag\.css">/) assert.deepEqual(html.match(/<script\b[^>]*>/g), ['<script type="module" src="/auftrag.js">']) assert.doesNotMatch(html, /<script>/) assert.doesNotMatch(html, /\son[a-z]+=/i, 'keine Ereignis-Attribute') assert.doesNotMatch(html, /https?:\/\/(?!webklar\.com\/impressum)/, 'keine Fremdressourcen') }) test('auftrag.html: Wurzel im Zustand „lädt“, Live-Region, Hinweis ohne JavaScript', () => { assert.match(html, /<div class="ab-wurzel" id="ab-wurzel" data-zustand="laedt" aria-busy="true">/) assert.match(html, /<p class="ab-laden">Ihre Auftragsbestätigung wird geladen …<\/p>/) assert.match(html, /<div class="ab-vh" id="ab-ansage" aria-live="polite"><\/div>/) assert.match(html, /<noscript><p>Bitte aktivieren Sie JavaScript, um Ihren Auftrag zu bestätigen\.<\/p><\/noscript>/) assert.match(html, /<noscript><style>\.ab-laden\{display:none\}<\/style><\/noscript>/) }) test('auftrag.html: Fußzeile mit Datenschutz und Impressum; Zurück-Link nur für die installierte App', () => { assert.match(html, /<footer class="ab-fuss">[\s\S]*<a href="\/datenschutz\.html" target="_blank" rel="noopener noreferrer">Datenschutz<\/a>[\s\S]*<a href="https:\/\/webklar\.com\/impressum" target="_blank" rel="noopener noreferrer">Impressum<\/a>[\s\S]*<\/footer>/) assert.match(html, /<a class="ab-app-back" href="\/dashboard\.html">‹ Zurück zum Kundenbereich<\/a>/) }) test('auftrag.css: Farben der Mailvorlagen hell und dunkel, Standalone-Modus, Handy-Tabelle, Umbruch, Tippflächen', () => { for (const farbe of ['#f1f0ec', '#efe6fb', '#5a2a91', '#e4f2e6', '#1d5b2c', '#161615', '#1f1f1e', '#f2f1ee', '#a8a6a0']) assert.ok(css.includes(farbe), farbe) assert.match(css, /@media \(prefers-color-scheme: dark\)/) assert.match(css, /@media \(display-mode: standalone\)/) assert.match(css, /env\(safe-area-inset-top\)/) assert.match(css, /overflow-wrap:\s*anywhere/) assert.match(css, /min-height:\s*48px/) assert.match(css, /content:\s*attr\(data-label\)/) assert.match(css, /\.ab-app-back\s*\{[^}]*display:\s*none/) assert.match(css, /\.ab-vh\s*\{/) assert.match(css, /body\.ab-seite[^{]*\.hidden|\.ab-seite \.hidden/) }) test('Service Worker und Manifest brauchen für die neue Seite keinen Eintrag', () => { assert.doesNotMatch(lies('public/sw.js'), /auftrag/) const manifest = JSON.parse(lies('public/manifest.webmanifest')) assert.equal(manifest.scope, '/', 'der Link aus der Mail kann in der installierten App öffnen: darum der Standalone-Modus oben') })