Spec-Zone.ru › Cypress

route

Используйте cy.route() для управления поведением сетевых запросов.

⚠️ cy.server() и cy.route() устарели в Cypress 6.0.0. В будущих релизах поддержка cy.server() и cy.route() будет удалена. Рассмотрите использование cy.intercept() вместо этого. См. наше руководство по миграции cy.route() к cy.intercept()

⚠️ cy.route() и cy.server() поддерживают только перехват XMLHttpRequests. Запросы, использующие API Fetch и другие типы сетевых запросов, такие как загрузка страниц и <script> теги, не будут перехватываться cy.route() и cy.server().

Для поддержки запросов, использующих API Fetch, вы можете использовать одно из решений ниже:

  • Используйте cy.intercept(), которое поддерживает запросы, использующие API Fetch, и другие типы сетевых запросов, такие как загрузка страниц. См. cy.intercept().
  • Используйте полифилл window.fetch для слежки за запросами и подстановки ответов, использующих cy.route() и cy.server() путём включения experimentalFetchPolyfill. См. #95 для более подробной информации и временных решений.

Синтаксис

cy.route(url)
cy.route(url, response)
cy.route(method, url)
cy.route(method, url, response)
cy.route(callbackFn)
cy.route(options)

Использование

Правильное использование

cy.route('/users/**')

Аргументы

url (Строка, Шаблон, Регулярное выражение)

Прослушивает маршрут, соответствующий определённому URL.

response (Строка, Объект, Массив)

Предоставляет ответ body для моделирования на совпадающем маршруте.

method (Строка)

Сопоставляет маршрут со специфическим методом (GET, POST, PUT, и т.д.).

Если метод не определён, Cypress по умолчанию будет сопоставлять запросы GET.

callbackFn (Функция)

Прослушивает маршрут, соответствующий возвращаемому объекту из функции обратного вызова. Функции, возвращающие Promise , будут автоматически ожидать завершения.

options (Объект)

Передайте объект опций, чтобы изменить стандартное поведение cy.route(). По умолчанию cy.route() наследует свои опции от cy.server().

Опция Значение по умолчанию Описание
delay 0 Задержка для смоделированных ответов (в мс)
force404 false Принудительно отправляет статус 404, когда XHR не соответствует ни одному существующему cy.route().
headers null Заголовки ответа для смоделированных маршрутов
method GET Метод для сопоставления с запросами
onAbort null Функция обратного вызова, срабатывающая при прерывании XHR
onRequest null Функция обратного вызова при отправке запроса
onResponse null Функция обратного вызова при возвращении ответа
response null Тело ответа при моделировании маршрутов
status 200 Код статуса ответа при моделировании маршрутов
url null Строка или регулярное выражение URL для сопоставления с URL запросов

Вы также можете установить опции для всех cy.wait() по умолчанию requestTimeout и responseTimeout в конфигурации, чтобы управлять временем ожидания запроса и ответа предоставленного маршрута.

Возвращаемые значения

  • cy.route() возвращает null .
  • cy.route() может быть переименован, но в дальнейшем не может быть использован в цепочке.

Примеры

Без моделирования

Если вы не передаёте response в маршрут, Cypress пропустит запрос без моделирования. Мы всё равно можем ожидать разрешения запроса позже.

Ожидание XHR GET запроса, соответствующего url

cy.server()
cy.route('**/users').as('getUsers')
cy.visit('/users')
cy.wait('@getUsers')

Ожидание XHR, соответствующих method и url

cy.server()
cy.route('POST', '**/users').as('postUser')
cy.visit('/users')
cy.get('#first-name').type('Julius{enter}')
cy.wait('@postUser')

Настройка маршрута POST для входа в систему

Посмотрите наш пример рецепта использования cy.route() для POST-запроса входа в HTML-формы

Ожидание url, соответствующего шаблону

Внутри Cypress используется minimatch для сопоставления шаблонов glob url.

Это означает, что вы можете воспользоваться поддержкой * и ** шаблонов glob. Это значительно упрощает маршрутизацию по динамическим сегментам без необходимости создания сложной RegExp.

Мы предоставляем Cypress.minimatch как функцию, которую вы можете использовать в своём консоли для тестирования маршрутов.

Сопоставление маршрута с любым UserId

cy.server()
cy.route('**/users/*/comments')

// https://localhost:7777/users/123/comments     <-- matches
// https://localhost:7777/users/123/comments/465 <-- does not match

Использование шаблона glob для сопоставления всех сегментов

cy.server()
cy.route('**/posts/**')

// https://localhost:7777/posts/1            <-- matches
// https://localhost:7777/posts/foo/bar/baz  <-- matches
// https://localhost:7777/posts/quuz?a=b&1=2 <-- matches

Переопределение url опций сопоставления шаблонов glob

При проверке glob шаблонов с помощью minimatch, по умолчанию Cypress устанавливает matchBase в true. Вы можете переопределить эту опцию в опциях cy.server().

