Cypress обеспечивает возможность взаимодействия тестов с Node.js
через функцию cy.task(). Этот механизм позволяет выполнять
код вне браузера, например, обращаться к файловой системе, работать с
базой данных или выполнять произвольные скрипты на серверной стороне.
Отличие cy.task() от обычных команд Cypress заключается в
том, что она запускается в Node-процессе, а не в браузере, что
обеспечивает доступ к API, недоступным на фронтенде.
Для использования cy.task() задачи нужно
зарегистрировать в файле плагинов cypress.config.js (для
Cypress 10+), либо plugins/index.js (для старых версий).
Пример структуры:
const fs = require('fs');
module.exports = (on, config) => {
on('task', {
readFile(filePath) {
return fs.readFileSync(filePath, 'utf8');
},
logMessage(message) {
console.log('Log from cy.task:', message);
return null; // обязательно возвращать значение
},
generateRandomNumber(max) {
return Math.floor(Math.random() * max);
}
});
};
Ключевые моменты:
null.cy.task('название', аргумент).После регистрации задачи становятся доступны в тестах:
describe('Примеры использования cy.task', () => {
it('Чтение файла через Node.js', () => {
cy.task('readFile', 'data/sample.txt').then(content => {
expect(content).to.include('Hello World');
});
});
it('Логирование сообщений', () => {
cy.task('logMessage', 'Тестовое сообщение');
});
it('Генерация случайного числа', () => {
cy.task('generateRandomNumber', 100).then(number => {
expect(number).to.be.lessThan(100);
});
});
});
Особенности вызова:
cy.task() возвращает цепочку промисов,
поэтому можно использовать .then() для обработки
результата.Функции, выполняющие асинхронные операции, можно реализовать с использованием промисов:
const axios = require('axios');
module.exports = (on, config) => {
on('task', {
fetchUserData(userId) {
return axios.get(`https://jsonplaceholder.typicode.com/users/${userId}`)
.then(response => response.data)
.catch(error => {
throw new Error('Ошибка при получении данных: ' + error.message);
});
}
});
};
В тесте:
it('Получение данных пользователя', () => {
cy.task('fetchUserData', 1).then(user => {
expect(user).to.have.property('id', 1);
expect(user).to.have.property('username');
});
});
Важно: Cypress корректно обрабатывает промисы, поэтому нет
необходимости вручную оборачивать асинхронный код в
cy.wrap() или другой метод синхронизации.
cy.task() часто используется для работы с базой данных
при подготовке данных или очистке после теста:
const mysql = require('mysql2/promise');
module.exports = (on, config) => {
const connection = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test_db'
});
on('task', {
queryDb(query) {
return connection.query(query)
.then(([rows]) => rows)
.catch(err => { throw err; });
}
});
};
Использование в тесте:
it('Проверка записи в базу', () => {
cy.task('queryDb', 'SELECT COUNT(*) AS count FROM users')
.then(result => {
expect(result[0].count).to.be.a('number');
});
});
Особенности:
null —
Cypress иначе выдаст ошибку.Множественные операции с файловой системой:
const path = require('path');
on('task', {
readAndTransform(filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const transformed = content.split('\n').map(line => line.toUpperCase());
return transformed;
},
deleteFile(filePath) {
fs.unlinkSync(filePath);
return null;
}
});
Интеграция с внешними API:
on('task', {
fetchPosts() {
return axios.get('https://jsonplaceholder.typicode.com/posts')
.then(res => res.data)
.catch(err => { throw err; });
}
});
Эти подходы позволяют строить полноценные сценарии end-to-end, комбинируя действия в браузере и операции на серверной стороне через Node.js.
cy.task() является мощным инструментом для расширения
возможностей Cypress, позволяя выполнять любые задачи Node.js,
интегрировать тесты с внешними сервисами и эффективно управлять данными
тестирования.