Как я могу надежно ждать запросов XHR после загрузки страницы в тесте Cypress?

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

У меня есть тест на кипарис, который в основном посещает страницу, применяет некоторые фильтры и проверяет, что содержимое в dom выглядит правильно:

it(`filters the data by 'price'`, () => {
  cy.server()
  cy.route('POST', 'http://my-api.biz/api').as('apiRequest')

  cy.visit('/')

  // initial page load loads the min and max price bounds for the UI,
  // as well as the data to initially populate the page. they happen
  // to hit the same URL with different POST params
  cy.wait(['@apiRequest', '@apiRequest'])

  cy.get('#price-filter-min').type('1000')
  cy.get('#price-filter-max').type('1400')

  // wait for data to get refreshed
  cy.wait('@apiRequest')

  cy
    .get('[data-test-column = "price"]')
    .each($el => {
      const value = parseFloat($el.text())
      expect(value).to.be.gte(1000)
      expect(value).to.be.lte(1400)
    })
})

однако иногда кажется, что кипарис загружает страницу, запросы XHR ожидают перед, а затем время от времени он не работает:

CypressError: Timed out retrying: cy.wait() timed out waiting 30000ms for the 2nd response to the route: 'apiRequest'. No response ever occurred.

потому что он ожидает запроса, который уже произошел.

есть ли лучший способ написать этот тест? есть ли способ посетить страницу и дождаться запросов XHR, который позволяет избежать этого состояния гонки?

ОБНОВИТЬ

Я попытался воссоздать это в изолированном тестовом примере, но, похоже, все работает правильно, поэтому, вероятно, есть какая-то ошибка оператора.

Приносим извинения за неудобства - я сделал только некоторые грамматические исправления, в чем проблема?

peterh 27.12.2020 17:31

@ peterh-ReinstateMonica Я предпочитаю то, как я изначально написал вопрос, он лучше читается с недостатками IMO. если вы можете воздержаться от редактирования, я был бы признателен!

schpet 28.12.2020 18:19

Я считаю, что такой контент бесполезен, точнее: вредный. Я готов проголосовать против. Все они. Для вас это не проблема?

peterh 28.12.2020 20:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
17
3
30 794
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Поскольку вы используете cy.visit('/'), я предполагаю, что в вашей конфигурации установлен baseUrl. Параметр URL в cy.route() делает baseUrl + строку, которую вы передаете в качестве параметра за кулисами.

Таким образом, URL-адрес, на который отправляется запрос POST, - это http://my-api.biz/apihttp://my-api.biz/api или что-то в этом роде.

Попробуйте изменить команду маршрута на:

cy.route('POST', '/api/foobar').as('apiRequest')

Дополнительная документация и примеры:https://docs.cypress.io/guides/guides/network-requests.html#Fixtures

Если вы проверите это, вы обнаружите, что это неверно. baseUrl не участвует в сопоставлении маршрута.

eric99 12.04.2018 23:18

Да, это. Посмотрите на примеры здесь: docs.cypress.io/api/commands/route.html Я также успешно реализую это во всех своих тестах.

TJH 13.04.2018 00:14

Где это относится к baseUrl на этой странице?

eric99 13.04.2018 01:03

Посмотрите на примеры. Используют ли они «website.com/route» или «/ route»?

TJH 13.04.2018 01:11

Судя по тому, что вы говорите, существует неправильное понимание того, что делает cy.route() - он соответствует маршруту, а не вызывает его.

eric99 13.04.2018 01:20

Если у вас cy.wait(..).then(xhr => console.info(...)), вы не увидите предложенный вами URL-адрес мешанины.

eric99 13.04.2018 01:23

Если вы смотрите на опцию matchBase, это значит Minimatch # Matchbase

eric99 13.04.2018 01:33

Вы можете сделать что-то вроде этого

// Give an alias to request
cy.server().route('GET', '/odata/locations/**').as('dataGetFirst');

// Visit site
cy.visit('admin/locations');

// Wait for response.status to be 200
cy.wait('@dataGetFirst').its('status').should('be', 200);

// Continue

Спасибо! Похоже, что маршрут тоже чувствителен к регистру, так что следите за этим

thul 09.07.2020 21:17

Пришлось заменить: cy.wait('@dataGetFirst').its('status').should('be', 200); на cy.wait('@cartIsUpdating').its('status').should('equal', 200);

Zeth 21.10.2020 15:35

Подобно Зету, мне пришлось сделать cy.wait('@getSomething').its('response.statusCode').should('‌​equal', 200). Может это потому, что cy.server теперь заменен на cy.intercept? Ответ должен быть обновлен до текущей версии Cypress.

Sjeiti 11.01.2021 18:02
Ответ принят как подходящий

Так что большинство ответов сейчас устарели. Начиная с [email protected], вы должны использовать intercept().

Вот как я сделал свой:

cy.intercept({
      method: "GET",
      url: "http://my-api.biz/api/**",
    }).as("dataGetFirst");
cy.wait("@dataGetFirst");

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

красивый! Я дам кипарису преимущество сомнения здесь и приму это, чтобы людям было легче открыть для себя новый api

schpet 09.02.2021 17:33

Другие вопросы по теме