@@ -5,20 +5,95 @@ import path from "node:path";
55import { fileURLToPath } from "node:url" ;
66
77const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) ) ;
8- const manifestPath = path . join ( __dirname , ".." , "manifest.webmanifest" ) ;
9- const swPath = path . join ( __dirname , ".." , "sw.js" ) ;
10-
11- test ( "manifest definiert standalone-PWA mit SVG-Icons" , ( ) => {
12- const manifest = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
13- assert . equal ( manifest . display , "standalone" ) ;
14- assert . equal ( manifest . start_url , "./index.html" ) ;
15- assert . ok ( Array . isArray ( manifest . icons ) ) ;
16- assert . ok ( manifest . icons . some ( ( icon ) => icon . src . endsWith ( "app.svg" ) ) ) ;
17- } ) ;
18-
19- test ( "service worker cached den Demo-Export und die Shell-Dateien" , ( ) => {
20- const source = fs . readFileSync ( swPath , "utf8" ) ;
21- assert . match ( source , / d e m o - w o r k s p a c e \. j s o n / ) ;
22- assert . match ( source , / m a n i f e s t \. w e b m a n i f e s t / ) ;
23- assert . match ( source , / c a c h e \. a d d A l l / ) ;
8+ const root = path . join ( __dirname , ".." ) ;
9+ const manifestPath = path . join ( root , "manifest.webmanifest" ) ;
10+ const swPath = path . join ( root , "sw.js" ) ;
11+ const indexPath = path . join ( root , "index.html" ) ;
12+ const appJsPath = path . join ( root , "app.js" ) ;
13+
14+ // --- Manifest ---
15+
16+ test ( "manifest: display ist standalone" , ( ) => {
17+ const m = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
18+ assert . equal ( m . display , "standalone" ) ;
19+ } ) ;
20+
21+ test ( "manifest: start_url vorhanden" , ( ) => {
22+ const m = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
23+ assert . equal ( m . start_url , "./index.html" ) ;
24+ } ) ;
25+
26+ test ( "manifest: id-Feld vorhanden (PWA-Installierbarkeit)" , ( ) => {
27+ const m = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
28+ assert . ok ( typeof m . id === "string" && m . id . length > 0 , "id fehlt oder leer" ) ;
29+ } ) ;
30+
31+ test ( "manifest: scope-Feld vorhanden" , ( ) => {
32+ const m = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
33+ assert . ok ( typeof m . scope === "string" && m . scope . length > 0 , "scope fehlt oder leer" ) ;
34+ } ) ;
35+
36+ test ( "manifest: name und short_name vorhanden" , ( ) => {
37+ const m = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
38+ assert . ok ( m . name && m . short_name ) ;
39+ } ) ;
40+
41+ test ( "manifest: SVG-Icon mit purpose any vorhanden" , ( ) => {
42+ const m = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
43+ assert . ok ( Array . isArray ( m . icons ) ) ;
44+ assert . ok ( m . icons . some ( ( i ) => i . src . endsWith ( "app.svg" ) && i . purpose === "any" ) ) ;
45+ } ) ;
46+
47+ test ( "manifest: maskable Icon vorhanden" , ( ) => {
48+ const m = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
49+ assert . ok ( m . icons . some ( ( i ) => i . purpose === "maskable" ) ) ;
50+ } ) ;
51+
52+ test ( "manifest: Icon-SVG-Dateien physisch vorhanden" , ( ) => {
53+ const m = JSON . parse ( fs . readFileSync ( manifestPath , "utf8" ) ) ;
54+ for ( const icon of m . icons ) {
55+ const iconPath = path . join ( root , icon . src . replace ( / ^ \. \/ / , "" ) ) ;
56+ assert . ok ( fs . existsSync ( iconPath ) , `Icon fehlt: ${ icon . src } ` ) ;
57+ }
58+ } ) ;
59+
60+ // --- Service Worker ---
61+
62+ test ( "sw.js: CACHE_NAME enthält 'devcenter'" , ( ) => {
63+ const src = fs . readFileSync ( swPath , "utf8" ) ;
64+ assert . match ( src , / d e v c e n t e r / ) ;
65+ } ) ;
66+
67+ test ( "sw.js: CACHE_NAME ist v2 (aktuell)" , ( ) => {
68+ const src = fs . readFileSync ( swPath , "utf8" ) ;
69+ assert . match ( src , / d e v c e n t e r - c o m p a n i o n - v 2 / ) ;
70+ } ) ;
71+
72+ test ( "sw.js: skipWaiting() im install-Handler" , ( ) => {
73+ const src = fs . readFileSync ( swPath , "utf8" ) ;
74+ assert . match ( src , / s e l f \. s k i p W a i t i n g \( \) / ) ;
75+ } ) ;
76+
77+ test ( "sw.js: clients.claim() im activate-Handler" , ( ) => {
78+ const src = fs . readFileSync ( swPath , "utf8" ) ;
79+ assert . match ( src , / s e l f \. c l i e n t s \. c l a i m \( \) / ) ;
80+ } ) ;
81+
82+ test ( "sw.js: Demo-Export und Shell-Dateien gecacht" , ( ) => {
83+ const src = fs . readFileSync ( swPath , "utf8" ) ;
84+ assert . match ( src , / d e m o - w o r k s p a c e \. j s o n / ) ;
85+ assert . match ( src , / m a n i f e s t \. w e b m a n i f e s t / ) ;
86+ assert . match ( src , / c a c h e \. a d d A l l / ) ;
87+ } ) ;
88+
89+ // --- HTML-Integration ---
90+
91+ test ( "index.html: verweist auf manifest.webmanifest" , ( ) => {
92+ const html = fs . readFileSync ( indexPath , "utf8" ) ;
93+ assert . match ( html , / m a n i f e s t \. w e b m a n i f e s t / ) ;
94+ } ) ;
95+
96+ test ( "app.js: registriert Service Worker" , ( ) => {
97+ const src = fs . readFileSync ( appJsPath , "utf8" ) ;
98+ assert . match ( src , / s e r v i c e W o r k e r \. r e g i s t e r / ) ;
2499} ) ;
0 commit comments