Начало работы с TypeScript в Cypress |
29.03.2022 00:00 |
Автор: Филип Рик (Filip Hric) TypeScript в последнее время набирает популярность, и для этого есть веские основания. Он помогает разработчикам создавать свои собственные типы. Это позволяет делать меньше ошибок и создавать самодокументирующийся код. В этой статье я познакомлю вас с основами TypeScript. Использование TypeScript в Cypress Начнем с простого примера. Как всегда, я буду использовать свой клон Trello, который можно скачать с GitHub. В коде ниже очень простой набор шагов. Я открываю приложение и создаю новую доску: /// <reference types="cypress" /> Так как создание новой доски – распространенное действие в моих тестах, я хочу выделить строки 8-14 в отдельную функцию. Эта функция способна принимать аргумент, и мы сможем задавать имя доски при использовании функции. /// <reference types="cypress" /> Возможно, смотря на код, вы заметили, что я оставил функцию .addBoard() пустой. Так как я не вводил текст, тест упадет. Мое приложение не позволяет создавать доски с пустым именем. Давайте просто сменим расширение с .js на .ts и посмотрим, что произойдет в текстовом редакторе.
Как можно видеть, теперь функция показывает ошибку в редакторе. Я сделал скриншот, наведя мышь на подчеркнутую функцию. VS Code дает объяснение – функция ожидает как минимум одного аргумента, но не был задан ни один. Ничто не мешает нам запустить этот код. Однако при использовании TypeScript мы сразу получаем обратную связь о его валидности. Увидев ошибку, мы можем легко ее исправить, передав функции аргумент. Поиграем с этим немного. При помощи TypeScript вы можете определять, какой тип ввода принимать. Так как, очевидно, наш аргумент должен быть строкой, определим тип следующим образом: const addBoard = (input: string) => { Теперь, определив тип нашего аргумента, мы будем получать ошибку при любой попытке передать что-либо другое, вроде Boolean или числа. Для этой функции это немного, но представьте функцию, которая вызывает конечную точку API с разными данными вроде массивов, объектов, строк и чисел. Для этого тоже можно задать типы. Поиграем с типами Возможности для настройки типов очень обширны. Пока что я только поверхностно их затронул, так как сам еще учусь. TypeScript можно долго изучать, поэтому давайте экспериментировать. К примеру, я хочу изменить свою функцию, чтобы она принимала только определенный текст. const addBoard = (input: 'new board' | 'my board') => { Добавив это, я могу уточнять, какие типы ввода принимает моя функция. Что еще приятнее, VS Code автодополняет ввод:
Могу себе представить классные варианты использования. Не уверен, почему, но мне немедленно пришли в голову селекторы атрибута data-cy. У меня есть команда getDataCy – простая обертка вокруг команды Cypress .get(). Она выбирает элементы на основании атрибута data-cy, и мне не приходится каждый раз печатать текст [data-cy=selector]. Что, если я смогу автоматически дополнять свои селекторы? Если я разберусь, подойдет ли такой способ, я дам вам знать в своем блоге. Предположим теперь, что я хочу добавить несколько досок при помощи этой функции. Внутри функции будет цикл с массивом строк, добавляющий все нужные доски. Вместо одной строки можно будет ввести массив строк. const addTodo = (titles: string[]) => { Если я добавлю в функцию addTodo что-то, кроме массива, я немедленно получу ошибку. Еще до запуска моего теста я получаю обратную связь о невалидном использовании функции. Это чудесно помогает при опечатках, неверных типах или забытых запятых. Если вы уже используете TypeScript в вашем проекте, то с шансами большая часть вашего проекта уже содержит типы. Вы сможете повторно использовать типы вашего приложения внутри своих тестов. По моим представлением строгая проверка типов приведет к тому, что изменение в приложении немедленно спровоцирует ошибку в тестах. Использование JSDoc У TypeScript есть еще одна классная функция, которую можно использовать даже с чистым JavaScript. При помощи JSDoc можно добавлять к функциям документацию. В VS Code это можно сделать, введя /** */. Это создаст специальный комментарий, всплывающий при наведении на функцию.
Тут множество различных флагов - @param для объяснения параметров, @example для примера использования команды, @deprecated для пометки команды как потерявшей актуальность. JSDoc с Cypress-командами тоже используется и даже может давать ссылки на документацию. Представьте, как это можно применить к кастомным командам или вашим Page Object, немедленно давая им контекст. Настройка TypeScript в проекте Вернемся чуть назад. Пока что мы просто меняли расширение файла с .js на .ts. Однако прежде, чем мы сможем запустить эти тесты в Cypress, нужно сделать еще две вещи. В документации Cypress есть отличная статья на эту тему. Резюмируя, вам нужно установить TypeScript через npm или yarn, а затем создать tsconfig.json. { Просто копирование и вставка этого в проект уже даст возможность начать работу, однако этот файл можно разнообразно настраивать. Заметьте, что в строке 5 мы определяем типы. Это в точности то же самое, что и добавление /// <reference types="cypress" /> в начале вашего файла для работы автодополнения. При помощи TypeScript это можно не делать – это будет доступно глобально. Создание кастомной команды Теперь вынесем функцию .addBoard() из нашего файла и создадим кастомную команду Cypress. Затем ее можно будет использовать в проекте. support/commands/addBoard.ts Все это здорово, но просто добавление этой команды не включит автодополнение при попытке использования в тестах. Чтобы это сделать, нужно расширить объект cy. Это можно сделать двумя способами. Один из них описан в вышеупомянутой документации. Вам нужно создать файл определений с расширением .d.ts и объявить команду там: support/commands.d.ts Тут есть о чем поговорить, но я не хочу чересчур вдаваться в детали. Простыми словами, мы добавляем нашу Cypress-команду addBoard в интерфейс Cypress. Void в конце функции означает, что наша функция не будет ничего передавать. При желании она может возвращать выбранный элемент или тело ответа на вызов API, в зависимости от того, что мы собираемся делать с этой функцией. Второй способ добавления кастомной команды – добавление определения прямо внутри кастомной команды. Файл будет выглядеть так: support/commands/addBoard.ts Так как тут я не пользуюсь Cypress.Commands.add api и вместо этого экспортирую функцию, мне нужно добавить это в мой файл my support/index.ts или прямо в тест. Обычно это выглядит как-то так: support/index.ts Я нашел этот подход на GitHub, и он мне очень нравится. Он позволяет хранить все в одном и том же файле, что лучше мне подходит. Возможно, это вопрос личных предпочтений. Может также случиться, что я не вижу очевидных проблем (я все еще учусь) – в этом случае сообщите мне об этом через Twitter, LinkedIn или Discord. Буду рад узнать об этом. |