Вступление

Привет! Меня зовут Вячеслав, я инженер по автоматизации тестирования в компании ROWI.Tech.
В ходе автоматизации тестирования пользовательских интерфейсов зачастую используется такой подход как визуальное тестирование. Он позволяет поддерживать стабильность и отсутствие ошибок в отображении страниц.  

Одним из инструментов, предоставляющих возможность автоматизации данного вида тестирования, является Playwright.

В этой статье я расскажу о работе с визуальным тестированием в рамках упомянутого инструмента, как мы справились со сложностями хранения эталонных скриншотов и автоматизировали их обновление.

Содержание

  • Визуальные проверки Playwright.

  • Облачное хранилище для эталонных скриншотов.

  • Обновление скриншотов.

  • Автоматизация обновления эталонных скриншотов.

Визуальные проверки в Playwright

Данный инструмент предоставляет утверждение из “коробки” для визуальных проверок - toHaveScreenshot. Можно визуально сравнивать как страницы, так и отдельные элементы на ней.

Возможные настройки утверждения:

  • Отключение анимаций.

  • Передача стилевых файлов.

  • Настройка маски для динамических элементов.

Также помимо настройки самого утверждения можно указать некоторые настройки глобально:

  • Максимальная разница в результатах по сравнению с эталоном в пикселях и долях.

  • Путь до скриншота

С полным списком настроек можно ознакомиться в официальной документации Playwright.

Отображение разницы скриншотов с помощью ползунка "Show overlay" в Allure
Отображение разницы скриншотов с помощью ползунка "Show overlay" в Allure

Облачное хранилище для эталонных скриншотов

Playwright сохраняет скриншоты в установленной директории проекта. Мы можем определить необходимое расположение согласно установленной структуре с помощью указания шаблона пути до необходимой директории в конфигурационном файле (playwright.config.ts).

Это дает нам выбрать способ хранения скриншотов:

  • Сохранять скриншоты в проекте, публиковать их вместе с изменениями кодовой базы.

  • Хранить скриншоты в отдельном удалённом хранилище.

Первый подход имеет свои недостатки. Он увеличивает размер проекта и число изменяемых файлов. С ростом количества тестов увеличивается и размер репозитория.

Git LFS является расширением Git, которое применяется в работе с часто изменяющимися большими файлами, такими как изображения и наборы данных. Оно может решить проблему хранения эталонных скриншотов в проекте. Подробнее об использовании Playwright с Git LFS можно прочитать тут.

Занимаемое скриншотами место на одном из проектов автоматизации
Занимаемое скриншотами место на одном из проектов автоматизации

Альтернативой Git LFS являются отдельные удалённые хранилища, например облачные. Одним из таких хранилищ является объектный S3.

Те самые облачные хранилища
Те самые облачные хранилища

Мы решили использовать альтернативный подход, воспользовавшись S3 хранилищем, в котором были заведены отдельные bucket’ы для визуального тестирования и e2e-тестов.

В CI/CD мы реализовали отдельный этап, на котором в проект загружаются все необходимые файлы, используя MC образ.

Этап скачивания эталонных скриншотов
screenshot-download:
  stage: screenshot-download
  allow_failure: true
  artifacts:
    paths:
      - screenshot
      - static-files
    reports:
      dotenv: screenshot-variables.env
    expire_in: 1 hour
  script:
    - |
      PROJECT_GROUP=$(echo ${CI_PROJECT_NAMESPACE} | grep -Eo '([^\/]+)[\/]?$')
    - echo "PROJECT_GROUP=${PROJECT_GROUP}" >> screenshot-variables.env
    - mc alias set bucket-alias https://path-to-storage.net $BUCKET_ROWI_TEST_SCREENSHOT_ACCESS_KEY $BUCKET_ROWI_TEST_SCREENSHOT_SECRET_KEY
    - mc cp --recursive bucket-alias/rowi-test-screenshot/${PROJECT_GROUP}/ screenshot
    - ls screenshot
    - |
      if [[ ! -z $(mc ls bucket-alias/rowi-test-static-files/${PROJECT_GROUP}/) ]]; then mc cp --recursive bucket-alias/rowi-test-static-files/${PROJECT_GROUP}/ static-files
      ls static-files;
	fi

Обновление скриншотов

После перемещения эталонных скриншотов в облачное хранилище механизм обновления стал следующим:

  • Запустить Docker контейнер playwright.

  • Выполнить необходимые тесты с ключом update-snapshots.

  • В ручном режиме загрузить полученные скриншоты в S3 хранилище, используя клиент (например, s3 Browser).

