Появление Puppeteer предоставило разработчикам мощный инструмент для автоматизации тестирования веб-приложений. Одним из самых востребованных аспектов в автоматизированном тестировании является возможность фильтровать запросы, отправляемые браузером, для того чтобы ограничить или изменить поведение страницы. В Puppeteer это достигается с помощью возможности перехватывать сетевые запросы, а затем фильтровать их по определённым критериям, таким как тип ресурса или URL.
Перехват сетевых запросов — это процесс, при котором можно перехватывать
запросы, отправляемые браузером, и обрабатывать их до того, как они
попадут на сервер. В Puppeteer для этого используется метод
page.setRequestInterception(true). Он активирует
возможность перехвата запросов на уровне страницы.
const puppeteer = require(&
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', request => {
console.log('Перехваченный запрос:', request.url());
request.continue();
});
await page.goto('https://example.com');
await browser.close();
})();
В этом примере с помощью метода page.on(‘request’, …) мы
настраиваем обработчик для перехвата всех запросов, отправляемых
страницей. Важно заметить, что после перехвата запроса необходимо явно
указать, что делать с ним. Метод request.continue()
сообщает Puppeteer, что запрос должен быть продолжен, и браузер должен
его выполнить.
После того как перехват запроса включён, можно настроить фильтрацию
запросов по их типу. Тип запроса определяется на основе MIME-типа
ресурса, который запрашивается. Для фильтрации по типу используется
свойство request.resourceType(). Это свойство позволяет
определить, какой тип ресурса запрашивается в данный момент.
Типы ресурсов могут включать:
document — HTML-документ
stylesheet — таблица стилей
image — изображение
media — видео или аудио
font — шрифт
script — JavaScript
xhr — AJAX-запросы
fetch — Fetch API запросы
websocket — WebSocket запросы
Пример фильтрации запросов по типу ресурса:
page.on('request', request => {
const resourceType = request.resourceType();
// Пропускаем все запросы, кроме изображений
if (resourceType === 'image') {
request.continue();
} else {
request.abort();
}
});
В данном примере перехватываются все запросы на странице, но выполняются
только те из них, которые касаются изображений. Все остальные запросы
прерываются с помощью метода request.abort().
Кроме того, можно фильтровать запросы по URL. Это особенно полезно, когда необходимо блокировать или изменять поведение запросов к определённым адресам. URL может быть проверен на наличие определённых подстрок или полных совпадений.
Пример фильтрации запросов по URL:
page.on('request', request => {
const url = request.url();
// Пропускаем запросы к домену example.com, остальные блокируем
if (url.includes('example.com')) {
request.continue();
} else {
request.abort();
}
});
В данном примере пропускаются только те запросы, которые содержат
подстроку example.com в URL. Все остальные запросы
блокируются.
Можно использовать регулярные выражения для более гибкой фильтрации:
page.on('request', request => {
const url = request.url();
// Пропускаем запросы к адресам, начинающимся с https://example.com/api/
const apiUrlPattern = /^https:\/\/example\.com\/api\//;
if (apiUrlPattern.test(url)) {
request.continue();
} else {
request.abort();
}
});
В этом примере запросы, которые начинаются с
https://example.com/api/, будут пропущены, а остальные —
заблокированы.
Часто возникает необходимость фильтровать запросы по нескольким критериям одновременно. Для этого можно комбинировать фильтрацию по типу ресурса и URL. Например, можно пропускать только те запросы, которые относятся к изображениям и имеют определённый домен в URL.
Пример комбинированной фильтрации:
page.on('request', request => {
const resourceType = request.resourceType();
const url = request.url();
// Пропускаем только запросы к изображениям с домена example.com
if (resourceType === 'image' && url.includes('example.com')) {
request.continue();
} else {
request.abort();
}
});
Здесь пропускаются только запросы на изображения, если их URL содержит
example.com. Все другие запросы блокируются.
После перехвата запросов может возникнуть необходимость обработки
ответов, приходящих от сервера. Для этого Puppeteer позволяет
подписываться на событие response. Этот метод используется
для анализа и модификации данных, которые приходят в ответ на запросы.
Пример обработки сетевых ответов:
page.on('response', response => {
const url = response.url();
// Логируем ответы только для запросов к API
if (url.includes('/api/')) {
console.log('Ответ от API:', response.status());
}
});
В этом примере мы анализируем все ответы от серверов, чьи URL содержат
подстроку /api/, и логируем их статус.
Если необходимо изменить поведение запроса, например, изменить его URL
или тип, можно воспользоваться методом request.respond().
Это позволяет полностью заменить запрос на новый ответ.
Пример замены ответа на запрос:
page.on('request', request => {
const url = request.url();
if (url.includes('example.com/old-resource')) {
request.respond({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ message: 'Заменённый ответ' })
});
} else {
request.continue();
}
});
В этом примере для определённого URL ответ на запрос заменяется на заранее заданный JSON-объект.
Фильтрация запросов по типу и URL является важной частью тестирования и автоматизации с использованием Puppeteer. Она позволяет не только блокировать нежелательные запросы, но и манипулировать поведением страницы, изменяя или подменяя сетевые ответы. Управление сетевыми запросами помогает ускорить тесты, уменьшить зависимость от внешних сервисов и контролировать поведение приложения на более глубоком уровне.