Работа с потоками электронной почты в тестах Cypress #frontend@twiliosendgrid
Опубликовано: 2020-11-24Twilio SendGrid отправляет много писем. Для отправки всех наших транзакционных электронных писем — от сброса пароля до проверки электронной почты учетной записи и экспорта электронных писем в формате CSV — мы используем наши собственные серверные службы.
Недавно мы преодолели колоссальный рубеж — более 3 триллионов отправленных электронных писем.
В наших тестовых средах мы отправляем наши электронные письма в тестовые почтовые ящики на собственных серверах Squirrelmail , чтобы избежать отправки тестовых электронных писем фактическим поставщикам услуг электронной почты, таким как Gmail. Многие важные потоки требуют, чтобы пользователь проверил свою электронную почту, щелкнул активную ссылку, перенаправился обратно в веб-приложение, а затем продолжил на какой-либо странице загрузки или проверки.
Мы тестируем эти функции вручную, вводя наши адреса электронной почты Squirrelmail в необходимые формы, нажимая некоторые кнопки и переходя по ссылкам электронной почты, чтобы убедиться, что все работает должным образом. Мы можем делать это каждый раз при новых изменениях кода, чтобы убедиться, что мы нигде не регрессировали, но было бы неплохо автоматизировать эти шаги в сквозном (E2E) тесте, который мы можем запускать снова, когда захотим. В частности, мы хотели бы написать E2E-тесты с помощью Cypress, чтобы нам не приходилось каждый раз вручную тестировать эти потенциально медленные и запутанные потоки электронной почты в нашем собственном веб-браузере.
Прежде чем мы перейдем к статье, вот несколько статей, которые вам, возможно, будет интересно прочитать в первую очередь.
- Если вы никогда раньше не писали E2E-тесты или хотели бы освежить в памяти, как мыслить при написании E2E-тестов, вы можете просмотреть эту запись в блоге, прежде чем мы начнем.
- Если вы не знакомы с использованием Cypress для написания тестов E2E в целом, мы настоятельно рекомендуем вам ознакомиться с нашим обзором на тысячу футов о реализации тестов Cypress для ваших веб-приложений — это даст вам лучшее представление об API Cypress.
В этом посте предполагается, что вы знаете некоторые функции Cypress, такие как cy.task()
для запуска произвольного кода, который мы определяем на сервере Node, чтобы помочь нам работать с электронной почтой. Кроме того, если более поздние фрагменты кода с TypeScript немного сбивают с толку, это может прояснить ситуацию, если вы посмотрите наш пост в блоге о том, как мы печатали наши тесты Cypress. Вы по-прежнему можете изменить код в своих собственных тестах Cypress, удалив определения типов и придерживаясь синтаксиса только для JavaScript.
Мы не будем рассказывать, как настроить собственный тестовый сервер электронной почты (например, Squirrelmail), но сосредоточимся на автоматизации этих шагов, связанных с поиском электронных писем, анализом соответствующего содержимого электронной почты и переходом по ссылкам электронной почты. Это должно дать вам лучшее представление о том, какие функции использовать и реализовать для обработки этих потоков электронной почты, при условии, что у вас есть тестовый сервер почтового ящика и ваши собственные учетные данные для подключения.
Как мы справляемся с потоками электронной почты в тестах Cypress?
Чтобы протестировать все потоки электронной почты, мы создали плагины cy.task()
для:
- Работа с подключением и фильтрацией почтовых ящиков для электронных писем с определенной строкой темы
- Получение соответствующего содержимого тела электронной почты
- Удаление электронных писем из почтового ящика пользователя без необходимости входа в систему через пользовательский интерфейс Squirrelmail
Мы также пошли по этому пути, потому что мы не владеем и не контролируем пользовательский интерфейс Squirrelmail, и невозможно посетить более одного супердомена в тесте Cypress, поскольку URL-адреса для пользовательского интерфейса Squirrelmail находятся в отдельном супердомене от нашего развернутого внешнего приложения. .
Сначала мы установили библиотеку под названием «emailjs-imap-client» , чтобы помочь нам настроить клиент IMAP для подключения к нашему почтовому ящику Squirrelmail через некоторые учетные данные и конфигурации хоста. Используя эту библиотеку, мы инкапсулировали все вещи, связанные со Squirrelmail, в модуль с именем squirrelmail.ts
, который мы позже импортировали в наши plugins/index.ts
для определения нашей cy.task()
.
Перед запуском тестов с использованием электронных писем мы должны удалить все электронные письма с одной и той же строкой темы, чтобы избежать ложных срабатываний при случайной ссылке на более старое электронное письмо, инициированное в предыдущем тесте. Чтобы справиться с этим вариантом использования, мы реализовали эту задачу, чтобы удалить все электронные письма с соответствующей строкой темы в папке «Входящие» пользователя следующим образом.
Во время наших тестов мы инициируем действие, которое приводит к отправке электронного письма на адрес электронной почты пользователя Squirrelmail, и часто приходится ждать, пока электронное письмо с соответствующей строкой темы поступит в почтовый ящик пользователя. Этот процесс занимает от секунд до минут, в зависимости от того, насколько задействованы серверные процессы. Мы должны обязательно проводить опрос до тех пор, пока он не прибудет, или указать ошибку тайм-аута в тесте, чтобы сообщить нам, если что-то не работает или задерживается в части отправки почты. Поскольку мы уже удалили электронные письма с соответствующими строками темы заранее, мы можем быть в основном уверены, что они были вызваны нашим тестовым запуском, если они действительно возвращаются успешно.
Вот как мы разработали функциональность для ожидания сообщения электронной почты с определенной строкой темы, такой как «Экспорт активности вашей электронной почты» или «Подтверждение отправителя», для поступления в почтовый ящик электронной почты пользователя.
Слишком далеко:
- Мы очистили почтовый ящик пользователя
- Тест запускается и запускает электронное письмо, которое будет отправлено в почтовый ящик пользователя.
- Мы успешно дождались поступления письма в почтовый ящик пользователя.
Теперь нам нужно получить содержимое тела этого конкретного письма.
К счастью, мы можем вернуть содержимое тела соответствующего электронного письма в виде строки, которую позже нам придется проанализировать, чтобы ссылка действия вернулась в веб-приложение, которое мы контролируем и которым владеем. Приведенный ниже подключаемый модуль задачи ищет в почтовом ящике пользователя электронное письмо с соответствующей строкой темы и возвращает содержимое тела для дальнейшего использования.
В качестве краткого напоминания, мы не могли просто создать объекты страницы для страниц Squirrelmail, посетить Squirrelmail через пользовательский интерфейс, отфильтровать соответствующую строку темы, открыть электронное письмо, напрямую щелкнуть активную ссылку и отправиться обратно в наше веб-приложение, потому что мы не можем посетить несколько супердоменов в одном и том же тесте Cypress. Кроме того, посещение страниц и приложений, которые вы не контролируете или которыми не владеете, скорее является антипаттерном.
После обнаружения соответствующего содержимого тела электронной почты, которое мы запустили в тесте, мы должны проанализировать содержимое HTML, найти ссылку действия, инициировать HTTP-запрос к ссылке, а затем выполнить перенаправление обратно в наше веб-приложение.
Для синтаксического анализа HTML-содержимого электронной почты и поиска частей ссылок действий мы использовали другую библиотеку под названием «cheerio», которая загружает строку HTML и позволяет нам вызывать функции, подобные jQuery, для извлечения кнопок действий или ссылок, которые нам нужны. После того, как мы проанализировали ссылки, мы делаем HTTP-запрос к ссылке с помощью cy.request()
, переходим по ссылке перенаправления обратно в веб-приложение, которое мы контролируем и владеем на одном супердомене, и продолжаем проверять состояния успеха на странице, которую мы перенаправлен на.
В вашем случае вам может не понадобиться инициировать HTTP-запрос к ссылке и следовать перенаправлению ответа, если ваша ссылка уже указывает на нужное место. Если URL-адрес ссылки уже указывает на ваше веб-приложение напрямую, ничто не мешает вам извлечь путь ссылки и выполнить cy.visit(linkPath)
для перенаправления обратно в ваше приложение. В случае ссылок Twilio SendGrid ссылки могут выглядеть как «…sendgrid.net?…», если у вас включено отслеживание ссылок для ваших электронных писем, или «brandedlink.com», если у вас включено брендирование ссылок. Вот почему нам нужно будет сделать HTTP-запрос и извлечь путь перенаправления, чтобы выполнить cy.visit(redirectPath)
, потому что непосредственный «href» ссылок не совпадает с нашим веб-приложением.
Ниже приведен пример поиска ссылки с помощью cheerio, выполнения HTTP-запроса к ссылке и выполнения перенаправления.
Заключение
Мы познакомили вас со многими функциями плагина cy.task()
, которые мы реализовали, чтобы выполнять больше операций чтения и удаления с соответствующими электронными письмами в наших почтовых ящиках. Мы создали эти функции, чтобы правильно сбросить состояние почтового ящика пользователя, прежде чем мы инициируем эти потоки электронной почты на веб-страницах, ждем, пока электронные письма поступят в почтовый ящик, и, наконец, перейдем по ссылкам обратно к их состояниям успеха. Мы резюмируем ключевые шаги для ваших тестов Cypress ниже:
- Удалите все электронные письма с определенной строкой темы, чтобы избежать ложных срабатываний с помощью
cy.task(“teardownMatchingEmails”)
. - Войдите в систему пользователя через API, а затем выполните ряд шагов через пользовательский интерфейс, чтобы сгенерировать это электронное письмо, которое будет отправлено в почтовый ящик пользователя.
- Опросите почтовый ящик пользователя, чтобы получить электронное письмо с соответствующей строкой темы через
cy.task(“awaitEmailInSquirrelmailInbox”)
. - Прочитайте содержимое тела письма с соответствующей строкой темы, используя
cy.task(“squirrelmailSearchBySubject”)
. - Разберите правильную ссылку действия с библиотекой cheerio, передав строку HTML тела письма и выполнив поиск элементов с синтаксисом, подобным jQuery.
- Сделайте HTTP-запрос по проанализированным ссылкам электронной почты через
cy.request(“link”)
и следуйте ответу перенаправления обратно в веб-приложение или перейдите по пути, если ссылки уже совпадают с вашим супердоменом, с помощьюcy.visit(“emailLinkToWebApp”)
. - Проверьте наличие состояний успеха или выполните дополнительные шаги пользовательского интерфейса на странице, которой вы владеете.
Мы надеемся, что этот пост в блоге побудит вас начать тщательное тестирование от начала до конца. Раньше мы избегали написания тестов E2E с потоками электронной почты, но, к счастью, мы нашли способ с помощью этих тестов Cypress сэкономить нам много времени, которое мы потратили бы на ручное регрессионное тестирование всего. Мы узнали, что гораздо полезнее автоматизировать и тестировать весь поток счастливого пути, а не его части, если только многие шаги не зависят от сторонних служб, которыми вы не владеете или не управляете, или если невозможно сбросить пользователя обратно к исходному состоянию. определенное состояние надежно.
Если вас интересуют другие сообщения в блогах, связанные с тем, что мы узнали о написании тестов Cypress для наших веб-приложений, ознакомьтесь со следующими статьями:
- Что следует учитывать при написании E2E-тестов
- 1000-футовый обзор написания тестов Cypress
- TypeScript — все, что нужно для ваших тестов Cypress
- Идеи по настройке, организации и объединению ваших тестов Cypress
- Интеграция тестов Cypress с Docker, Buildkite и CICD