Разделы портала

Онлайн-тренинги

.
Автодополнение селекторов в Cypress при помощи TypeScript
25.03.2022 00:00

Автор: Филип Рик (Filip Hric)
Оригинал статьи
Перевод: Ольга Алифанова

Вы узнаете:

  • Как создать кастомную команду, автоматически дополняющую ваши селекторы
  • Как выполнить проверку тестов, написанных на TypeScript
  • Как грепнуть селекторы из приложения
  • Как создать предупреждение, если в приложении есть неиспользуемые селекторы.

Cypress советует использовать селекторы data-cy в качестве лучшей практики для выбора элементов на странице. Недавно мы отлично подискутировали в дискорде, действительно ли эта практика хороша. Лично я сильно склоняюсь к "да". Если вы в моем лагере, у меня есть для вас ряд полезных советов.

Использование селекторов data-* с кастомными командами

Если вы часто пользуетесь селекторами data-*, то с шансами вам пригодится кастомная команда.

If you are using data-* selectors a lot, chances are you want to create a custom command.

Cypress.Commands.add('getDataCy', (input) => {
    return cy.get(`[data-cy='${input}']`);
})

Таким образом вы можете пропустить часть [data-cy="], используя команду .get(). Если вам нужна более модная версия, я написал об этом статью, объясняя, как улучшить логи для вашей кастомной команды.

Используя TypeScript, вы можете конкретнее определить, какой тип ввода будет получать ваша свежесозданная кастомная команда. Как правило, это что-то простое, вроде input: string. Однако вместо этого можно создать свой собственный тип, который ограничит возможный ввод, передаваемый в функцию.

type Selectors = 'board' | 'list' | 'card'
 
Cypress.Commands.add('getDataCy', (input: Selectors) => {
     return cy.get(`[data-cy='${input}']`);
})

В этом случае TypeScript выдаст ошибку, если мы используем неразрешенный селектор:

 

Создание файла селекторов

Список селекторов может сильно разрастись со временем. Поэтому, возможно, хорошей идеей будет держать его в отдельном файле. Я создаю файл selectors.d.ts и держу там все мои селекторы. Как правило, я храню его в папке cypress/support/@types/.

cypress/support/@types/selectors.d.ts
type Selectors =
     | 'board'
     | 'list'
     | 'card'
      // ...

Когда я добавляю в приложение новый селектор, его нужно добавить в список, иначе я получу ошибку. С другой стороны, при использовании селектора, уже существующего в списке, я получаю приятное автодополнение в коде VS.


Проверка селекторов

Конечно, мы можем попасть в ситуацию, когда селектор из списка удален, и это незаметно, пока мы не откроем тест-файл, или пока не запустятся наши тесты. Так как мы используем TypeScript, мы можем создать скрипт typecheck, который будет искать ошибки TypeScript. Этот скрипт будет использовать флаг –noEmit, так как компилировать файлы не нужно. Это делает Cypress при прогоне наших тестов.

package.json
// ...
"scripts": {
      "typecheck": "tsc --noEmit -p ."
}
// ...

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

scripts/getSelectors.sh
#!/usr/bin/env bash
 
SRC_SELECTORS=$(grep -hro 'data-cy="[^"]*"' src | cut -d \" -f2 | sort | uniq)

Затем я применяю этот корявый способ генерации всех селекторов в файл cypress/support/@types/selectors.d.ts. Корявый, ну и что, работает же!

scripts/getSelectors.sh
#!/usr/bin/env bash
 
SRC_SELECTORS=$(grep -hro 'data-cy="[^"]*"' src | cut -d \" -f2 | sort | uniq)
echo $SRC_SELECTORS | sed "s/ /'\n| '/g; s/^/&export type Selectors = \n| '/; s/.$/&'/;" | cat > cypress/support/@types/selectors.d.ts

Таким образом при удалении любого селектора из исходного кода я немедленно замечу это, запуская npm run typecheck.

Поиск неиспользуемых селекторов data-cy

Мне так это понравилось, что я решил грепнуть свои тесты. Затем я сравнивал селекторы с селекторами кода и выводил предупреждение о лишних селекторах.

scripts/getSelectors.sh
#!/usr/bin/env bash
# find all selectors in src folder
SRC_SELECTORS=$(grep -hro 'data-cy="[^"]*"' src | cut -d \" -f2 | sort | uniq) TEST_SELECTORS=$(grep -hro '.getDataCy([^"]*' cypress | cut -d \' -f2 | sort | uniq
# find all selectors in cypress folder)
# compare selector lists
UNUSED_SELECTORS=$(comm -23 <(echo "$SRC_SELECTORS") <(echo "$TEST_SELECTORS"))
# if any found in src, print them our
if [[ $UNUSED_SELECTORS != "" ]]; then
echo -e "WARNING! There are some selectors in your app that are not being used:
$UNUSED_SELECTORS"
fi
# create selectors.d.ts from all selectors found in src
echo $SRC_SELECTORS | sed "s/ /'\n| '/g; s/^/&export type Selectors = \n| '/; s/.$/&'/;" | cat > cypress/support/@types/selectors.d.ts
fi

Думаю, что есть способы справиться с этим и получше – я не эксперт в скриптах оболочки. Этот скрипт находится в моем проекте Trello – комментируйте и добавляйте пулл-реквесты по улучшению!

Обсудить в форуме