Тестирование кэша браузера

Веб-приложения активно используют кэш браузера для повышения производительности. Однако наличие кэша может влиять на корректность тестов, приводя к ложноположительным или ложноотрицательным результатам. В Protractor, инструменте для e2e-тестирования Angular и других приложений, важно уметь управлять кэшем, очищать его перед тестами и проверять поведение приложения при различных состояниях кэша.


Управление кэшем через настройки браузера

Protractor работает поверх WebDriver, что позволяет управлять сессией браузера и его настройками. Для контроля кэша используются параметры запуска браузера:

exports.config = {
  capabilities: {
    browserName: 'chrome',
    chromeOptions: {
      args: [
        '--disable-application-cache', // Отключение кэша приложения
        '--incognito',                // Режим инкогнито для чистой сессии
        '--disable-cache'             // Отключение кэша браузера
      ]
    }
  }
};

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

  • --disable-application-cache запрещает использование кэша веб-приложения, что полезно для проверки актуальности ресурсов.
  • Режим инкогнито гарантирует, что все предыдущие данные пользователя (cookies, локальный кэш) не влияют на тест.
  • --disable-cache работает для сетевого кэша браузера, заставляя браузер заново загружать все ресурсы.

Очистка кэша между тестами

Даже при отключении кэша на уровне запуска браузера иногда требуется программная очистка. В Protractor для этого можно использовать WebDriver API:

beforeEach(async () => {
  await browser.executeScript('window.sessionStorage.clear();');
  await browser.executeScript('window.localStorage.clear();');
  await browser.driver.manage().deleteAllCookies();
});

Разбор операций:

  1. window.sessionStorage.clear() — очищает временное хранилище сессии.
  2. window.localStorage.clear() — удаляет все данные, сохранённые локально для приложения.
  3. deleteAllCookies() — убирает cookies, которые также могут использоваться для кэширования авторизации или состояния страницы.

Проверка поведения приложения с кэшем

Для полноценного тестирования необходимо проверять, как приложение реагирует на существующий кэш. Это особенно важно для SPA (Single Page Application), где данные могут сохраняться в localStorage или sessionStorage.

Пример теста:

it('должно корректно обновлять данные при наличии кэша', async () => {
  // Имитируем кэшированное состояние
  await browser.executeScript('window.localStorage.setItem("userData", JSON.stringify({name: "Test"}));');

  await browser.get('/dashboard');
  
  const userName = await element(by.id('user-name')).getText();
  expect(userName).toBe('Test');

  // Проверяем обновление данных после очистки кэша
  await browser.executeScript('window.localStorage.clear();');
  await browser.refresh();

  const updatedName = await element(by.id('user-name')).getText();
  expect(updatedName).not.toBe('Test');
});

Особенности:

  • Скрипты через executeScript позволяют эмулировать любое состояние кэша.
  • После очистки данных требуется перезагрузка страницы (refresh()), чтобы браузер заново загрузил ресурсы.
  • Такой подход помогает выявить ошибки, связанные с устаревшей информацией в localStorage или sessionStorage.

Принудительное обновление ресурсов

Иногда необходимо протестировать обновление статических ресурсов, таких как JS и CSS, которые могут кэшироваться браузером. Для этого можно использовать стратегию “cache busting”:

await browser.get('/app?cacheBust=' + new Date().getTime());

Пояснение:

  • Добавление уникального параметра в URL заставляет браузер загрузить новый ресурс, игнорируя кэш.
  • Это особенно полезно при тестировании обновлений интерфейса или исправлений багов, связанных с устаревшими скриптами.

Логирование и анализ кэшированных запросов

Protractor позволяет анализировать сетевые запросы через интеграцию с браузерными инструментами разработчика или сторонними библиотеками:

const perfLogs = await browser.manage().logs().get('performance');

perfLogs.forEach(log => {
  const message = JSON.parse(log.message).message;
  if (message.method === 'Network.responseReceived') {
    console.log(message.params.response.url, message.params.response.fromCache);
  }
});

Что важно:

  • Поле fromCache указывает, был ли ответ сервера взят из кэша.
  • Анализ логов помогает выявлять участки приложения, которые неправильно обрабатывают кэшированные данные.

Тестирование в разных браузерах

Разные браузеры ведут себя по-разному с кэшем. Chrome, Firefox и Edge поддерживают схожие подходы, но различия могут проявляться в обработке service worker, localStorage и кэширования AJAX-запросов. В Protractor рекомендуется создавать конфигурации для нескольких браузеров и использовать одинаковые стратегии очистки кэша:

multiCapabilities: [
  { browserName: 'chrome', chromeOptions: { args: ['--incognito'] } },
  { browserName: 'firefox', 'moz:firefoxOptions': { args: ['-private'] } }
]

Тонкости работы с Angular-приложениями

Для Angular-приложений важно учитывать, что HTTP-запросы часто кэшируются через сервисы HttpClient и интерсепторы. При тестировании кэша стоит проверять:

  • Поведение при повторных GET-запросах.
  • Обновление данных при смене состояния (например, после логина).
  • Корректность работы cache-busting для динамических шаблонов и JSON-файлов.

Использование Protractor в связке с очисткой sessionStorage, localStorage и cookies позволяет воспроизводить любые сценарии, где кэш может повлиять на пользовательский опыт.