Но по мере увеличения таких тестов увеличиваются и трудозатраты на актуализацию ожидаемых результатов.

Мы приняли решение реализовать механизм, с помощью которого можно было бы обновлять скриншоты прямо из отчёта о тестировании. Вдохновением для реализации послужила статья, в которой был разработан артефакт, содержащий запись теста.

Автоматизация обновления эталонных скриншотов

Мы остановились на HTML с кнопкой обновления скриншота, загружаемый в качестве артефакта.

Требования

Реализуемая страница должна обладать следующими качествами:

  • Кнопка должна относиться к конкретному скриншоту.

  • Кнопка появляется только в случае несоответствия скриншотов.

  • Загрузка скриншотов должна осуществляться в S3 хранилище по одному нажатию кнопки.

  • Актуальный скриншот должен стать эталонным.

  • Должна быть индикация успешной загрузки скриншота.

Реализация

Флагом несоответствия с эталонным скриншотом является наличие актуального скриншота. Это можно использовать для начала формирования артефакта.

if (matcherResult["actual"]) await attachHtmlButton(matcherResult); 

После того, как стала понятна отправная точка для формирования артефакта, нужно определить зависимости, необходимые для его реализации. Такими зависимостями стали:

  • AWS SDK для взаимодействия с удалённым хранилищем.

  • Buffer для преобразования base64 строки в объект Buffer.

Allure предлагает широкий выбор типов приложений, одним из которых является HTML, в котором можно разместить кнопку.

Для записи артефакта используется TestInfo объект, содержащий информацию о выполняемом тесте.

Создание артефакта представлено следующим образом:

//генерируется случайный uuid для уникального названия артефакта
//получение пути до артефакта в контексте текущего теста
const file = testInfo.outputPath(`${faker.string.uuid()}.html`);
//запись HTML-артефакта
await fs.writeFile(file,prepareHtml((await fs.readFile(matcherResult.actual, { encoding: "base64" })).toString(),`path/to/s3/expected.png`),"utf8");
//приложение HTML к артефактам текущего теста
await testInfo.attach("Upload:" + matcherResult.actual.split(/\//).at(-1).replace(".png", ""), {path: file, contentType: "text/html"});

В HTML-артефакте была создана кнопка, нажатие на которую обрабатывается с помощью функции uploadSnapshot.

HTML-кнопка
<html>
  <head>
     <script src="https://sdk.amazonaws.com/js/aws-sdk-2.742.0.min.js"></script>
	 <script src=" https://bundle.run/buffer@6.0.3"></script>
   </head>
   <body>
		<button onclick="uploadSnapshot()">Send to S3</button>
		<div id="Notification">Click button to upload</div>
		<script>
			async function uploadSnapshot(){
			<!-- настройка подключения к S3 -->
			AWS.config.update({
			<!-- здесь ключи доступа к S3 -->
			});
			<!-- создание S3 объекта с настроенным подключением -->
			var s3 = new AWS.S3({
			sslEnabled: true,
			});
			<!-- создание Buffer объекта -->
			var base64Data =
			buffer.Buffer.from("${buffer}","base64");
			<!-- оглашение параметров PUT запроса в S3-->
			var params = {
			Bucket: "название bucket’a",
			Key: "путь до эталонного скриншота",
			Body: base64Data,
			ContentEncoding: "base64",
			ContentType: "image/png",
		};
		try {
			<!-- отправка  PUT запроса в S3-->
			await s3.upload(params).promise();
			<!-- уведомление об успешном завершении загрузки -->
			document.getElementById("Notification").textContent = "Uploaded";
		} catch (error) {
		console.log(error);
}		
        </script>
   </body>
</html>
Отображение кнопки в Allure отчёте
Отображение кнопки в Allure отчёте

Используемые CDN были добавлены в Allure-образ, чтобы сократить время на их загрузку и обеспечить их доступность.

Выводы

Визуальное тестирование является одним из популярных видов тестирования, встречающихся в автоматизации. Правильный подход к хранению и обновлению эталонных скриншотов может значительно сократить затрачиваемые ресурсы на поддержку данных тестов.

Перемещение скриншотов в облачное хранилище позволило уменьшить размер репозитория и исключить лишние коммиты в репозиторий, связанные с обновлением скриншотов.

Реализованная кнопка позволила упростить обновление эталонных скриншотов и сделала данный процесс доступным для всех участников команды. Теперь вместо поднятия Docker контейнера с образом Playwright или скачивания с Allure отчёта и последующей ручной отправки в S3 формируется артефакт, автоматизирующий рутинные действия

Комментарии (0)