Сценарий проверки веб-сайта
Когда мы переносили ProfessorWeb в новую систему, сохранённый адрес был лишь частью задачи. Читатель должен был попасть на нужный материал, увидеть понятное оглавление и перейти к следующему уроку. Для такого изменения полезно заранее описать наблюдаемое поведение. Иначе проверка превращается в беглый просмотр страницы, а важные условия остаются в памяти человека.
В этом курсе рассмотрим отдельный учебный каталог. Он похож на небольшой раздел сайта, но не содержит настоящих материалов или пользовательских данных. В первом уроке определим границы сценария: от исходного состояния страницы до результата действия. Автоматизацию добавим позже. Оглавление и архив исходников относятся к локальному черновику серии; примеры пока не выполнялись.
Поведение вместо списка элементов
Представим, что на странице есть четыре курса. «Основы HTML» и «Современный JavaScript» относятся к фронтенду; «HTTP и API» и «Статический сайт из Markdown» — к публикации. Во всех уроках используются эти же названия и идентификаторы. Число уроков равно соответственно 12, 20, 8 и 10. Каталог содержит 50 уроков, хотя его основной список показывает четыре карточки курсов.
Наличие поля поиска само по себе не означает, что поиск работает. Поле может принимать текст, но кнопка не менять список. Поэтому сформулируем задачу от лица посетителя: выбрать раздел «Фронтенд» и получить только два относящихся к нему курса. Здесь есть начальное состояние, действие и ожидаемый эффект. Они связывают интерфейс с причиной, по которой человек его использует.
Начальное состояние важно записать явно. Поле запроса пустое, выбран пункт «Все разделы», каталог закончил загрузку, браузер находится в светлой теме и не имеет учебной сессии. Если предыдущая проверка оставила запрос HTTP, тот же выбор раздела приведёт к нулю карточек. Это не обязательно ошибка фильтра; это другое сочетание условий. Сценарий должен отличать такие случаи.
Следующее описание находится в lesson-01/expected/scenario.md. Это ожидаемое поведение, а не отчёт о проведённой проверке:
Исходное состояние: четыре курса, пустой запрос, раздел all.
Действие: выбрать frontend и отправить поиск.
Результат: c001 и c002; «Найдено курсов: 2».
Другой результат: запрос несуществующийxyz даёт ноль карточек.
Объяснение: «По этому запросу ничего не найдено».
Идентификаторы помогают сверять данные, а видимые названия — поведение интерфейса. Посетитель не обязан знать c001. При будущей автоматизации мы будем искать элементы главным образом по доступным названиям. Связь между записью и карточкой сохранится в исходниках, чтобы случайная замена текста не заставляла гадать, какой курс пропал.
Где заканчивается сценарий
Для проверки фильтра результатом является изменённый список. Отправка сообщения об ошибке, вход в редактор и открытие отдельного курса относятся к другим действиям. Их можно выполнить в одной длинной прогулке по сайту, но тогда неудача на первом шаге скроет все последующие результаты. Небольшой самостоятельный сценарий позволяет точнее описать, что перестало работать.
Граница не должна быть слишком узкой. Проверка только значения frontend внутри элемента select подтверждает выбор пункта, но ничего не говорит о карточках. Проверка только текста «2» также недостаточна: счётчик может обновиться, а список остаться прежним. Для нашего результата полезно совместить число карточек и их названия. Это два наблюдения над одним действием, а не две независимые задачи.
Различайте договорённость продукта и случайную деталь реализации. Наш каталог применяет фильтр после кнопки «Найти». Если дизайнер поменяет подпись этой кнопки, сценарий может потребовать обновления локатора. Если разработчик решит применять фильтр немедленно, изменится сам договорённый путь. Такой переход обсуждают как изменение поведения, а не маскируют исправлением проверочного кода.
Сценарий не доказывает, что все страницы сайта исправны. Он исследует конкретное сочетание данных и действий. Для старого ProfessorWeb отдельная задача — сохранение тысяч маршрутов. Для поиска — сочетания запроса и раздела. Для формы — допустимый ввод и понятная ошибка. Число проверок растёт из числа важных обещаний сайта, а не из количества технических элементов в HTML.
Наблюдаемый результат и причина неудачи
Допустим, после выбора раздела видны два курса, но это «HTTP и API» и «Статический сайт из Markdown». Счётчик верен, содержимое неверно. Описание с точными названиями позволяет заметить перепутанное значение раздела. Если же карточек четыре, а счётчик равен двум, вероятна рассогласованность двух частей интерфейса. Такие различия полезнее неопределённого замечания «фильтр сломан».
Для пустого запроса по отсутствующему слову запишем другой эффект: список пуст, счётчик сообщает ноль, объяснение доступно. Пустота сама по себе неоднозначна. Она может означать нормальное отсутствие совпадений, продолжающуюся загрузку или сетевой сбой. В лаборатории эти состояния представлены разными текстами. Следующие уроки будут опираться на эту договорённость, поэтому не следует объединять их одним ожиданием пустого списка.
Состояние загрузки тоже относится к модели. Начальный HTML содержит «Загрузка каталога», а карточки появляются после ответа /api/courses. Сценарий фильтра начинается после получения четырёх курсов. Это не требование ждать определённое число секунд: это требование увидеть конкретный результат подготовки. В дальнейшем такой результат станет условием автоматического ожидания.
Полезно записывать условие, которое делает вывод ограниченным. Четыре записи покрывают два раздела и несколько названий, но не длинный каталог, пагинацию или сложный поиск по содержимому. Мы не добавляем обещаний, для которых нет данных. Новый пример можно расширить отдельным уроком, сохраняя понятную причину каждого дополнения.
От ручного описания к автоматизации
Сначала прочитайте common/public/data.js и сопоставьте значения с описанием. Затем найдите в common/public/index.html форму «Поиск курсов» и список «Курсы». Даже без запуска видно, какие имена понадобятся автоматизации. Чтение исходников не заменяет проверку поведения в браузере, но обнаруживает несогласованные названия до дорогостоящего разбора неудачного запуска.
В архиве start означает предыдущую учебную точку, а expected — состояние после урока. Общий интерфейс уже подготовлен; мы постепенно меняем способ его проверки. Никаких настоящих отчётов, установленных браузеров или результатов запуска в архиве нет. Будущий читатель отдельно создаёт лабораторную папку и выполняет приведённые команды в ней.
Принцип проверки пользовательского поведения описан в рекомендациях Playwright. Для нашего курса он превращается в короткую договорённость: известное исходное состояние, одно осмысленное действие и результат, который можно отличить от ошибки. В следующем уроке эта договорённость получит первый исполняемый сценарий, а его ожидаемый результат останется тем же.