Программатическая аутентификация

Программатическая аутентификация в Cypress позволяет миновать интерфейсные формы входа и пройти авторизацию напрямую через API или собственные внутренние механизмы приложения. Такой подход делает тесты стабильнее: исключается зависимость от сложных UI-компонентов, снижается время выполнения тестов и устраняются лишние шаги, несущие не бизнес-ценность.

Большинство современных веб-приложений реализуют вход по токенам, кукам или session-id. Cypress способен взаимодействовать с этим слоем непосредственно благодаря cy.request.

Ключевые моменты:

  • Использование REST или GraphQL запросов для получения токена доступа.
  • Установка токена или cookies в браузерный контекст перед переходом на защищённые страницы.
  • Сохранение и восстановление состояния между тестами для ускорения прогонов.

Пример запроса к API для получения токена:

cy.request('POST', '/api/auth/login', {
  username: 'test_user',
  password: 'secret'
}).then(({ body }) => {
  window.localStorage.setItem('access_token', body.token)
})

После записи токена достаточно выполнить cy.visit любой защищённой страницы — приложение распознает валидную сессию.

Работа с cookies и session-id

Некоторые приложения используют cookies вместо localStorage. Cypress предоставляет команды cy.setCookie и cy.getCookie.

Важно:

  • Cookie должны быть установлены до cy.visit, иначе сервер может не идентифицировать сессию.
  • Для доменных cookies необходимо соответствие пути и домена.

Пример установки cookie:

cy.request('POST', '/login', {
  user: 'admin',
  password: '1234'
}).then((res) => {
  cy.setCookie('session_id', res.body.sessionId)
})
cy.visit('/dashboard')

Сценарии с refresh-token

В архитектуре с короткоживущими access-token часто присутствует refresh-token, выдаваемый браузеру. Cypress способен воспроизводить эту логику без UI.

Типовая последовательность:

  1. Получение пары access и refresh.
  2. Обновление access-token по истечении срока.
  3. Запись актуальных значений в localStorage или cookies.
  4. Взаимодействие с API на защищённых эндпоинтах.

Кодовый пример обновления токена:

function refreshToken(refresh) {
  return cy.request('POST', '/api/auth/refresh', { refresh })
}

cy.request('POST', '/api/auth/login', { username, password })
  .then((res) => {
    const { access, refresh } = res.body
    window.localStorage.setItem('access', access)
    window.localStorage.setItem('refresh', refresh)
    return refreshToken(refresh)
  })
  .then((res) => {
    window.localStorage.setItem('access', res.body.access)
  })
cy.visit('/profile')

Встраивание аутентификации в beforeEach

При наличии большого количества тестов программная аутентификация помещается в beforeEach, что избавляет от повторяющегося кода.

Пример структуры:

beforeEach(() => {
  cy.request('POST', '/api/auth/login', {
    username: 'qa',
    password: 'pass'
  }).then(({ body }) => {
    window.localStorage.setItem('token', body.access)
  })
})

Каждый тест начинает выполнение уже в авторизованном состоянии, что особенно полезно для тестирования внутренних разделов.

Сохранение и восстановление сессий

Модуль cy.session оптимизирует повторное выполнение сценариев входа. Он позволяет кэшировать состояние между тестами в рамках одного прогона.

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

Cypress.Commands.add('login', () => {
  cy.session('user_qa', () => {
    cy.request('POST', '/api/auth/login', {
      username: 'qa',
      password: 'pass'
    }).then(({ body }) => {
      window.localStorage.setItem('token', body.access)
    })
  })
})

После определения можно вызвать cy.login() в beforeEach и избавить тесты от повторного запроса аутентификации.

Гибридные методы

Иногда сервер требует дополнительную логику (например MFA, CSRF-токены или preflight-handshake). В таких ситуациях используется гибридный подход:

  • Получение cookies и токенов через API.
  • Выполнение промежуточных действий через UI или вспомогательные запросы.
  • Завершение входа через установку состояния в браузер.

Подобная комбинация сохраняет производительность и надёжность, позволяя покрыть сложные кейсы.

Взаимодействие с прокси и мокированием

При интеграции Cypress с обратными прокси или сервисами аутентификации вроде OAuth удобнее имитировать успешный вход, заменяя реальный обмен токенами stub-ответами.

Используются cy.intercept для возврата подготовленных данных:

cy.intercept('POST', '/oauth/token', {
  access_token: 'fake_access',
  refresh_token: 'fake_refresh'
})
window.localStorage.setItem('access_token', 'fake_access')
cy.visit('/account')

Такая техника подходит для unit-ориентированных e2e-сценариев, когда сама логика OAuth уже протестирована отдельно.

Практические рекомендации

Минимизация связанности: программный вход должен зависеть только от API-контракта, но не от UI.

Детерминированность: токены и cookies необходимо задавать явно, избегая неявных сторонних зависимостей.

Производительность: использование cy.session и вынесение логики в команды Cypress обеспечивает существенное ускорение среднего тестового прогона.

Отладка: в сложных случаях отображение localStorage, cookies и сетевых запросов в DevTools ускоряет диагностику, а Cypress предоставляет логи и реплеи запросов для анализа.