Как позволить Cypress-тестам обходить все кеши (Varnish, Redis и т.п.)

На сайте у меня есть такая инфраструктура кеширования:

После развертывания я хотел бы получить «свежую» и некэшированную версию сайта для моих Cypress-тестов. Я не хочу очищать кеш для всех посетителей. Я просто хочу, чтобы мои тесты Cypress видели некэшированную версию после развертывания.

Моя идея заключалась в том, чтобы добавить заголовок ко всем моим cy.visit и cy.request, а затем настроить параметры Varnish-кэша, чтобы найти его. И обработка этого в Redis также.

Кажется, что это довольно громоздко, но выполнимо на самом деле выполнить эту настройку «обхода кэша» в Varnish и Redis. Если у кого-то есть лучший/более простой способ сделать это, я внимательно слушаю.

В чем суть этого вопроса: «Как мне отправить заголовок со всеми моими cy.visit и cy.request без необходимости каждый раз вводить его вот так (см. ниже)?»

cy.request({
  method: 'GET',
  url: 'https://example.org',
  headers: {
    'x-my-custom-header': 'myValue'
  }
}).then((response) => {
  // ... 
});

cy.visit('/', {
  headers: {
    'x-my-custom-header': 'myValue'
  }});

Мои соображения по решению

Я подумывал о создании собственной команды поверх этого. Но он быстро становится длиннохвостым и неуклюжим.

Я также подумал, смогу ли я перехватить все запросы и добавить к ним заголовок в beforeEach в моем e2e.js. Однако я не смог заставить это работать. Это была моя попытка:

beforeEach(() => {
  cy.intercept('*', (req) => {
    req.headers['x-foo'] = 'bar';
  });
});
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
138
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Запросы, исходящие из теста (обрабатываются с помощью перехвата)

Вы не упомянули проблему с перехватом, просто она есть. Если в конвейере есть другие перехваты, опция middleware гарантирует, что заголовки будут добавлены до вызова этих других перехватов.

Передача запроса следующему обработчику запроса

// you could have a top-level middleware handler that
// sets an auth token on all requests
// but remember setting `middleware: true` will
// cause this to always be called first
cy.intercept('http://api.company.com/', 
  { middleware: true },              <--  don't block the intercepts in the tests
  (req) => {
    req.headers['authorization'] = `token ${token}`
  }
)

Пример

beforeEach(() => {
  cy.intercept('*', { middleware: true }, (req) => {
    req.headers['x-nocache'] = '123'
  }).as('header-added')
})

it('/todos/1 with additional header', () => {

  cy.intercept('https://jsonplaceholder.typicode.com/todos/1')
    .as('wait-for-response')

  cy.window().then(win => win.fetch('https://jsonplaceholder.typicode.com/todos/1'))

  cy.wait('@wait-for-response')
    .its('request')
    .its('headers')
    .its('x-nocache')
    .should('eq', '123')
})

it('/todos/2 with additional header', () => {

  cy.window().then(win => win.fetch('https://jsonplaceholder.typicode.com/todos/2'))

  cy.wait('@header-added')
    .its('request')
    .its('headers')
    .its('x-nocache')
    .should('eq', '123')
})


Запросы, исходящие из теста (не обрабатываемые перехватом)

Использование специальной команды для добавления заголовка ко всем cy.request()

Cypress.Commands.overwrite("request", (originalFn, ...args) => {
  const {_} = Cypress
  const isMethod = (a) => ['GET','POST','PUT','PATCH','DELETE'].includes(a)

  let options = { headers: {} }
  if (_.isObject(args[0])) {
    _.extend(options, args[0])
  } else if (args.length === 1) {
    options.url = args[0]
  } else if (args.length === 2 && isMethod(args[0])) {
    options.method = args[0]
    options.url = args[1]
  } else if (args.length === 2 && _.isObject(args[1])) {  
    options.url = args[0]
    options.body = args[1]
  } else if (args.length === 3) {
    options.method = args[0]
    options.url = args[1]
    options.body = args[2]
  }

  options.headers['x-nocache'] = '123'
  return originalFn(options)
})

cy.request('https://jsonplaceholder.typicode.com/todos/3')
  .its('requestHeaders').should('have.property', 'x-nocache', '123')

cy.request({url: 'https://jsonplaceholder.typicode.com/todos/3', headers:{'x-other': 'abc'}}) 
  .its('requestHeaders')
  .should(requestHeaders => {
    expect(requestHeaders['x-nocache']).to.eq('123')
    expect(requestHeaders['x-other']).to.eq('abc')
  })

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