App & Browser Testing Made Easy

Give your users a seamless experience by testing on 3000+ real devices and browsers. Don't compromise with emulators and simulators

Get Started free
Home Guide How to Upload a File in Cypress? (with Advanced Techniques)

How to Upload a File in Cypress? (with Advanced Techniques)

By Ansa Anthony, Community Contributor -

File upload functionality is an essential part of web application testing. File upload testing is essential to ensure the feature works correctly, completes the user’s needs, complies with regulations and standards, and integrates seamlessly with other systems or services. 

Importance of File Upload in Web Testing

Testing File upload functionality thoroughly is critical to delivering a high-quality web application that provides a seamless user experience while ensuring the security and integrity of the application and its users’ data.

Here are five reasons why file upload testing is essential in web testing:

  1. Data integrity
  2. Security
  3. Usability
  4. Compliance
  5. Integration

Why use Cypress for File Upload Testing?

Cypress is a popular end-to-end testing framework used for testing web applications. It provides a clean and concise syntax, an intuitive API, and a comprehensive set of commands to interact with web pages, making it an excellent choice for testing file upload functionality. 

Here is an overview of using Cypress for file upload testing:

1. Selecting the File Input Element: Cypress allows you to select the file input element using its selector syntax, just like any other element on the page.

cy.get('input[type="file"]').as('fileInput');

2. Uploading a File: Once you have selected the file input element, you can use the cy.fixture() method to create a file fixture and then use the cy.get(‘@fileInput’).attachFile() method to attach the file to the input element.

cy.fixture('example.png').then(fileContent => {
cy.get('@fileInput').attachFile({
fileContent: fileContent.toString(),
fileName: 'example.png',
mimeType: 'image/png'
});
});

3. Verifying the Uploaded File: Cypress provides a cy.contains() method to verify that the uploaded file appears correctly on the page.

cy.contains('example.png');

4. Testing Error Handling: Cypress allows you to test error handling during file upload by simulating different scenarios, such as uploading a file that exceeds the maximum file size or uploading a file with an invalid file format.

cy.get('@fileInput').attachFile('example.docx');
cy.contains('Error: Invalid file format');

Cypress framework provides a straightforward and powerful way to test file upload functionality in web applications. Using its intuitive API and commands, you can easily create tests covering various scenarios and ensure that the file upload feature works correctly and meets the user’s requirements.

Setting up Cypress for File Upload

Setting up Cypress for file upload testing involves a few steps to configure the environment and install the necessary dependencies. Here is an overview of the steps required to set up Cypress for file upload testing:

Step 1 – Install Cypress: You can install Cypress using npm, the Node.js package manager, by running the following command in your terminal:

npm install cypress --save-dev

Step 2 – Install Cypress-file-upload: Install the Cypress-file-upload plugin, which adds support for file upload testing to Cypress, by running the following command in your terminal:

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

Step 3 – Configure Cypress: Once you have installed Cypress and Cypress-file-upload, you need to configure Cypress by adding the following lines of code to your cypress/support/index.js file:

import 'cypress-file-upload';
Cypress.Commands.add('upload_file', (fileName, fileType = ' ', selector) => {
cy.get(selector).then(subject => {
cy.fixture(fileName, 'base64').then(content => {
const el = subject[0];
const testFile = new File([content], fileName, { type: fileType });
const dataTransfer = new DataTransfer();
dataTransfer.items.add(testFile);
el.files = dataTransfer.files;
});
});
});

This code imports the Cypress-file-upload plugin and adds a custom command to Cypress that can be used to upload files. The upload_file command takes the following parameters:

  • fileName: The name of the file to upload.
  • fileType: The MIME type of the file to upload.
  • selector: The selector for the file input element on the page.

Step 4Use the upload_file command: To upload a file in your Cypress test, use the upload_file command you just created, passing in the appropriate parameters. 

For example:

describe('File upload', () => {
it('should upload a file', () => {
cy.visit('https://example.com');
cy.upload_file('example.png', 'image/png', 'input[type="file"]');
cy.contains('example.png');
});
});

