$ cd App/static && node tests/run-tests.js --with-php
Profitina Laundry static front end - tests (Node v22.22.2)

== Core rules ==
PASS JS-FORMAT    money, numbers, dates (U-1, AC-7.3)
PASS JS-RULES     BR-1/2/3/7: price, rounding up, express, promised time, overdue
PASS JS-CSV       CSV parser: quotes, commas, row counts of all 7 files
PASS JS-PBKDF2    Web Crypto PBKDF2 check of the README test vector and the owner hash (S-5)

== Mock API on database/csv (the same answers as docs/api.md) ==
PASS TC-3.1       services: 12, S0001 8000, S0005 65000
PASS TC-10.1      status B2938 + 0896-0000-1482 = the api.md example
PASS TC-10.2      b2938 + '0896 0000 1482' / '089600001482' -> the same
PASS TC-10.3/10.4 wrong phone and unknown bill -> the same 404 message
PASS TC-10.5      the status answer has no name, address or e-mail
PASS TC-10.7      B2944 (queued): promised 2 Oct 2026 07:31
PASS TC-1.1/1.2/1.3 mock login: owner OK; wrong password and unknown e-mail give the same 401
PASS TC-1.10      roles of the 14 employees (BR-12)
PASS TC-1.5       without login, bills/dashboard -> 401
PASS TC-8.1/8.2/8.3 owner dashboard 2026-09-30 = the api.md example
PASS TC-8.4/8.5   washer: O01 queue only, no money; cashier: O01 only
PASS TC-11.2      bills O03 queued: total 5, first item = the api.md example
PASS TC-11.6      per_page=1000 is capped at 100
PASS TC-5.11      O02 overdue: 6, oldest B2909
PASS TC-11.1      bill B2938 and B0014 = the api.md examples
PASS TC-2.2/2.3   customer search: wijaya 8 (C0228 ... C0082); phone and id find C0151
PASS TC-9.1       monthly report 2025-10 .. 2026-09
PASS TC-9.7       cashier: monthly report -> 403
PASS TC-5.1/5.2/5.12 finish B2941: spv2 (O02) 403, cuci5 OK, again 409 (in memory)

== Static checks of the pages ==
PASS JS-DOM-IDS   every id the page scripts look up exists in its page
PASS JS-NO-INNERHTML no script writes data with innerHTML/outerHTML/document.write (S-3)
PASS JS-LOGO      the pages use the official logo file (byte-identical to the brand file)

== LiveApi against the PHP track (php -S) ==
PASS LIVE-PROBE   the API answers at http://127.0.0.1:18551
PASS LIVE-SAME    LiveApi (PHP) and MockApi (CSV) give identical JSON for 12 calls
PASS LIVE-LOGIN   wrong password -> ApiError 401 login_failed; /api/me after login
PASS LIVE-CSRF    finish B2941 as cuci5 with X-CSRF-Token; without the token -> 403 csrf_failed
PASS LIVE-LOGOUT  logout -> the next call is 401
PASS LIVE-CORS    a page on http://localhost:5500 may call the API with its cookie (CORS + preflight)

============================================================
PASS 32   FAIL 0   (total 32)
