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

17 мар. 2020

Cypress — это JS-фрэймворк для End-to-End тестирования. От всех других он отличается тем, что использует не Selenium, а свой собственный движок. Это позволяет разработчикам быстрее и легче писать более надёжные тесты.

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

Добавляем новую команду

В Cypress есть API для добавления новых и перезаписи встроенных методов. Все встроенные в Cypress методы добавлены с помощью этого же API:

Cypress.Commands.add(name, callbackFn)
Cypress.Commands.add(name, options, callbackFn)
Cypress.Commands.overwrite(name, callbackFn)

Всё, что нам нужно сделать, это добавить новую команду в cypress/support/commands.js:

Cypress.Commands.add('uploadFile', { prevSubject: true }, (subject, fixturePath, mimeType) => {
  cy.fixture(fixturePath, 'base64').then(content => {
    Cypress.Blob.base64StringToBlob(content, mimeType).then((blob) => {
      const testfile = new File([blob], fixturePath, { type: mimeType });
      const dataTransfer = new DataTransfer();
      const fileInput = subject[0];

      dataTransfer.items.add(testfile);
      fileInput.files = dataTransfer.files;

      cy.wrap(subject).trigger('change', { force: true });
    });
  });
})

Как применять

Поместите файл, который вы будете загружать (например, test.jpg), в папку cypress/fixtures.

Далее в любом тестовом файле:

describe("File upload tests", () => {

  it("should upload file", () => {
    // Запускаем сервер, для контроля XHR-запросов
    cy.server();
			
    // Присваиваем запросу загрузки файлов алиас
    cy.route("POST", "/api/upload-url").as("postURL");
   
    // Переходим на страницу, где будем загружать файл
    cy.visit('localhost:4200/admin/upload-page');
	
    // Сохраняем тестовый файл и его тип в переменные
    const fixturePath = 'test.jpg';
    const mimeType = 'application/jpg';
	
    // Выбираем нужный инпут, например, по плэйсхолдеру
    // И добавляем в него файл
    cy.get('[placeholder="Файл"]').uploadFile(fixturePath, mimeType);

    // Нажимаем кнопку загрузки
    cy.get('.upload-button').click();
    
    // Ждём выполнение запроса и проверяем статус ответа
    cy.wait("@postURL").then((xhr) => {
      expect(xhr.response.body.status).to.equal(200);
    })
  })
})

Богдан Звягинцев

Спасибо за внимание! Если вы нашли ошибку или у вас есть дополнения, напишите мне в Телеграм.

© Богдан Звягинцев, 2022