This code visits a web page, uses the upload_file command to upload a file, and then verifies that the uploaded file appears on the page.

You can install and configure Cypress to handle file upload testing with these steps. You can then use the upload_file command in your Cypress tests to ensure your application’s file upload functionality works correctly and meets user requirements.

Setting up the Cypress Test Environment

To set up the test environment for file upload in Cypress, you can follow these steps:

1. Install the cypress-file-upload plugin:

npm install -D cypress-file-upload

2. In your cypress/support/index.js file, import the addMatchImageSnapshotCommand function from the plugin:

import 'cypress-file-upload';

3. Create a test case that performs a file upload. For example:

describe('File upload', () => {
it('uploads a file', () => {
cy.visit('https://www.example.com');
cy.get('input[type="file"]').attachFile('example.txt');
// Add any additional assertions or actions as needed
});
});

4. Make sure the file you want to upload (example.txt) is in the cypress/fixtures directory.

5. To run the test case, use the Cypress Test Runner by running the following command in your terminal:

npm run cypress:open

6. Select the file-upload.spec.js file in the Test Runner and click the “Run” button to run the test case.

Writing File Upload tests with Cypress

File upload tests with Cypress typically involve the following steps:

  1. Navigate to the page that contains the file upload functionality using the cy.visit command.
  2. Locate the file input element on the page using the cy.get command and pass in the ID or CSS selector of the file input element.
  3. Attach a file to the file input element using the attachFile command and pass in the path to the file you want to upload.
  4. Click the submit button to upload the file.
  5. Verify that the file was uploaded successfully by checking for the presence of the file name or other success messages on the page using the cy.get command and assertions such as should or contains.

Writing a Basic File Upload Test

describe('File Upload Test', () => {
it('uploads a file', () => {
// Visit the file upload page
cy.visit('https://the-internet.herokuapp.com/upload');
// Get the file input element and attach a file
const fileName = 'example.txt';
cy.get('#file-upload').attachFile(fileName);
// Click the submit button
cy.get('#file-submit').click();
// Verify that the upload was successful
cy.get('#uploaded-files').should('contain', fileName);
});
});

