aere-quantum/control-plane/control-negativ-consola-web.mjs

53 lines
4.4 KiB
JavaScript

// Controlul negativ al probei consolei web in browser (proba-consola-web.mjs): fiecare defect se planteaza intr-o COPIE a paginii,
// proba ruleaza pe copie (primeste calea ei) si proba NUMITA trebuie sa iasa rosie, cu proba chiar rulata; pe copia neatinsa, verde.
// Trei stari: un tipar care nu apare exact o data sau o proba care nu ajunge la rezumat e STRICAT si se numara esec.
// node control-negativ-consola-web.mjs iesire 0 = martorul verde si toate plantarile rosii pe proba lor
import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path';
import { spawn } from 'node:child_process'; import { fileURLToPath } from 'node:url';
const AICI = path.dirname(fileURLToPath(import.meta.url));
const PAGINA = path.join(AICI, 'consola-web', 'index.html');
const PLANTARI = [
// [nume, tipar, inlocuire, proba (o parte din numele ei)]
['fara viewport: telefonul primeste pagina de desktop (forma din 29 sept)', '<meta name="viewport" content="width=device-width, initial-scale=1">\n', '', '390px: latimea interna = latimea ecranului'],
['o treapta de finalitate marcata pentru orice stare lipita (forma din 29 sept)', 'const cur = exemplu ? 1 : 0;', 'const cur = 1;', 'nicio treapta de finalitate nu e aratata'],
['caseta de finalitate spune "ready" pentru orice stare lipita (forma din 29 sept)', ':(exemplu?{k:"Finality"', ':(true?{k:"Finality"', 'caseta de finalitate spune'],
['o eroare de script dupa prima redare', 'render(SAMPLE, true);\n</script>', 'render(SAMPLE, true); nuExistaFunctia();\n</script>', 'nicio eroare de consola sau de pagina'],
['un buraf brut aratat drept verificat', 'verdict:"UNCHECKED",', 'verdict:"OK",', 'un buraf brut redat UNCHECKED'],
['un continut mai lat decat telefonul', '.wrap{max-width:1000px;', '.wrap{min-width:600px;max-width:1000px;', '390px: latimea interna = latimea ecranului'],
['verdictul BROKEN aratat in culoarea buna', 'v.className="verdict "+(ok?"ok":"bad");', 'v.className="verdict ok";', 'redata BROKEN, in culoarea rea'],
['un JSON stricat redat in tacere', 'e.hidden=false; e.textContent="invalid JSON: "+err.message;', '', 'un JSON stricat'],
];
function ruleaza(pagina) {
return new Promise((resolve) => {
const c = spawn(process.execPath, [path.join(AICI, 'proba-consola-web.mjs'), pagina]); let out = '';
const ceas = setTimeout(() => c.kill(), 240000);
c.stdout.on('data', (x) => { out += x; }); c.stderr.on('data', (x) => { out += x; });
c.on('close', (cod) => { clearTimeout(ceas); resolve({ cod, rulat: /consola-web: \d+\/\d+/.test(out), rosii: out.split('\n').filter((l) => l.includes('[RAU ]')), nemasurat: /^NEMASURAT/m.test(out) }); });
});
}
const T = fs.mkdtempSync(path.join(os.tmpdir(), 'cons-web-ctl-'));
let rele = 0;
try {
const m0 = path.join(T, 'martor.html'); fs.copyFileSync(PAGINA, m0);
const m = await ruleaza(m0);
if (m.nemasurat) { console.log('NEMASURAT: proba nu poate rula aici (fara browser)'); process.exit(2); }
if (m.rulat && m.cod === 0 && !m.rosii.length) console.log(' OK martorul: copia neatinsa verde');
else { rele++; console.log(` STRICAT martorul nu e verde (cod ${m.cod}, ${m.rosii.length} rosii)`); }
const src = fs.readFileSync(PAGINA, 'utf8');
const planteaza = async ([nume, din, inl, tinta], i) => {
if (src.split(din).length !== 2) return [false, ` STRICAT ${nume}: tiparul apare de ${src.split(din).length - 1} ori`];
const f = path.join(T, `p${i}.html`); fs.writeFileSync(f, src.replace(din, inl));
const r = await ruleaza(f);
if (!r.rulat) return [false, ` STRICAT ${nume}: proba nu a ajuns la rezumat (cod ${r.cod})`];
if (r.rosii.some((l) => l.includes(tinta))) return [true, ` ROSU cum trebuia ${nume} (proba '${tinta}' pica)`];
return [false, ` CONTROL CAZUT ${nume}: proba '${tinta}' a ramas verde (${r.rosii.length} rosii altundeva)`];
};
// cate doua browsere deodata (fiecare cateva sute de MB): laptopul e impartit cu constructiile celuilalt agent
const rez = new Array(PLANTARI.length); let k = 0;
await Promise.all(Array.from({ length: 2 }, async () => { while (k < PLANTARI.length) { const i = k++; rez[i] = await planteaza(PLANTARI[i], i); } }));
for (const [bun, linie] of rez) { console.log(linie); if (!bun) rele++; }
} finally { fs.rmSync(T, { recursive: true, force: true }); }
console.log(rele ? `CONTROL NEGATIV: ${rele} probleme` : `DOVEDIT: martorul verde, ${PLANTARI.length} din ${PLANTARI.length} defecte plantate -> proba lor rosie`);
process.exitCode = rele ? 1 : 0;