mega-plant/scripts/verify-clock-pwa.mjs

26 lines
2.3 KiB
JavaScript
Raw Permalink Normal View History

// Read-only checks against the built app. No database access or writes.
import assert from 'node:assert/strict';
const base=process.env.MEGA_AUTH_BASE_URL||'http://localhost:6007';
const manifestResponse=await fetch(base+'/clock.webmanifest');
assert.equal(manifestResponse.status,200);
assert.match(manifestResponse.headers.get('content-type'),/json|manifest/);
const manifest=await manifestResponse.json();
assert.equal(manifest.id,'/clock');assert.equal(manifest.start_url,'/clock');assert.equal(manifest.scope,'/clock');assert.equal(manifest.display,'standalone');
for(const icon of manifest.icons) {
const response=await fetch(base+icon.src);assert.equal(response.status,200);
const png=Buffer.from(await response.arrayBuffer());assert.equal(png.subarray(1,4).toString(),'PNG');
const [width,height]=icon.sizes.split('x').map(Number);assert.equal(png.readUInt32BE(16),width);assert.equal(png.readUInt32BE(20),height);
}
const dashboard=await (await fetch(base+'/manifest.json')).json();assert.notEqual(dashboard.start_url,manifest.start_url);assert.notEqual(dashboard.name,manifest.name);
const login=await fetch(base+'/clock/login');assert.equal(login.status,200);const html=await login.text();
assert.match(html,/<link[^>]+rel="manifest"[^>]+href="\/clock.webmanifest"/);
assert.match(html,/<meta[^>]+name="apple-mobile-web-app-title"[^>]+content="Plant Clock"/);
assert.match(html,/<link[^>]+rel="apple-touch-icon"[^>]+href="\/icons\/plant-clock-192.png"/);
assert.equal((html.match(/rel="manifest"/g)||[]).length,1);
assert.equal((html.match(/name="apple-mobile-web-app-title"/g)||[]).length,1);
assert.match(html,/name="clock"[^>]+value="1"/);
const app=await fetch(base+'/clock',{redirect:'manual'});assert.equal(app.status,307);assert.ok(app.headers.get('location')?.endsWith('/clock/login'));
const password=await fetch(base+'/clock/change-password',{redirect:'manual'});assert.equal(password.status,307);assert.ok(password.headers.get('location')?.endsWith('/clock/login'));
const sw=await fetch(base+'/sw.js');assert.equal(sw.status,200);const worker=await sw.text();assert.match(worker,/precache|precacheAndRoute/);
console.log('PASS: distinct standalone manifest, public valid PNG icons, one correct iOS/manifest metadata set, scoped login/onboarding redirects, shared production service worker.');