Работа с токенами

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

Получение токена через cy.request

Чаще всего токен получается от бекенда по HTTP-запросу. Cypress поддерживает такие вызовы через cy.request, что исключает необходимость использования UI для аутентификации.

Пример

cy.request({
  method: 'POST',
  url: '/api/auth/login',
  body: { username: 'test', password: 'pass' }
}).then((res) => {
  const token = res.body.token;
  // дальнейшая работа с токеном
});

Ключевой момент: получение токена должно происходить до обращения к защищённым ресурсам, иначе сервер вернёт ошибку доступа (чаще всего 401 или 403).

Сохранение и использование токена

Токен может храниться в LocalStorage, SessionStorage, Cookies или прямо в переменной окружения тестов. Выбор зависит от специфики приложения и предпочтений команды.

LocalStorage

Этот подход подходит для SPA-приложений, где клиент самостоятельно добавляет токен в заголовки запросов.

localStorage.setItem('access_token', token);

После установки токена требуется выполнить cy.visit('/'), чтобы приложение подхватило состояние авторизации.

Cookies

При использовании cookies генерал логика проста: Cypress устанавливает cookie с токеном, а сервер считывает её на запросах.

cy.setCookie('access_token', token);

Cookies удобны для доменно-ориентированной аутентификации и сценариев с SSR.

Переменные окружения

Токен можно пробрасывать через cypress.config.js или .env для повторного использования без запросов авторизации.

module.exports = {
  e2e: {
    env: {
      accessToken: token
    }
  }
}

Автоматизация получения токена в хуках Cypress

Для сокращения времени выполнения тестов логично вынести получение токена в хуки before или beforeEach. Такой подход уменьшает дублирование и упрощает поддержку.

before(() => {
  cy.request('POST', '/api/auth/login', {
    username: 'test',
    password: 'pass'
  }).then((res) => {
    cy.wrap(res.body.token).as('token');
  });
});

Далее токен используется в любом тесте через this.token или cy.get('@token').

Подстановка токена в заголовки

Для эмуляции полноценной авторизации токен необходимо добавлять в заголовки запросов.

cy.get('@token').then((token) => {
  cy.request({
    method: 'GET',
    url: '/api/secure/data',
    headers: {
      Authorization: `Bearer ${token}`
    }
  });
});

Практический эффект: Cypress получает доступ к данным, минуя взаимодействие с UI и экономя время.

Проверка истечения срока действия токена

JWT обычно содержит срок жизни (exp). Cypress может проверять корректность обработки таких сценариев бекендом.

  • При истёкшем токене запрос должен вернуть 401.
  • При обновлении токена — выдачу нового значения и повтор запроса.
cy.request({
  method: 'GET',
  url: '/api/secure/data',
  failOnStatusCode: false,
  headers: { Authorization: `Bearer expired-token` }
}).its('status').should('eq', 401);

Эмуляция обновления токена (refresh flow)

При наличии refresh-механизма Cypress способен тестировать цепочку действий клиента:

  1. Запрос с просроченным access-токеном.
  2. Получение нового токена через refresh-эндпоинт.
  3. Повтор исходного запроса.

Каждый шаг фиксирует корректность поведения клиента и сервера.

Хранение токенов между тестами

Cypress очищает состояние между it() по умолчанию, что может приводить к повторным логинам. Для оптимизации используют:

  • preserveOnce() для cookies
  • localStorage snapshot через кастомные команды
  • experimentalSessionAndOrigin или cy.session

Пример с cy.session

cy.session('auth', () => {
  cy.request('POST', '/api/auth/login', { username: 'test', password: 'pass' })
    .then((res) => localStorage.setItem('access_token', res.body.token));
});

Сессия сохраняет токен между тестами, сокращая время авторизации.

Кастомные команды

Локализация логики токенов через Cypress.Commands.add делает тесты чище и проще.

Cypress.Commands.add('login', () => {
  cy.request('POST', '/api/auth/login', {
    username: 'test',
    password: 'pass'
  }).then((res) => {
    localStorage.setItem('access_token', res.body.token);
  });
});

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

cy.login();
cy.visit('/');

Работа с несколькими токенами

В сложных системах могут существовать разные уровни доступа (admin, user, guest). Cypress способен генерировать токены для каждой роли, сохраняя их под алиасами или в переменных окружения. Такой подход позволяет проверять разграничение прав на API и UI-уровне.

Безопасность и изоляция

В тестовой среде допустимо прямое использование токенов, но необходимо исключить их попадание в CI-логи и репозитории. Предпочтительно хранение в переменных окружения CI/CD или в зашифрованных секретах.

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

Особенности интеграции с CI

В CI-средах получение токена обычно выполняется автоматически:

  • запросом к auth-сервису через cy.request
  • передачей токена через секреты pipeline
  • использованием refresh-механизма

Cypress способен работать без UI в headless-режиме, что делает токен-авторизацию особенно выгодной при массовом прогоне тестов.

Выводы по практике

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