Here’s what each step in the test does:

  1. Start by describing the test using the describe function, which takes a string describing the test suite and a function containing the test cases.
  2. Define a Cypress test case using the it function, which takes a string describing it and a function containing the test steps.
  3. Start the test by visiting the file upload page using the cy.visit command.
  4. Use the cy.get command to get the file input element by its ID (#file-upload). We then use the attachFile command to attach a file (example.txt) to the input element.
  5. Click the submit button using the cy.get command to get the submit button by its ID (#file-submit) and the click command to simulate a click.
  6. Finally, verify that the file was uploaded successfully by checking that the file name (example.txt) is displayed on the page using the cy.get command to get the uploaded files element by its ID (#uploaded-files). The should command to assert that the element contains the file name.

To use the attachFile command in Cypress, you’ll need to install the cypress-file-upload plugin.

Testing Different File Types and Sizes

1. Install the BrowserStack Cypress plugin and configure your cypress.json file to use your BrowserStack credentials. You can find instructions on how to do this in the BrowserStack Cypress documentation.

2. In your test, define an array of file paths representing the different file types and sizes you want to test. For example:

const filesToUpload = [
{ path: 'example.txt', type: 'text/plain' },
{ path: 'example.jpg', type: 'image/jpeg' },
{ path: 'example.pdf', type: 'application/pdf' },
{ path: 'largefile.mp4', type: 'video/mp4' },
];

3. Define a test case that loops through the filesToUpload array and uploads each file using the attachFile command. For example:

describe('File Upload Test', () => {
filesToUpload.forEach((file) => {
it(`uploads ${file.path}`, () => {
cy.visit('https://the-internet.herokuapp.com/upload');
// Get the file input element and attach the file
cy.get('#file-upload').attachFile({
filePath: file.path,
mimeType: file.type,
});
// Click the submit button
cy.get('#file-submit').click();
// Verify that the upload was successful
cy.get('#uploaded-files').should('contain', file.path);
});
});
});

4. Run your test on BrowserStack by running the following command in your terminal:

npx cypress run --record --key <your-access-key> --browserstack-build-name "File Upload Test"

This will run your test on BrowserStack and upload each file in the filesToUpload array, verifying that each upload was successful.

You can customize the BrowserStack configuration for your test, such as the browser and platform you want to test on, by adding configuration options to your cypress.json file. You can find more information on how to do this in the BrowserStack Cypress documentation.

Verifying the Success of the File Upload

describe('File Upload Test', () => {
it('uploads a file and verifies the success', () => {
// Visit the file upload page
cy.visit('https://the-internet.herokuapp.com/upload');
// Get the file input element and attach a file
const fileName = 'example.txt';
cy.get('#file-upload').attachFile(fileName);
// Click the submit button
cy.get('#file-submit').click();
// Verify that the upload was successful
cy.get('#uploaded-files').should('contain', fileName);
// Get the success message element and verify its text
const successMessage = 'File Uploaded!';
cy.get('.example > h3').should('contain', successMessage);
});
});

Here’s what each step in the test does:

  1. Start by describing the test using the describe function, which takes a string describing the test suite and a function containing the test cases.
  2. Define a test case using the it function, which takes a string describing the test case and a function containing the test steps.
  3. Start the test by visiting the file upload page using the cy.visit command.
  4. Use the cy.get command to get the file input element by its ID (#file-upload). We then use the attachFile command to attach a file (example.txt) to the file input element.
  5. Click the submit button using the cy.get command to get the submit button by its ID (#file-submit) and the click command to simulate a click.
  6. Verify that the file was uploaded successfully by checking that the file name (example.txt) is displayed on the page using the cy.get command to get the uploaded files element by its ID (#uploaded-files) and the should command to assert that the element contains the file name.
  7. We get the success message element using the cy.get command to get the message element by its CSS selector (.example > h3). We then use the should command to assert that the element contains the success message (File Uploaded!).

Note: The success message element may vary depending on the application you are testing, so you’ll need to customize the CSS selector and success message text accordingly.

Handling File Upload Errors

 describe('File Upload Test', () => {
it('handles file upload errors', () => {
// Visit the file upload page
cy.visit('https://the-internet.herokuapp.com/upload');
// Get the file input element and attach an unsupported file
const fileName = 'unsupported_file.exe';
cy.get('#file-upload').attachFile(fileName);
// Click the submit button
cy.get('#file-submit').click();
// Verify that an error message is displayed
const errorMessage = 'Internal Server Error';
cy.get('.example > h1').should('contain', errorMessage);
});
});

Here’s what each step in the test does:

  1. Start by describing the test using the describe function, which takes a string describing the test suite and a function containing the test cases.
  2. Define a test case using the it function, which takes a string describing the test case and a function containing the test steps.
  3. Start the test by visiting the file upload page using the cy.visit command.
  4. Use the cy.get command to get the file input element by its ID (#file-upload). We then use the attachFile command to attach an unsupported file (unsupported_file.exe) to the file input element.
  5. Click the submit button using the cy.get command to get the submit button by its ID (#file-submit) and the click command to simulate a click.
  6. Verify that an error message is displayed by checking that the error message (Internal Server Error) is displayed on the page using the cy.get command to get the error message element by its CSS selector (.example > h1) and the should command to assert that the element contains the error message.

The error message element may vary depending on the application you are testing, so you’ll need to customize the CSS selector and error message text accordingly.

Advanced Cypress File Upload Techniques

Advanced file upload techniques in Cypress go beyond the basic steps of locating the file input element, attaching a file, and submitting the form. These techniques involve more advanced Cypress commands and strategies for handling file uploads in various scenarios. 

Some examples of advanced file upload techniques include:

Uploading Multiple Files at once

describe('Multiple File Upload Test', () => {
it('uploads multiple files', () => {
// Visit the file upload page
cy.visit('https://the-internet.herokuapp.com/upload');
// Get the file input element and attach multiple files
const fileNames = ['file1.txt', 'file2.txt', 'file3.txt'];
cy.get('#file-upload').each((fileInput, index) => {
cy.fixture(fileNames[index]).then(fileContent => {
cy.wrap(fileInput).attachFile({
fileContent: fileContent.toString(),
fileName: fileNames[index],
mimeType: 'text/plain',
});
});
});
// Click the submit button
cy.get('#file-submit').click();
// Verify that all files were uploaded successfully
fileNames.forEach(fileName => {
cy.get('.uploaded-files').should('contain', fileName);
});
});
});

Explanation:

  1. Start by describing the test using the describe function, which takes a string describing the test suite and a function containing the test cases.
  2. Define a test case using the it function, which takes a string describing the test case and a function containing the test steps.
  3. Start the test by visiting the file upload page using the cy.visit command.
  4. Use the cy.get command to get the file input element by its ID (#file-upload). We then use the each command to loop through an array of file names (fileNames) and attach each file to the file input element using the attachFile command. We use the cy.fixture command to load each file’s contents as a string and pass it to the attachFile command along with the filename and MIME type.
  5. Click the submit button using the cy.get command to get the submit button by its ID (#file-submit) and the click command to simulate a click.
  6. Verify that all files were uploaded successfully by checking that each file name is displayed on the page in the list of uploaded files. We use the forEach method to loop through the file names array and the should command to assert that each file name is contained in the list of uploaded files.

Each command allows us to attach multiple files to the file input element by looping through an array of files. We use the fixture command to load each file’s contents as a string and pass it to the attachFile command. We also pass in the file name and MIME type so that the application can properly handle each file. By using these techniques, we can test the application’s ability to handle multiple file uploads.

Uploading files using drag and drop

describe('File Upload using Drag and Drop Test', () => {
it('uploads a file using drag and drop', () => {
// Visit the file upload page
cy.visit('https://the-internet.herokuapp.com/upload');
// Get the file input element and hide it
cy.get('#file-upload').then(subject => {
cy.wrap(subject).hide();
});
// Get the drop zone element and drop the file onto it
cy.get('#drag-drop-upload')
.attachFile('file1.txt', { subjectType: 'drag-n-drop' });
// Click the submit button
cy.get('#file-submit').click();
// Verify that the file was uploaded successfully
cy.get('.uploaded-files').should('contain', 'file1.txt');
});
});

Explanation:

  1. Start by describing the test using the describe function, which takes a string describing the test suite and a function containing the test cases.
  2. Define a test case using the it function, which takes a string describing the test case and a function containing the test steps.
  3. Start the test by visiting the file upload page using the cy.visit command.
  4. Use the cy.get command to get the file input element by its ID (#file-upload). We then use the then command to access the raw DOM element and the wrap command to wrap it in a Cypress object. We then use the hide command to hide the file input element, since we won’t be using it for this test.
  5. Use the cy.get command to get the drop zone element by its ID (#drag-drop-upload). Using drag and drop, we then use the attachFile command to attach the file file1.txt to the drop zone element. We pass in { subjectType: ‘drag-n-drop’ } as an option to specify that we want to use drag and drop.
  6. Click the submit button using the cy.get command to get the submit button by its ID (#file-submit) and the click command to simulate a click.
  7. Verify that the file was uploaded successfully by checking that the file name is displayed on the page in the list of uploaded files. We use the should command to assert that the file name is in the uploaded file list.

Note that the attachFile command allows us to upload files using drag and drop. We pass in { subjectType: ‘drag-n-drop’ } as an option to specify that we want to use drag and drop. We also use the hide command to hide the file input element, since we won’t use it for this test. By using drag and drop, we can test the functionality of the file upload feature more realistically.

Uploading Files from a Remote Location

To upload files from a remote location with Cypress, we can use the cy.request command to make an HTTP request to the remote server and download the file to a temporary directory on our machine. 

Here’s an example of how to upload a file from a remote location with Cypress:

describe('File Upload from Remote Location Test', () => {
it('uploads a file from a remote location', () => {
// Download the file to a temporary directory on our machine
cy.request('https://example.com/file.txt')
.then(response => {
cy.writeFile('/tmp/file.txt', response.body, 'binary');
});
// Visit the file upload page
cy.visit('https://the-internet.herokuapp.com/upload');
// Get the file input element and attach the file to it
cy.get('#file-upload').attachFile('/tmp/file.txt');
// Click the submit button
cy.get('#file-submit').click();
// Verify that the file was uploaded successfully
cy.get('.uploaded-files').should('contain', 'file.txt');
});
});

Explanation:

  1. Start by describing the test using the describe function, which takes a string describing the test suite and a function containing the test cases.
  2. Define a test case using the it function, which takes a string describing the test case and a function containing the test steps.
  3. Use the cy.request command to make an HTTP GET request to the remote server (https://example.com/file.txt) and download the file to a temporary directory on our machine using the cy.writeFile command. We pass in ‘/tmp/file.txt’ as the file path and ‘binary’ as the encoding, since the file is a binary file.
  4. Visit the file upload page using the cy.visit command.
  5. Use the cy.get command to get the file input element by its ID (#file-upload). We then use the attachFile command to attach the file ‘/tmp/file.txt’ to the file input element.
  6. Click the submit button using the cy.get command to get the submit button by its ID (#file-submit) and the click command to simulate a click.
  7. Verify that the file was uploaded successfully by checking that the file name is displayed on the page in the list of uploaded files. We use the should command to assert that the file name is in the uploaded file list.

Uploading Files with Custom Headers

To upload files with custom headers with Cypress, we can use the cy.fixture command to load the file into the test runner, and then attach it to the file input element using the attachFile command. We can also specify custom headers using the cy.request command, which allows us to set headers such as authentication tokens or custom content types.

Here’s an example of Cypress upload file test:

describe('File Upload with Custom Headers Test', () => {
it('uploads a file with custom headers', () => {
// Define the custom headers to be sent with the file upload request
const headers = {
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
};
// Load the file into the test runner
cy.fixture('example.txt').then(fileContent => {
// Visit the file upload page
cy.visit('https://the-internet.herokuapp.com/upload');
// Attach the file to the file input element with custom headers
cy.get('#file-upload').attachFile({
fileContent,
fileName: 'example.txt',
mimeType: 'text/plain',
headers
});
// Click the submit button
cy.get('#file-submit').click();
// Verify that the file was uploaded successfully
cy.get('.uploaded-files').should('contain', 'example.txt');
});
});
});

Explanation:

1. Start by describing the test using the describe function, which takes a string describing the test suite and a function containing the test cases.

2. Define a test case using the it function, which takes a string describing the test case and a function containing the test steps.

3. Define the custom headers to be sent with the file upload request in the headers object. In this case, we’re setting an authentication token and a custom content type.

4. Load the file into the test runner using the cy.fixture command, which takes the file name as an argument and returns the file contents. We then visit the file upload page using the cy.visit command.

5. Use the cy.get command to get the file input element by its ID (#file-upload). We then use the attachFile command to attach the file to the file input element. We pass in an object as an argument with the following properties:

  • fileContent: The contents of the file, which we loaded using the cy.fixture command.
  • fileName: The name of the file, which will be displayed on the page after the upload is complete.
  • mimeType: The MIME type of the file, which is set to ‘text/plain’ in this case.
  • headers: The custom headers to be sent with the file upload request, which we defined earlier.

6. Click the submit button using the cy.get command to get the submit button by its ID (#file-submit) and the click command to simulate a click.

7. Verify that the file was uploaded successfully by checking that the file name is displayed on the page in the list of uploaded files. We use the should command to assert that the file name is contained in the list of uploaded files.

Best Practices for Cypress Test File Upload

When testing file uploads with Cypress, it’s important to follow best practices to ensure your tests are reliable, maintainable, and effective. 

Here are some best practices to keep in mind when testing file uploads with Cypress:

Using Unique File names for each Test

When testing file uploads with Cypress, it’s important to use unique file names for each test to ensure that the tests are independent and don’t interfere with each other. Here are the steps to use unique file names for each test with Cypress:

  1. Generate a unique file name: Before each test that involves file uploads, generate a unique file name using a unique identifier such as a timestamp or a random string. You can use the cy.uuid command to generate a random UUID, or any other method that suits your needs.
  2. Use the unique file name in your test: When attaching the file to the upload input, use the unique file name you generated in step 1. You can do this by passing the unique file name as a parameter to the cy.fixture command, or by appending it to the file name in any other way that suits your needs.
  3. Verify the success of the file upload: After uploading the file, verify that it was uploaded successfully by checking that the file name or other identifying information is displayed on the page. Ensure the uploaded file has the same unique name as the one you generated in step 1.
  4. Repeat for each test: Repeat these steps for each test that involves file uploads. This ensures that each test uses a unique file name and is independent of other tests that may be running concurrently.

By using unique file names for each test, you can ensure that your tests are independent of each other and don’t interfere with each other, leading to more reliable and robust tests.

Cleaning up Uploaded Files after each test

When testing file uploads with Cypress, it’s important to clean up any files that were uploaded during the test to avoid leaving test artifacts behind. Here are the steps to clean up uploaded files after each test with Cypress:

  1. Find the uploaded file: After the file has been uploaded, you need to find the uploaded file on the server or storage location. You can do this by inspecting the network requests or by using an API to access the storage location.
  2. Delete the uploaded file: Delete it using an appropriate API or command for your server or storage location once you have located it. You can use the cy.request command to send a DELETE request to the server or use any other appropriate method for your needs.
  3. Repeat for each test: Repeat these steps for each test that involves file uploads. This ensures that any files uploaded during the test are deleted after the test has been completed.
  4. Verify the cleanup: After the test has been completed, verify that the uploaded file has been deleted and that there are no test artefacts left behind.

By cleaning up uploaded files after each test, you can avoid leaving test artefacts behind and ensure that your tests are more reliable and repeatable.

Storing File Data in Fixtures or Data Files

When testing file uploads with Cypress, it can be useful to store file data in fixtures or data files so that it can be easily reused across multiple tests. Here are the steps to store file data in fixtures or data files with Cypress:

  1. Create a fixture file: Create a fixture file containing the data you want to use in your tests. You can do this by creating a new file in the fixtures directory of your Cypress project and adding the file data to it. Make sure to give the file a unique name.
  2. Load the fixture file: In your test, use the cy.fixture command to load the fixture file into a variable. This command reads the file data from the fixture file and returns it as a string or binary data, depending on the file type.
  3. Use the file data in your test: Once you have loaded it into a variable, you can use it by attaching it to the upload input using the cy.get and .attach commands. Make sure to set the appropriate file name and file type for the uploaded file.
  4. Repeat for each test: Repeat these steps for each test that involves file uploads. This ensures that you can reuse the file data across multiple tests, leading to more efficient and maintainable tests.

By storing file data in fixtures or data files, you can easily reuse the same file data across multiple tests, leading to more efficient and maintainable tests.

Running File Upload Tests on Different Browsers

When testing file uploads with Cypress, it’s important to test your tests on different browsers to ensure that your application works correctly across different environments. Cypress supports browsers that you can use for testing, including:

  • Chrome
  • Edge
  • Firefox
  • Electron and more
  • Webkit (experimental support)

Here are the steps to run file upload tests on different browsers using Cypress:

  1. Configure Cypress to use the desired browser: To use a different browser for testing, you must configure Cypress to use the desired browser. You can do this by setting the browser property in your cypress.json configuration file or bypassing the –browser flag when running Cypress.
  2. Run your tests: Once you configure Cypress to use the desired browser, run your file upload tests as usual. Cypress will launch the specified browser and run your tests in that environment.
  3. Repeat for each browser: Repeat these steps for each browser that you want to test on. This ensures that your tests work correctly across various environments and helps you identify any browser-specific issues that may arise.

By running your file upload tests on different browsers, you can ensure your application works correctly across different environments and provide a more reliable and consistent user experience.

Start Cypress Testing

Tags
Automation Testing Cypress

Featured Articles

Cypress Best Practices for Test Automation

How to use Cypress Clear Cookies Command?

App & Browser Testing Made Easy

Seamlessly test across 20,000+ real devices with BrowserStack