Если вы хотите постоянно переопределить эти опции, вы можете сделать это, установив Cypress.Server.defaults().

cy.server({
  urlMatchingOptions: { matchBase: false, dot: true }
})
cy.route(...)

С моделированием

Если вы передаёте response в cy.route(), Cypress смоделирует ответ на запрос.

url как строка

При передаче string как url, URL XHR должен точно соответствовать вашей записи. Вам необходимо использовать декодированную строку и не включать хеш-кодирование (то есть используйте @ вместо %40).

cy.server()
cy.route('https://localhost:7777/surveys/customer?email=john@doe.com', [
  {
    id: 1,
    name: 'john',
  },
])

url как регулярное выражение

При передаче регулярного выражения как url, URL XHR будет проверен на соответствие регулярному выражению, если пройдёт проверку.

cy.server()
cy.route(/users\/\d+/, { id: 1, name: 'Phoebe' })
// Application Code
$.get('https://localhost:7777/users/1337', (data) => {
  console.log(data) // => {id: 1, name: "Phoebe"}
})

Функции ответа

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

Функции, возвращающие Promise , будут автоматически ожидать завершения.

const commentsResponse = (routeData) => {
  //routeData is a reference to the current route's information
  return {
    data: someOtherFunction(routeData),
  }
}

cy.route('POST', '**/comments', commentsResponse)

Сопоставление запросов и маршрутов

Любой запрос, соответствующий method и url маршрута, будет обработаться в соответствии с его конфигурацией.

GET — это метод HTTP по умолчанию для сопоставления маршрутов. Если вы хотите смоделировать маршрут с другим методом HTTP, например, POST, то вам необходимо явно указать метод.

Если запрос не соответствует ни одному маршруту, поведение зависит от значения опции force404 в cy.server():

  • если force404 равно false (по умолчанию), то запрос будет передан серверу.
  • если force404 равно true , то ответ будет 404.

Вы можете узнать больше об этом поведении здесь.

Указание метода

В следующем примере все запросы DELETE на "/users" моделируют ответ с пустым JSON-объектом.

cy.server()
cy.route('DELETE', '**/users/*', {})

Отправка нескольких запросов на один и тот же маршрут

Вы можете тестировать маршрут несколько раз с уникальными объектами ответов, используя алиасы и cy.wait(). Каждый раз, когда мы используем cy.wait() для алиаса, Cypress ожидает следующего n-го совпадающего запроса.

cy.server()
cy.route('/beetles', []).as('getBeetles')
cy.get('#search').type('Weevil')

// wait for the first response to finish
cy.wait('@getBeetles')

// the results should be empty because we
// responded with an empty array first
cy.get('#beetle-results').should('be.empty')

// now re-define the /beetles response
cy.route('/beetles', [{ name: 'Geotrupidae' }])

cy.get('#search').type('Geotrupidae')

// now when we wait for 'getBeetles' again, Cypress will
// automatically know to wait for the 2nd response
cy.wait('@getBeetles')

// we responded with 1 beetle item so now we should
// have one result
cy.get('#beetle-results').should('have.length', 1)

Фикстуры

Вместо написания ответа непосредственно вы можете автоматически подключить ответ с помощью cy.fixture().

cy.server()
cy.route('**/posts/*', 'fixture:logo.png').as('getLogo')
cy.route('**/users', 'fixture:users/all.json').as('getUsers')
cy.route('**/admin', 'fx:users/admin.json').as('getAdmin')

Вы можете определить cy.route() после получения фикстуры и работы с её данными.

cy.fixture('user').then((user) => {
  user.firstName = 'Jane'
  // work with the users array here

  cy.route('GET', '**/user/123', user)
})

cy.visit('/users')
cy.get('.user').should('include', 'Jane')

Вы также можете ссылаться на фикстуры как на строки напрямую в ответе, передавая алиасированные фикстуры с @.

cy.fixture('user').as('fxUser')
cy.route('POST', '**/users', '@fxUser')

Опции

Передача объекта опций

cy.server()
cy.route({
  method: 'DELETE',
  url: '**/user/*',
  status: 412,
  response: {
    rolesCount: 2,
  },
  delay: 500,
  headers: {
    'X-Token': null,
  },
  onRequest: (xhr) => {
    // do something with the
    // raw XHR object when the
    // request initially goes out
  },
  onResponse: (xhr) => {
    // do something with the
    // raw XHR object when the
    // response comes back
  },
})

Моделирование перенаправления сервера

Ниже мы моделируем возврат сервера 503 со stubbed пустым JSON ответом.

cy.route({
  method: 'POST',
  url: '**/login',
  response: {
    // simulate a redirect to another page
    redirect: '/error',
  },
})

Настройка маршрута для ошибки при POST на вход в систему

Проверьте наш пример «Формы веб-форм XHR», использующий cy.route() для моделирования 503 при POST для входа в систему

Изменение headers

