writeFile
cy.writeFile() writes text, JSON, or binary data to a file on disk from your
test. Your spec code runs in the browser, which can't reach the file system, so
Cypress hands the contents to its server, which writes the file. cy.writeFile() resolves the
path from your project root and creates any missing folders, so file output
stays in your test code, with no cy.task() to register
in your config.
Reach for cy.writeFile() when you need to:
- Turn a live response into a fixture and stub requests with it
- Save output your test produces, such as a log file, a CSV file, or a JSON report
- Save a binary file, such as an image
from a request or a
<canvas>element
To read a file back, use cy.readFile(). For file
operations cy.writeFile() doesn't cover, such as deleting a file, use
cy.task().
Syntax​
cy.writeFile(filePath, contents)
cy.writeFile(filePath, contents, encoding)
cy.writeFile(filePath, contents, options)
cy.writeFile(filePath, contents, encoding, options)
Usage​
Correct Usage
cy.writeFile('menu.json', { lunch: 'soup' })
Arguments​
filePath (String)
A path to a file, resolved relative to the project root (the directory that contains the Cypress configuration file). An absolute path also works. Cypress creates any missing directories in the path.
contents (String, Array, Object, or Buffer)
The contents to write to the file. Cypress writes a String or a Buffer as is,
and converts an Array or Object to JSON indented with 2 spaces.
encoding (String)
The encoding Cypress uses to write the file. The following encodings are supported:
'ascii''base64''binary''hex''latin1''utf8''utf-8''ucs2''ucs-2''utf16le''utf-16le'null
Passing null explicitly writes a Buffer directly, without first encoding it
as a string.
options (Object)
Pass in an options object to change the default behavior of cy.writeFile().
| Option | Default | Description |
|---|---|---|
encoding | utf8 | The encoding Cypress uses to write the file |
flag | w | File system flag as used with fs.writeFile |
log | true | Displays the command in the Command Log |
timeout | defaultCommandTimeout | Time to wait for cy.writeFile() to resolve before timing out |
Yields ​
cy.writeFile()yieldsnull.
Examples​
Text​
Write text to a .txt file​
If the file or any directory in its path doesn't exist, Cypress creates it. If the file already exists, Cypress overwrites it.
cy.writeFile('path/to/message.txt', 'Hello World')
cy.readFile('path/to/message.txt').then((text) => {
expect(text).to.equal('Hello World')
})
{projectRoot}/path/to/message.txt is created with the following contents:
Hello World
Write an array as CSV or lines of text​
An array is written as JSON, not as one line per item. To write a CSV file or other line-based text, join the array into a string first.
const rows = ['name,email', 'Eliza,eliza@example.com']
cy.writeFile('path/to/users.csv', rows.join('\n'))
{projectRoot}/path/to/users.csv is created with the following contents:
name,email
Eliza,eliza@example.com
JSON​
Write JSON to a file​
Cypress converts arrays and objects to JSON indented with 2 spaces.
- JavaScript
- TypeScript
const user = { name: 'Eliza', email: 'eliza@example.com' }
cy.writeFile('path/to/data.json', user)
cy.readFile('path/to/data.json').then((saved) => {
expect(saved.name).to.equal('Eliza')
})
type User = { name: string; email: string }
const user: User = { name: 'Eliza', email: 'eliza@example.com' }
cy.writeFile('path/to/data.json', user)
cy.readFile<User>('path/to/data.json').then((saved) => {
expect(saved.name).to.equal('Eliza')
})
{projectRoot}/path/to/data.json is created with the following contents:
{
"name": "Eliza",
"email": "eliza@example.com"
}
Generate a fixture file and stub a request with it​
Save response data under cypress/fixtures/, and the file works like any other
fixture. Here cy.intercept() serves it as the
response to your app's request.
cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
cy.writeFile('cypress/fixtures/users.json', response.body)
})
cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers')
cy.visit('/users')
cy.wait('@getUsers')
Write the file before you add the intercept. cy.intercept() reads a fixture
when it registers the route, so writing the file afterwards doesn't change the
response. See
How Cypress caches fixture data.
Add properties to an existing JSON file​
The a+ flag appends text, so it can't merge JSON. Read the file, add the new
properties, then write the combined result back. In TypeScript, pass a type
argument to cy.readFile() so the yielded object has the file's shape.
- JavaScript
- TypeScript
const filename = 'path/to/file.json'
cy.readFile(filename).then((user) => {
user.id = '1234'
// write the merged object
cy.writeFile(filename, user)
})
type User = { name: string; id?: string }
const filename = 'path/to/file.json'
cy.readFile<User>(filename).then((user) => {
user.id = '1234'
// write the merged object
cy.writeFile(filename, user)
})
Add items to an existing JSON array​
- JavaScript
- TypeScript
const filename = 'path/to/list.json'
cy.readFile(filename).then((list) => {
list.push({ item: 'example' })
// write the merged array
cy.writeFile(filename, list)
})
type Item = { item: string }
const filename = 'path/to/list.json'
cy.readFile<Item[]>(filename).then((list) => {
list.push({ item: 'example' })
// write the merged array
cy.writeFile(filename, list)
})
Encoding​
Specify the encoding as a string argument​
cy.writeFile('path/to/ascii.txt', 'Hello World', 'ascii')
{projectRoot}/path/to/ascii.txt is created with the following contents:
Hello World
Specify the encoding as part of the options object​
cy.writeFile('path/to/ascii.txt', 'Hello World', { encoding: 'ascii' })
Save a binary file from a request​
Request the file with encoding: 'binary', then write the response body with
the same encoding so the bytes reach the disk unchanged.
cy.request({
url: 'https://example.cypress.io/assets/img/javascript-logo.png',
encoding: 'binary',
}).then((response) => {
cy.writeFile('path/to/logo.png', response.body, 'binary')
})
Decode a base64 string into a file​
With the base64 encoding, Cypress decodes the string and writes the
resulting bytes. This example saves the image drawn on a <canvas> element.
cy.get('canvas')
.invoke('get', 0)
.invoke('toDataURL', 'image/png')
.then((dataUrl) => {
const base64 = dataUrl.split(',')[1]
cy.writeFile('path/to/chart.png', base64, 'base64')
})
Flags​
Build a log file one line at a time​
Pass flag: 'a+' to add contents to the end of the file instead of
overwriting it. Appending adds the contents exactly as passed, with no
separator, so end each entry with \n to keep entries on their own lines. The
first write uses the default w flag, so each run starts with an empty log.
cy.writeFile('path/to/run.log', 'Test started\n')
cy.writeFile('path/to/run.log', 'Logged in\n', { flag: 'a+' })
cy.writeFile('path/to/run.log', 'Checkout complete\n', { flag: 'a+' })
{projectRoot}/path/to/run.log contains:
Test started
Logged in
Checkout complete
Buffer​
Write a buffer directly without encoding as a string​
Read a file with a null encoding to get a Buffer, then write it with a
null encoding to copy the bytes unchanged.
cy.readFile('path/to/logo.png', null).then((buffer) => {
// <Buffer 89 50 4e 47 ... >
cy.writeFile('path/to/logo-copy.png', buffer, null)
})
Options​
Keep a large response out of the Command Log​
The console output for cy.writeFile() includes the full contents written.
Pass log: false to hide the command when the contents are large or
sensitive.
cy.request('https://jsonplaceholder.cypress.io/photos').then((response) => {
cy.writeFile('cypress/fixtures/photos.json', response.body, { log: false })
})
Allow more time for a large write​
const largeText = 'x'.repeat(50 * 1024 * 1024)
cy.writeFile('path/to/large.txt', largeText, { timeout: 15000 })
Notes​
How the encoding argument and option combine​
When you pass both an encoding argument and an encoding option, the option
takes precedence. This call writes the string as UTF-8 text, not as decoded
hex:
cy.writeFile('path/to/message.txt', '48656c6c6f', 'hex', { encoding: 'utf8' })
How cy.writeFile() updates the fixture cache​
Writing a file inside the
fixturesFolder clears that
file from the cy.fixture() cache, so a later
cy.fixture() call yields the new contents.
Rules​
Requirements ​
cy.writeFile()requires being chained off ofcy.cy.writeFile()must be invoked from the spec file or support file.cy.writeFile()requires the file be successfully written to disk. Anything preventing this, such as OS permission issues, causes it to fail.
Assertions ​
cy.writeFile()runs assertions you have chained once, and does not retry.
Timeouts ​
cy.writeFile()can time out when writing the file takes longer than thetimeoutoption.
Command Log​
Write an array to a file
cy.writeFile('info.log', ['foo', 'bar', 'baz'])
The command above displays in the Command Log as:

When you click the writeFile command in the Command Log, the console outputs
the following. File path is the absolute path Cypress resolved from
filePath, and Contents is what Cypress wrote, with the array converted to
JSON.

History​
| Version | Changes |
|---|---|
| 15.0.0 | Writing a fixture file clears it from the cy.fixture() cache |
| 9.2.0 | Added timeout option |
| 4.0.0 | cy.writeFile() now yields null instead of contents |
| 3.1.1 | Added flag option and appending with a+ |
| 1.0.0 | cy.writeFile() command added |
See also​
cy.fixture()to load the test data a file holds, with cachingcy.readFile()to read a file, retrying until it existscy.task()for file operationscy.writeFile()doesn't cover, such as deleting a file