File upload testing made easy.
This package adds a custom Cypress command that allows you to make an abstraction on how exactly you upload files through HTML controls and focus on testing user workflows.
Note: v4 is unstable and at the moment there is no capacity to look through all the issues. So please consider using v3 https://github.com/abramenal/cypress-file-upload/tree/v3.5.3
The package is distributed via npm and should be installed as one of your project's devDependencies
:
npm install --save-dev cypress-file-upload
cypress-file-upload
extends Cypress' cy
command.
Add this line to your project's cypress/support/commands.js
:
import 'cypress-file-upload';
Now you are ready to actually test uploading. Here are some basic examples:
/* Plain HTML input */
const yourFixturePath = 'data.json';
cy.get('[data-cy="file-input"]').attachFile(yourFixturePath);
/* Drag-n-drop component */
cy.get('[data-cy="dropzone"]').attachFile(yourFixturePath, { subjectType: 'drag-n-drop' });
/* You can also attach multiple files by chaining the command */
const yourBestPicture = 'meow.png';
cy.get('[data-cy="file-input"]')
.attachFile(yourFixturePath)
.attachFile(yourBestPicture);
/* If your file encoding is not supported out of the box, make sure to pass it explicitly */
const weirdo = 'test.shp';
cy.get('[data-cy="file-input"]').attachFile({ filePath: weirdo, encoding: 'utf-8' });
/* If your input element is invisible or stays within shadow DOM, make sure enforcing manual event triggering */
cy.get('[data-cy="file-input"]').attachFile(yourFixturePath, { force: true });
/* If you want to overwrite the file name */
const data = 'test.json';
cy.get('[data-cy="file-input"]').attachFile({ filePath: data, fileName: 'users.json' });
/* If your file needs special processing not supported out of the box, you can pass fileContent directly */
const special = 'file.spss';
cy.fixtures(special, 'binary')
.then(Cypress.Blob.binaryStringToBlob)
.then((fileContent) => {
cy.get('[data-cy="file-input"]').attachFile({ fileContent, filePath: special, encoding: 'utf-8' });
})
/* when providing fileContent is possible to ignore filePath but fileName and mime type must be provided */
const special = 'file.spss';
cy.fixtures(special, 'binary')
.then(Cypress.Blob.binaryStringToBlob)
.then((fileContent) => {
cy.get('[data-cy="file-input"]').attachFile({ fileContent, fileName: 'special', mimeType: 'application/octet-stream', encoding: 'utf-8' });
})
Trying to upload a file that does not supported by Cypress by default? Make sure you pass encoding
property (see API).
See more usage guidelines in recipes.
Exposed command in a nutshell:
cySubject.attachFile(fixture, processingOpts);
fixture
is a string path (or object with same purpose) that represents your local fixture file and contains following properties:
- {String}
filePath
– file path (with extension) - {String}
fileName
- (optional) the name of the file to be attached, this allows to override the name provided byfilePath
- {Blob}
fileContent
- (optional) the binary content of the file to be attached - {String}
mimeType
– (optional) file MIME type. By default, it gets resolved automatically based on file extension. Learn more about mime - {String}
encoding
– (optional) normallycy.fixture
resolves encoding automatically, but in case it cannot be determined you can provide it manually. For a list of allowed encodings, see here
processingOpts
(optional) contains following properties:
- {String}
subjectType
– target (aka subject) element kind:'drag-n-drop'
component or plain HTML'input'
element. Defaults to'input'
- {Boolean}
force
– (optional) same as forcy.trigger
it enforces events triggering on HTML subject element. Usually this is necessary when you use hidden HTML controls for your file upload. Defaults tofalse
- {Boolean}
allowEmpty
- (optional) when true, do not throw an error iffileContent
is zero length. Defaults tofalse
Most common frontend UI setups along with Cypress & file upload testing are located at recipes.
Any contributions are welcome!
During the lifetime plugin faced some issues you might need to be aware of:
- Chrome 73 changes related to HTML file input behavior: #34
- Force event triggering (same as for
cy.trigger
) should happen when you use hidden HTML controls: #41 - Binary fixture has a workarounded encoding: #70
- Video fixture has a workarounded encoding: #136
- Shadow DOM compatibility: #74
- Reading file content after upload: #104
Here is step-by-step guide:
- Check Caveats – maybe there is a tricky thing about exactly your setup
- Submit the issue and let us know about you problem
- In case you're using a file with encoding and/or extension that is not yet supported by Cypress, make sure you've tried to explicitly set the
encoding
property (see API) - Comment your issue describing what happened after you've set the
encoding
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!