По умолчанию Cypress автоматически устанавливает Content-Type и Content-Length на основе того, как выглядит ваш response body.

Если вы хотите переопределить это, явно передайте headers в виде объекта.

cy.route({
  url: '**/user-image.png',
  response: 'fx:logo.png,binary', // binary encoding
  headers: {
    // set content-type headers
    'content-type': 'binary/octet-stream',
  },
})

Использование задержек для ответов

Вы можете передать параметр delay, который вызывает задержку (в мс) для response для совпадающих запросов. Приведенный ниже пример приведет к задержке ответа на 3 секунды. Это может быть полезно для тестирования состояний загрузки, таких как загрузка спиннеров, в DOM перед ответом на запрос.

cy.route({
  method: 'PATCH',
  url: '**/activities/*',
  response: {},
  delay: 3000,
})

Функция

Установка параметров маршрутизации с помощью функции обратного вызова

cy.route(() => {
  // ...do some custom logic here..

  // and return an appropriate routing object here
  return {
    method: 'POST',
    url: '**/users/*/comments',
    response: this.commentsFixture,
  }
})

Функции, возвращающие промисы, ожидают их выполнения

cy.route(() => {
  // a silly example of async return
  return new Cypress.Promise((resolve) => {
    // resolve this promise after 1 second
    setTimeout(() => {
      resolve({
        method: 'PUT',
        url: '**/posts/**',
        response: '@postFixture',
      })
    }, 1000)
  })
})

Примечания

Отладка

Понимание различия между подставленными и обычными XHR

Cypress указывает, был ли XHR возвращен подставленным ответом или действительно отправлен на сервер в журнале команд.

XHR, которые отображают (XHR STUB) в журнале команд, были подставлены, и их ответ, статус, заголовки и задержка контролировались соответствующим cy.route().

XHR, которые отображают (XHR) в журнале команд, не были подставлены и были переданы непосредственно на сервер.

XHR Command Log when not stubbed

Cypress также записывает в консоль, был ли XHR подставлен или нет, когда вы нажимаете на команду в журнале команд. Это укажет, был ли запрос подставленным, какой URL он сопоставил или что он не сопоставил ни одного маршрута.

XHR Command Log stubbed

Также включен Initiator, который представляет собой стек вызовов, вызвавший отправку XHR.

cy.route() нельзя отлаживать с помощью cy.request()

cy.request() отправляет запросы на фактические конечные точки, минуя те, которые определены с использованием cy.route()

Целью cy.request() является проверка конечных точек на фактическом работающем сервере без необходимости запуска приложения на стороне клиента.

Соответствия

Сопоставление доменов и URL без указания домена

При сопоставлении Cypress исходящего запроса XHR с cy.route(), он фактически пытается сопоставить его как с полным URL, так и без указания домена URL.

cy.route('**/users/*')

Следующие XHR, которые были xhr.open(...) с этими URL, будут:

Совпадают:

  • /users/1
  • http://localhost:2020/users/2
  • https://google.com/users/3

Не совпадают:

  • /users/4/foo
  • http://localhost:2020/users/5/foo

Отсутствие соответствий

Запросы, не соответствующие ни одному маршруту

Вы можете заставить запросы, которые не соответствуют маршруту, возвращать статус 404 и пустое тело, передав параметр в cy.server() следующим образом:

cy.server({ force404: true })

Вы можете прочитать больше об этом здесь.

Правила

Требования

  • cy.route() требует быть привязанным к cy.

Ассерции

  • cy.route() не может содержать связанных ассерций.

Таймауты

  • cy.route() не может иметь таймауты.

Журнал команд

cy.server()
cy.route(/accounts/).as('accountsGet')
cy.route(/company/, 'fixtures:company').as('companyGet')
cy.route(/teams/, 'fixtures:teams').as('teamsGet')

Всякий раз, когда вы запускаете сервер и добавляете маршруты, Cypress отобразит новую панель инструментов под названием «Маршруты». Она будет отображать таблицу маршрутизации на панели инструментов, включая method, сопоставленный шаблон URL, stubbed, alias и количество сопоставленных запросов:

Command Log routing table

При выполнении XHR Cypress будет регистрировать их в журнале команд и указывать, соответствуют ли они псевдониму маршрутизации:

Command Log XHR alias route

Круговой индикатор заполнен, если запрос был отправлен на целевой сервер, но не заполнен, если запрос был подставлен с ответом.

Console Log XHR alias route

Дополнительная информация о регистрации запросов в Cypress.

История

Версия Изменения
6.0.0 Команда cy.route() устарела

См. также

  • Миграция cy.route() в cy.intercept()
  • .as()
  • cy.fixture()
  • cy.server()
  • cy.wait()
  • Руководство: Сеть запросов
  • Рецепт: Вход в систему - формы XHR веб-форм

© 2017 Cypress.io
Licensed under the MIT License.
https://docs.cypress.io/api/commands/route

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API