Для работы с Puppeteer и тестированием REST API на базе Express необходимо создать Node.js-проект и установить зависимости:
mkdir puppeteer-express
cd puppeteer-express
npm init -y
npm install express puppeteer axios jest
express — для создания REST API.
puppeteer — для автоматизации браузера и тестирования
фронтенд-взаимодействий.
axios — для HTTP-запросов к API.
jest — для организации тестов.
Создание структуры проекта:
puppeteer-express/
├── src/
│ ├── server.js
│ └── routes/
│ └── users.js
├── tests/
│ └── api.test.js
└── package.json
Файл src/server.js:
const express = require(&
const app = express();
const usersRouter = require('./routes/users');
app.use(express.json());
app.use('/users', usersRouter);
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
module.exports = app;
Файл src/routes/users.js:
const express = require('express');
const router = express.Router();
let users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
];
// Получение всех пользователей
router.get('/', (req, res) => {
res.json(users);
});
// Получение пользователя по ID
router.get('/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ message: 'User not found' });
res.json(user);
});
// Создание нового пользователя
router.post('/', (req, res) => {
const { name } = req.body;
if (!name) return res.status(400).json({ message: 'Name is required' });
const newUser = { id: users.length + 1, name };
users.push(newUser);
res.status(201).json(newUser);
});
// Обновление пользователя
router.put('/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ message: 'User not found' });
user.name = req.body.name || user.name;
res.json(user);
});
// Удаление пользователя
router.delete('/:id', (req, res) => {
const index = users.findIndex(u => u.id === parseInt(req.params.id));
if (index === -1) return res.status(404).json({ message: 'User not found' });
users.splice(index, 1);
res.status(204).send();
});
module.exports = router;
Хотя Puppeteer предназначен для тестирования браузерного взаимодействия, его можно сочетать с API-запросами для интеграционных сценариев. Puppeteer позволяет эмулировать реальный браузер, что полезно для проверки работы фронтенда с REST API.
Пример интеграционного теста с использованием Puppeteer и Jest:
const puppeteer = require('puppeteer');
const axios = require('axios');
const app = require('../src/server');
let server;
beforeAll(() => {
server = app.listen(4000);
});
afterAll(() => {
server.close();
});
test('Создание и отображение нового пользователя через фронтенд', async () => {
// Создание пользователя через API
const newUser = { name: 'Charlie' };
const response = await axios.post('http://localhost:4000/users', newUser);
expect(response.status).toBe(201);
expect(response.data.name).toBe('Charlie');
// Проверка через Puppeteer, эмулируя фронтенд
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('http://localhost:4000/users');
const content = await page.evaluate(() => document.body.innerText);
expect(content).toContain('Charlie');
await browser.close();
});
Ключевые моменты:
beforeAll и
afterAll для старта и остановки сервера.
Для тестирования можно создать простую HTML-страницу, которая запрашивает данные API и отображает их:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Пользователи</title>
</head>
<body>
<ul id="users"></ul>
<script>
fetch('http://localhost:3000/users')
.then(res => res.json())
.then(users => {
const list = document.getElementById('users');
users.forEach(u => {
const li = document.createElement('li');
li.textContent = u.name;
list.appendChild(li);
});
});
</script>
</body>
</html>
Такой подход позволяет:
Основные операции Puppeteer для тестирования REST API через фронтенд:
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('http://localhost:3000');
const content = await page.$eval('#users', el => el.innerText);
expect(content).toContain('Alice');
await page.type('#username', 'David');
await page.click('#submit');
await page.waitForSelector('#users li:last-child');
const updatedContent = await page.$eval('#users', el => el.innerText);
expect(updatedContent).toContain('David');
await browser.close();
Для запуска тестов в автоматизированной среде рекомендуется:
headless: true).
beforeAll и afterAll для поднятия и
остановки Express-сервера.
Такой подход позволяет тестировать как чистую логику API, так и поведение фронтенда при взаимодействии с REST API, обеспечивая полноценное покрытие функциональности.