Граница, за которой автопроверки не работают
Гейты сети умеют многое: коды ответов, дубли, длину заголовков, вес страницы, наличие блоков, разметку. Текст они читают ровно на два параметра — длину и уникальность. За этой границей остаются три вещи, каждая из которых видна человеку с первого взгляда:
| Что померила проверка — и была права | Что осталось за границей |
|---|---|
| Разметка валидна, заголовки в норме, дублей и битых ссылок нет | Язык. «В {Название} районе» — валидно как HTML, бессмысленно как фраза |
| Блок формы найден на всех страницах, «0 страниц без формы» | Применённые стили. Тег в разметке и работающий блок на экране — разные утверждения |
| Ноль ошибок в консоли при нажатии на кнопку отправки | Конец сценария. «Ошибок нет» и «заявка ушла» — тоже разные утверждения |
Падеж: шаблон писался под одно конкретное слово
Дефект оказался шире одного шаблона. При живой проверке прода после первой волны правок в блоке вопросов нашлось то же самое на именах посёлков: «заберём авто из {Посёлок}», «доедете до {Посёлок}». Класс формулируется так: топоним из данных попадает в текст в именительном падеже, потому что шаблон писался под одно конкретное слово.
Обошли тремя приёмами, по убыванию надёжности:
- Падеж — функцией генератора, а не руками в выводе. Функция склонения прилагательных в сборщике уже была; её просто не применили в двух местах из десяти. Добавили родительный падеж и правило в описание функции: сырое имя ставить только в именительном и винительном.
- Для имён собственных — явный словарь, никакого автосклонения. Для 25 посёлков пригорода завели список форм: правило «добавить окончание» превратило бы несклоняемые названия в мусор, и это было бы хуже исходной ошибки. Список конечный, а новое название без записи ловится предупреждением при сборке.
- Где падеж не нужен — снять его родовым словом. Названия микрорайонов разнородны, словарь предложного падежа вышел бы длинным и спорным, поэтому шаблон переписан на «в мкр {Название}»: приложение после родового слова не склоняется. Правильная форма уже стояла в соседнем вопросе на той же странице.
Прогон по остальным сайтам сети: четыре чистых, а на сайте-близнеце с общим предком-генератором — 20 вхождений в 20 файлах. Тот же класс мы уже ловили на ядре раньше, но выводов в виде автоматической проверки тогда не осталось — и он спокойно повторился.
Стиль: «блок есть» было правдой и не значило ничего
Генератор вставил блок формы на 175 страниц. Поиск по коду показывал форму, адрес обработчика стоял на месте, скан рапортовал «0 страниц без формы». В браузере блок оказался без единого стиля: поля в два кривых столбца, фон не применился.
Причина в одну строку. Шаблон собирался как «CSS плюс HTML» через подстановку значений в фигурные скобки. В CSS фигурные скобки — синтаксис, и подстановка читает {background:…} как имя плейсхолдера. В первой редакции это роняло сборку с ошибкой ключа, и 175 страниц уехали бы с голым HTML. Шаблон со стилями склеивается конкатенацией, а не подстановкой — исключений тут нет.Приёмку блока после этого поменяли: не «есть ли класс», а вычисленный стиль — цвет фона элемента должен быть заданным, а не прозрачным. Форму принимаем реальной отправкой: заполнить, нажать, увидеть запрос в сетевом логе и итоговую страницу благодарности. Локальный сервер поднимает сайт целиком со статикой и обработчиком, поэтому сценарий проверяется до выкладки: три шаблона, каждый до конца.
Побочная мина замера. Ширина окна, снятая сразу после нажатия на кнопку отправки, возвращает ноль и даёт ложную тревогу о горизонтальном переполнении: страница в этот момент уже уходит. Мерить вёрстку и отправлять форму — разными проходами.
Конец сценария: «причина» оказалась недостижимым кодом
В постановке значилось, что сторонний рекламный скрипт роняет отправку формы. Код действительно падал — проверено на живом проде. Но вызов стоит внутри условия «форма подтверждена», а флаг подтверждения выставляется только из ответа капчи — и скрипт капчи закомментирован в 221 файле. Ветка недостижима, вредом этот пункт не был; починку оставили как страховку.
Дальше нашлось то, ради чего стоило доводить сценарий до конца. Раз капча недостижима, форма заказа не отправляет заявки вообще: реальный клик даёт валидацию, затем отправку, ноль ошибок в консоли, запрос при этом не уходит, а человеку показывается «докажите, что вы не робот». Заявки шли только через мессенджер и звонок, и это не было видно ни в одном отчёте.
Что делать у себя
- Считать язык дефектом сборки. Если текст собирает шаблон, к нему нужен детектор согласования с ненулевым кодом выхода. Проверять на двух состояниях: на сломанном он обязан краснеть, на починенном — молчать.
- Не автосклонять имена собственные. Конечный словарь форм плюс предупреждение на новое имя надёжнее любого правила окончаний.
- Принимать блоки по вычисленному стилю и живому сценарию, а не по наличию тега в разметке.
- Один раз пройти путь клиента целиком — от заполнения до страницы благодарности. Дефект «дошло до кнопки и остановилось» не виден ни в одном структурном отчёте.
Все три дефекта прожили в проде недели под зелёными проверками. Каждый нашёлся за минуту, как только страницу открыл человек и попробовал ею воспользоваться.