ci: make the stability measurement a gate, not a printout

Замер сделал свою работу — теперь он остаётся как проверка. Если кадр снова
начнёт зависеть от времени, шаг упадёт, а не напечатает число в лог. Стоит
перед съёмкой набора: публиковать артефакт, снятый недетерминированной
съёмкой, смысла нет.

Issue: #410
User-Visible: no
This commit is contained in:
Matysh
2026-09-01 23:20:09 +03:00
parent ed700c8c8e
commit ca0b318e5e
2 changed files with 16 additions and 4 deletions
+8 -4
View File
@@ -89,10 +89,14 @@ jobs:
# сравнить два прогона одного и того же SHA, нужен текст, который видно с
# экрана. Именно так измеряется недетерминированность съёмки — и её
# отсутствие после починки.
# ВРЕМЕННО на ветке замера #410: три снимка на сценарий в одном процессе,
# без правки состояния между ними. Отвечает на вопрос, плавает ли кадр
# внутри одного состояния страницы.
- name: "Замер стабильности (#410)"
# Съёмка обязана быть воспроизводимой, и это проверяется, а не
# предполагается (#410): три снимка на сценарий в одном процессе, без
# правки состояния между ними, обязаны совпасть побайтово. Шаг падает,
# если кадр снова начнёт зависеть от времени.
#
# Проверка стоит ПЕРЕД съёмкой набора: смысла публиковать артефакт,
# снятый недетерминированной съёмкой, нет.
- name: "Кадр не плавает внутри одного состояния (#410)"
run: node demo/docs/capture.mjs --stability=3
- name: Хеши кадров
run: |
+8
View File
@@ -186,6 +186,7 @@ const DETERMINISTIC_ARGS = [
*
* Ничего не пишет на диск и манифест не трогает: это измерение, а не съёмка.
*/
const unstable = [];
const stabilityArg = process.argv.find((arg) => arg.startsWith('--stability'));
const STABILITY_SHOTS = stabilityArg
? Math.max(2, Number(stabilityArg.split('=')[1] || 3))
@@ -314,6 +315,7 @@ try {
+ (result.box ? `, bbox ${result.box.x0},${result.box.y0}`
+ `..${result.box.x1},${result.box.y1}` : '')
+ `, кадр ${result.size ? result.size.join('x') : '?'}`);
if (result.pixels || result.sizeMismatch) unstable.push(`${scenario.id} ${result.pair}`);
}
continue;
}
@@ -336,6 +338,12 @@ try {
if (browserErrors.length) throw new Error(`browser errors: ${browserErrors.join(' | ')}`);
if (STABILITY_SHOTS) {
console.log(`\nзамер стабильности: ${STABILITY_SHOTS} снимка на сценарий, манифест не тронут`);
if (unstable.length) {
// Режим — не только диагностика, но и гейт: если кадр снова начнёт зависеть
// от времени, это должно останавливать съёмку, а не печататься в лог.
throw new Error(`кадр плавает внутри одного состояния страницы: ${unstable.join(', ')}`);
}
console.log('кадр не плавает ни в одном сценарии');
} else {
const manifest = {
version: DOC_SCREENSHOT_VERSION,