Puppeteer — это библиотека для управления браузером Chrome или Chromium через протокол DevTools, которая позволяет автоматизировать действия пользователя, тестировать интерфейсы и производить скрейпинг. Интеграция с GraphQL открывает возможности для более глубокого тестирования сложных веб-приложений, где клиентский интерфейс активно взаимодействует с сервером через GraphQL API.
Для начала необходимо установить Puppeteer через npm:
npm install puppeteer
Создается базовый скрипт запуска браузера:
const puppeteer = require(&
(async () => {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com');
// Дальнейшие действия
await browser.close();
})();
Важно использовать режим headless: false для отладки, чтобы
видеть происходящее в браузере.
GraphQL запросы обычно отправляются через POST на один и
тот же endpoint, например /graphql. Puppeteer позволяет
перехватывать и анализировать такие запросы с помощью
page.on(‘request’, callback):
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url().includes('/graphql') && request.method() === 'POST') {
const postData = request.postData();
console.log('GraphQL запрос:', postData);
}
request.continue();
});
Ключевое преимущество: возможность проверять, какие именно данные отправляются на сервер, и сравнивать их с ожидаемыми значениями.
Иногда необходимо тестировать поведение приложения при изменении данных на уровне запросов. Puppeteer позволяет перехватывать и модифицировать запросы:
page.on('request', request => {
if (request.url().includes('/graphql') && request.method() === 'POST') {
const data = JSON.parse(request.postData());
if (data.operationName === 'GetUser') {
data.variables.userId = 'mocked-id';
}
request.continue({ postData: JSON.stringify(data) });
} else {
request.continue();
}
});
Такой подход позволяет симулировать различные сценарии без изменения сервера или базы данных.
Для проверки корректности данных, возвращаемых сервером, используют
response события:
page.on('response', async response => {
if (response.url().includes('/graphql') && response.request().method() === 'POST') {
const json = await response.json();
if (json.data && json.data.user) {
console.log('Проверка данных пользователя:', json.data.user);
}
}
});
Это позволяет убедиться, что интерфейс получает правильные данные и корректно их отображает.
Для полноценного тестирования рекомендуется интегрировать Puppeteer с фреймворками тестирования, такими как Jest или Mocha. Пример с Jest:
const puppeteer = require('puppeteer');
describe('GraphQL тестирование', () => {
let browser;
let page;
beforeAll(async () => {
browser = await puppeteer.launch({ headless: true });
page = await browser.newPage();
});
afterAll(async () => {
await browser.close();
});
test('Запрос пользователя через GraphQL', async () => {
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url().includes('/graphql') && request.method() === 'POST') {
const data = JSON.parse(request.postData());
expect(data.operationName).toBe('GetUser');
}
request.continue();
});
await page.goto('https://example.com/users');
// Действия, вызывающие GraphQL запрос
});
});
Для тестов, которые не зависят от внешнего сервера, используется мокирование ответов:
page.on('request', request => {
if (request.url().includes('/graphql')) {
const response = {
status: 200,
contentType: 'application/json',
body: JSON.stringify({
data: {
user: { id: '123', name: 'Mock User' }
}
})
};
request.respond(response);
} else {
request.continue();
}
});
Такой метод позволяет полностью контролировать возвращаемые данные и тестировать интерфейс в изоляции.
operationName — уменьшает
вероятность перехвата посторонних запросов.
await для request.continue() и
response.json() предотвращает ошибки с несвоевременной
обработкой данных.
headless:
false и вывод в консоль помогает выявлять ошибки на ранних
этапах.
Интеграция Puppeteer с GraphQL делает тестирование более точным, позволяя анализировать и управлять запросами и ответами на уровне сети, а также обеспечивать стабильность интерфейса при изменении серверной логики.