Cypress: Uploading Files with selectFile Command


What it Does

  • Simulates dragging and dropping a file into the browser window.
  • Selects a file (or multiple files) within an HTML5 file upload element.

Key Points

  • It accepts an object as an argument to configure the file details.
  • It's a built-in Cypress command, eliminating the need for external plugins like cypress-file-upload.

Configuration Options (within the Object)

  • lastModified: Sets the last modified date of the file (optional).
  • mimeType: Defines the MIME type of the file (e.g., text/plain, image/jpeg).
  • fileName: Sets the name of the file being uploaded.
  • contents: This defines the actual content of the file. You can use Cypress.Buffer.from('your content') to specify the content as a string.

Example Usage

cy.get('#file-upload-input').selectFile({
  contents: Cypress.Buffer.from('This is the file content'),
  fileName: 'my_file.txt',
  mimeType: 'text/plain',
});

In this example:

  • The MIME type is set to plain text.
  • The filename is set to my_file.txt.
  • The file content is set as a string.
  • We use selectFile to simulate selecting a file.
  • We target the element with the ID file-upload-input.
  • For more complex scenarios, you might explore third-party libraries that handle advanced file upload functionalities.


Uploading a File from Disk

const filePath = './cypress/fixtures/image.jpg'; // Path to your image file

cy.get('#image-upload').selectFile({ filePath });

This code retrieves the file path of an image stored in your Cypress fixtures folder and then uses selectFile to upload it through the element with the ID image-upload.

Uploading from a Fixture

cy.fixture('report.pdf').then(fileContent => {
  cy.get('#report-upload').selectFile({
    contents: fileContent,
    fileName: 'report.pdf',
    mimeType: 'application/pdf',
  });
});

This example loads a PDF file named report.pdf from your Cypress fixtures using cy.fixture. Then, it uses selectFile to upload the loaded content, specifying the filename and MIME type.

Selecting Multiple Files

While selectFile typically handles a single file, Cypress allows simulating multiple file selection with a slight modification. You can achieve this by calling selectFile multiple times within a loop:

const files = ['image1.jpg', 'image2.png', 'image3.gif'];

files.forEach(fileName => {
  cy.get('#multiple-files').selectFile({ filePath: `./images/${fileName}` });
});

This code iterates through an array containing filenames and uses selectFile for each file, specifying the path within the images folder.

Uploading a File on a Hidden Input

cy.get('#hidden-file-upload').selectFile({ fileName: 'secret_data.txt' });

This example targets a hidden input element with the ID hidden-file-upload and uses selectFile to upload a file named secret_data.txt. Note that the file content isn't specified here, as hidden inputs might not require content details.



  1. Third-party Libraries

You can install it using npm:

npm install cypress-file-upload

Then, in your tests, you can use the attachFile command:

cy.get('#file-upload').attachFile('image.jpg');

Manual File Upload Simulation

  • For basic scenarios, you can simulate file upload behavior using a combination of Cypress commands. This approach involves:
    • Triggering a click event on the file input element.
    • Using the invoke command to programmatically set the file selection through the browser's native file selection dialog.

This method can be less robust compared to dedicated libraries or selectFile, but it might be suitable for simpler test cases.

  • For very specific scenarios or troubleshooting, you might explore manual simulation using Cypress commands.
  • If you require more advanced features like drag-and-drop simulation or handling multiple file uploads, consider using a library like cypress-file-upload.
  • If you need basic file upload functionality, selectFile is a good built-in option.