Загрузка файлов

Cypress предоставляет мощный и удобный механизм для тестирования функционала загрузки файлов в веб-приложениях. Загрузка файлов является одной из критических частей тестов, поскольку позволяет проверять, как система обрабатывает файлы различного типа и размера, а также корректность интеграции с серверной частью.


Основные подходы к загрузке файлов

В Cypress существует два основных способа симулировать загрузку файлов:

  1. Использование cy.get().attachFile() Для работы с этим методом требуется подключение внешнего плагина cypress-file-upload. Он позволяет имитировать выбор файла в <input type="file"> и передать файл прямо в элемент формы.

    Пример использования:

    import 'cypress-file-upload';
    
    describe('Тест загрузки файла', () => {
        it('Загружает файл на сервер', () => {
            cy.visit('/upload-page');
            cy.get('input[type="file"]').attachFile('example.pdf');
            cy.get('form').submit();
            cy.contains('Файл успешно загружен').should('be.visible');
        });
    });

    Здесь ключевым моментом является то, что файл должен находиться в папке cypress/fixtures. Метод attachFile принимает имя файла и дополнительные параметры, например, MIME-тип или имитацию имени файла при загрузке.

  2. Использование cy.fixture() с отправкой через cy.request() Этот метод полезен для API-тестирования или если загрузка происходит через AJAX-запрос без формы. Файл читается как fixture и отправляется в теле запроса.

    Пример:

    describe('Загрузка файла через API', () => {
        it('Отправляет файл на сервер', () => {
            cy.fixture('example.pdf', 'binary')
              .then(Cypress.Blob.binaryStringToBlob)
              .then((fileContent) => {
                  cy.request({
                      method: 'POST',
                      url: '/api/upload',
                      body: fileContent,
                      headers: {
                          'Content-Type': 'application/pdf'
                      }
                  }).then((response) => {
                      expect(response.status).to.eq(200);
                      expect(response.body.message).to.eq('Файл загружен');
                  });
              });
        });
    });

    Этот подход дает больше контроля над запросом и позволяет тестировать загрузку без UI, что ускоряет выполнение тестов.


Настройка плагина для загрузки файлов

Для использования attachFile необходимо установить плагин:

npm install --save-dev cypress-file-upload

После установки в cypress/support/commands.js добавляется импорт:

import 'cypress-file-upload';

Теперь метод attachFile доступен на любом элементе input[type="file"].


Работа с различными типами файлов

Cypress позволяет загружать:

  • Текстовые файлы: .txt, .csv
  • Документы: .pdf, .docx
  • Изображения: .png, .jpg, .svg

Важно учитывать размер файлов. Для больших файлов рекомендуется использовать API-подход через cy.request(), чтобы не нагружать DOM.

Пример с изображением:

cy.get('input[type="file"]').attachFile({
    filePath: 'image.png',
    mimeType: 'image/png'
});

Проверка результата загрузки

После загрузки файла необходимо убедиться, что файл корректно обработан:

  • Проверка наличия имени файла в интерфейсе:
cy.get('.uploaded-file-name').should('contain.text', 'example.pdf');
  • Проверка ответа сервера через API:
cy.intercept('POST', '/api/upload').as('fileUpload');
cy.get('input[type="file"]').attachFile('example.pdf');
cy.wait('@fileUpload').its('response.statusCode').should('eq', 200);

Загрузка нескольких файлов

Cypress позволяет загружать несколько файлов одновременно, используя массив объектов:

cy.get('input[type="file"]').attachFile([
    { filePath: 'file1.pdf' },
    { filePath: 'file2.pdf' }
]);

Каждый файл можно настраивать отдельно: указывать MIME-тип, имя, кодировку.


Обработка ошибок при загрузке

Тесты должны предусматривать случаи:

  • Загрузка файла неподдерживаемого типа
  • Превышение допустимого размера
  • Ошибка на сервере

Пример проверки ошибки при загрузке неподдерживаемого типа:

cy.get('input[type="file"]').attachFile('example.exe');
cy.get('.error-message').should('contain.text', 'Недопустимый тип файла');

Такой подход позволяет проверять как фронтенд-валидацию, так и серверную защиту.


Полезные советы

  • Размещать тестовые файлы в cypress/fixtures для удобного доступа.
  • Использовать cy.intercept() для проверки реального запроса на сервер.
  • Для динамических файлов можно создавать Blob в тесте и прикреплять их через attachFile.
  • Разделять тесты на UI и API-загрузку, чтобы ускорить выполнение и уменьшить зависимость от интерфейса.

Этот подход к загрузке файлов в Cypress обеспечивает гибкость, точность и возможность полноценного тестирования всех аспектов работы с файлами в веб-приложениях.