mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 19:58:50 +00:00
Issue: #426 Issue: #427 Issue: #428 Issue: #431 Issue: #432 Issue: #434 User-Visible: no
92 lines
4.9 KiB
JavaScript
92 lines
4.9 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* Отрицательный прогон гарда исключений (#404).
|
||
*
|
||
* Гард объявлен в `demo/serve.mjs` с 2026-07-27 и до этой задачи не срабатывал
|
||
* ни разу: счётчик читался раньше, чем Playwright доставлял `pageerror`. Такое
|
||
* ловится только запуском — «проверка, которая не умеет падать» выглядит
|
||
* идентично работающей во всём, кроме исхода.
|
||
*
|
||
* Почему не тест в `test/`: пробам нужен настоящий Chromium, а job «Фронтенд»,
|
||
* где идёт `npm test`, браузеры не ставит. Тест там молча скипался бы — то есть
|
||
* ровно тот тихий успех, против которого всё это и делается. Поэтому проверка
|
||
* живёт в job «Смоки в браузере», где браузер есть, и вызывается один раз.
|
||
*/
|
||
import { spawnSync } from 'node:child_process';
|
||
import { dirname, resolve } from 'node:path';
|
||
import { fileURLToPath } from 'node:url';
|
||
|
||
const HERE = dirname(fileURLToPath(import.meta.url));
|
||
|
||
/**
|
||
* Каждая проба: чего ждём от кода возврата и что обязано быть в выводе.
|
||
*
|
||
* `args` — необязательные аргументы запуска; `file` может указывать и выше
|
||
* этого каталога (`../benchmark_*.mjs`), потому что benchmark в `demo/guard/`
|
||
* не переселить: его гоняют руками при рекалибровке порогов (#430).
|
||
*/
|
||
const PROBES = [
|
||
{
|
||
file: 'guard_tail_exception.mjs',
|
||
expectExit: 1,
|
||
expectOutput: /uncaught exception\(s\) inside the card/,
|
||
because: 'исключение в хвосте — та самая слепая зона, из-за которой заводился #404',
|
||
},
|
||
{
|
||
file: 'guard_tail_rejection.mjs',
|
||
expectExit: 1,
|
||
expectOutput: /uncaught exception\(s\) inside the card/,
|
||
because: 'отклонение промиса приходит тем же каналом; на этом держится связь с #405',
|
||
},
|
||
{
|
||
file: 'guard_closed_page.mjs',
|
||
expectExit: 0,
|
||
expectOutput: /OK/,
|
||
because: 'round-trip к закрытой странице не имеет права ронять вердикт',
|
||
},
|
||
{
|
||
// #430: до этой задачи гард benchmark доказывался тестом, который искал
|
||
// в тексте те самые подстроки, которые сам же и вырезал у мутанта, —
|
||
// доказано было, что регулярка не пуста. Режим `--guard-probe` в
|
||
// benchmark существовал с #423 и не вызывался ни одним прогоном; теперь
|
||
// вызывается здесь, в единственной job с настоящим браузером.
|
||
file: '../benchmark_backdrop_decode.mjs',
|
||
args: ['--guard-probe'],
|
||
expectExit: 1,
|
||
expectOutput: /uncaught exception\(s\) inside the card/,
|
||
because: 'benchmark открывает страницу Playwright и обязан выносить тот же вердикт,'
|
||
+ ' что и смоки: исключение внутри карточки во время замера иначе не увидит никто',
|
||
},
|
||
{
|
||
file: 'guard_report_page_errors.mjs',
|
||
expectExit: 1,
|
||
expectOutput: /uncaught exception\(s\) inside the card/,
|
||
because: 'reportPageErrors() обязан сам дождаться хвостового pageerror, не полагаясь на finish()',
|
||
},
|
||
];
|
||
|
||
let failed = 0;
|
||
for (const probe of PROBES) {
|
||
const run = spawnSync(process.execPath, [resolve(HERE, probe.file), ...probe.args || []], {
|
||
encoding: 'utf8', cwd: resolve(HERE, '../..'), timeout: 90_000,
|
||
});
|
||
const output = `${run.stdout || ''}${run.stderr || ''}`;
|
||
const exitOk = run.status === probe.expectExit;
|
||
const textOk = probe.expectOutput.test(output);
|
||
if (exitOk && textOk) {
|
||
console.log(`ok ${[probe.file, ...probe.args || []].join(' ')} → exit ${run.status}`);
|
||
continue;
|
||
}
|
||
failed += 1;
|
||
console.error(`FAIL ${probe.file}: ${probe.because}`);
|
||
console.error(` ожидался exit ${probe.expectExit}, получен ${run.status}`);
|
||
if (!textOk) console.error(` в выводе нет ${probe.expectOutput}`);
|
||
console.error(output.split('\n').slice(-12).map((line) => ` | ${line}`).join('\n'));
|
||
}
|
||
|
||
if (failed) {
|
||
console.error(`\nгард исключений не доказан: проб провалено ${failed} из ${PROBES.length}`);
|
||
process.exit(1);
|
||
}
|
||
console.log(`\nгард исключений доказан на ${PROBES.length} пробах`);
|