Перевод статьи «Playing with experimental network stubbing feature in Cypress».
Примечание: В версии 6 была выпущена экспериментальная сетевая заглушка, а команда
.route2()
была переименована в.intercept()
. Кроме того, команда.route()
в этой версии была устаревшей. Чтобы узнать, как можно перевести свои.route()
команды на.intercept()
, рекомендую прочитать мой пост в блоге об этом. Там вы найдете примеры и много полезных ссылок.
В начале сентября компания Cypress выпустила новую экспериментальную функцию под названием
. Я решил подробнее изучить, что она делает. Ниже я поделюсь с вами примерами кода.experimentalNetworkStubbing
В версии 5.1.0 и выше эту возможность можно включить, добавив в файл cypress.json следующую строку:
{ "experimentalNetworkStubbing": true }
Это позволяет использовать команду.route2()
, которая описана в документации Cypress. Представьте себе команду .route()
, но более мощную. Скоро вы все поймете.
Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ
Возможности .route()
Если бы кто-нибудь спросил меня о моей любимой команде в Cypress, то это была бы .route()
. С помощью простого синтаксиса вы можете наблюдать, как выполняется ваш api вызов:
cy .server() .route({ method: 'GET', url: '/todos' }).as('todoslist'); cy .visit('/'); // open page cy .wait('@todoslist'); // items load from server via api
После открытия нашего приложения оно загружает список товаров из базы данных. Для этого отправляется запрос GET к URL-адресу /todos. Ответ приходит в виде простого json-файла, который затем отображается в нашем приложении. Если вы хотите изменить этот ответ и предоставить своему приложению собственный json-список элементов, просто добавьте еще один параметр:
cy .server() .route({ method: 'GET', url: '/todos', response: 'fx:items' // fixtures/items.json }).as('todoslist'); cy .visit('/'); // open page cy .wait('@todoslist'); // items load from server via api
Это простая, но очень мощная функция для тестирования вашего приложения. Команда .route()
позволяет заглянуть в любой xhr-запрос, который делает ваше приложение, и протестировать его. Вы можете объединить api и ui тесты в один.
Однако проблема с этой командой заключается в том, что вы можете работать только с xhr-запросами. Это исключает возможность работы с fetch-запросами или другими активами, загружаемыми по сети.
Возможности .route2()
С помощью команды .route2()
вы можете направлять запросы на выборку так же, как это делается с помощью XHR. Довольно удобно.
cy .route2({ method: 'POST', path: '/todos' }) .as('createTodo'); cy .visit('/'); cy .addItem('new todo item'); // fetch request fired when adding item cy .wait('@createTodo'); // it works!!
Но это еще не все. Вы можете маршрутизировать статические файлы, такие как CSS или изображения. Это может оказаться очень удобным, если вы хотите протестировать веб-сайт с отложенной загрузкой изображений:
cy .route2('/vendor/index.css') .as('css'); cy .route2('/vendor/cypress-icon.png') .as('logo'); cy .visit('/'); cy .wait('@css') .wait('@logo');
Но и это не все! С помощью команды .route2()
вы можете изменить не только ответ на api вызов, но и сам запрос. Допустим, мы хотим добавить в запрос пользовательский заголовок, чтобы сервер знал, что это запросы от приложения, которое в данный момент тестируется. Вы можете манипулировать заголовками запроса следующим образом:
cy .route2({ method: 'POST', path: '/todos' }, (req) => { req.headers['Mr-Meeseeks'] = 'Look at me!!'; }) .as('createTodo'); cy .visit('/'); cy .addItem('new todo item');
Этот новый заголовок невозможно увидеть на сетевой панели в DevTools, поскольку манипуляция с запросом фактически происходит вне браузера — до того, как запрос будет отправлен на сервер. По этой причине DevTools отображает исходные заголовки запросов. Но в терминале, где вы выполнили команду npm start
, вы можете видеть, что я регистрирую все заголовки запросов для запроса POST/todos, и там виден наш недавно добавленный заголовок:
{ connection: 'keep-alive', host: 'localhost:3000', 'proxy-connection': 'keep-alive', 'content-length': '61', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', 'content-type': 'application/json', accept: '*/*', origin: 'http://localhost:3000', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', referer: 'http://localhost:3000/', 'accept-encoding': 'gzip', 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 'mr-meeseeks': 'Look at me!!' }
Точно так же, как мы изменили заголовки, мы можем изменить тело запроса. Наше приложение берет название элемента задачи из нашего текстового ввода. Как только мы нажимаем клавишу ввода, этот ввод отправляется через запрос выборки на наш сервер. При использовании .route2()
мы можем изменить то, что отправляется на сервер, или даже добавить свои собственные данные.
cy .route2({ method: 'POST', path: '/todos' }, (req) => { const requestBody = JSON.parse(req.body); req.body = JSON.stringify({ ...requestBody, title: 'Wubba Lubba Dub Dub!' }); }) .as('createTodo'); cy .visit('/'); cy .addItem('new todo item');
Все эти примеры можно найти в репозитории. Не стесняйтесь экспериментировать с ним.