Service Workers — это скрипты, работающие в фоновом режиме в браузере, которые позволяют управлять сетевыми запросами, кэшированием ресурсов и уведомлениями, обеспечивая офлайн-доступ и улучшая производительность веб-приложений. В контексте JavaScript-тестирования с использованием Karma понимание Service Workers важно для корректной симуляции поведения приложения и проверки его функциональности в различных условиях сети.
Service Worker регистрируется в основном JavaScript-файле приложения:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker зарегистрирован с областью:', registration.scope);
})
.catch(error => {
console.error('Ошибка при регистрации Service Worker:', error);
});
}
Ключевые моменты:
if ('serviceWorker' in navigator) гарантирует
поддержку браузером.register возвращает промис с объектом
регистрации.Жизненный цикл Service Worker включает несколько стадий:
Эти стадии можно отследить через события:
self.addEventListener('install', event => {
event.waitUntil(
caches.open('my-cache-v1')
.then(cache => cache.addAll(['/index.html', '/main.js']))
);
});
self.addEventListener('activate', event => {
console.log('Service Worker активирован');
});
Основная сила Service Worker заключается в возможности перехватывать и модифицировать сетевые запросы:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) {
return response; // Возвращает кэшированную версию
}
return fetch(event.request); // Запрос к сети при отсутствии кэша
})
);
});
Особенности:
event.respondWith() позволяет заменить стандартное
поведение запроса.Использование Cache API обеспечивает офлайн-доступ:
caches.open('dynamic-cache-v1').then(cache => {
cache.put('/data.json', new Response(JSON.stringify({ key: 'value' })));
});
beforeEach(async () => {
const keys = await caches.keys();
await Promise.all(keys.map(key => caches.delete(key)));
});
Настройка окружения:
Асинхронные тесты:
Service Worker работает асинхронно, поэтому тесты должны корректно обрабатывать промисы:
describe('Service Worker fetch', () => {
it('должен возвращать кэшированные данные', async () => {
const response = await caches.match('/index.html');
expect(response).not.toBeNull();
});
});
Изоляция тестов:
Мокирование fetch:
Для контроля сетевых запросов удобно применять spy или stub:
spyOn(window, 'fetch').and.callFake(() => Promise.resolve(new Response('OK')));
Тестирование этих стратегий требует:
Service Worker может обрабатывать push-события и фоновые синхронизации:
self.addEventListener('push', event => {
const data = event.data.json();
event.waitUntil(
self.registration.showNotification(data.title, { body: data.body })
);
});
Тестирование:
localhost. В тестовом окружении Karma это учитывает.karma-serve или кастомного сервера с
HTTPS позволяет корректно тестировать SW.Service Workers позволяют глубоко контролировать поведение приложения в браузере, обеспечивая офлайн-работу, оптимизацию сетевых запросов и push-уведомления. Тестирование через Karma требует особого внимания к асинхронности, кэшированию и изоляции окружения, что обеспечивает надежность тестов и корректное воспроизведение поведения приложения.