In Cypress, how does cy.fixture('receipts') resolve a file with no extension?
answer
- The folder Cypress looks in first
- A default folder underneath cypress/
- An exact filename beats any guess
- A fixed list of extensions, tried in order
- JSON first, zip last, no coffee
basics
~20 sCypress joins the path onto fixturesFolder, which defaults to cypress/fixtures. If that exact file exists it is read; otherwise Cypress tries a fixed extension list, .json first, and yields the first match, parsed according to that extension.
solid answer
~40 s`cy.fixture('receipts')` resolves against `fixturesFolder`, which defaults to `cypress/fixtures`, so it is asking for `cypress/fixtures/receipts`. Cypress tries that literal path first; if no such file exists it matches the same stem against a fixed extension list and takes the first hit, in the order `.json`, `.js`, `.html`, `.txt`, `.csv`, `.png`, `.jpg`, `.jpeg`, `.gif`, `.tif`, `.tiff`, `.zip`. What you receive depends on which extension won: `.json` arrives as a parsed object, `.js` as the evaluated object literal, `.html`/`.txt`/`.csv` as strings, images and `.zip` as base64. Sub-paths work the same way, so `cy.fixture('receipts/approved.json')` reads `cypress/fixtures/receipts/approved.json`. As of Cypress 16, `.coffee` is no longer on that list. If nothing matches, the test fails with a fixture-not-found error naming the extensions Cypress tried.
code
javascript · 14 lines// cypress/fixtures/receipts.json
// [{ "id": "R-1001", "merchant": "Blue Bottle", "amountCents": 1450 }]
it('shows the merchant on each receipt row', () => {
cy.fixture('receipts').then((receipts) => {
// resolved cypress/fixtures/receipts.json and parsed it
expect(receipts[0].merchant).to.equal('Blue Bottle')
})
cy.fixture('receipts.json', 'utf8').then((raw) => {
// an encoding was passed, so this is the unparsed text
expect(raw).to.be.a('string')
})
})go deeper
Be ready to say where fixture files live by default and what a JSON fixture hands your test. Knowing that cypress/fixtures is the default folder and that .json comes back parsed covers most screening questions here.
Explain the resolution mechanics: literal path first, then a fixed extension list in a documented order, then parse by extension. Be able to say what a .csv or a .png fixture yields and how the encoding argument changes it.
Show that you have been bitten by ambiguous fixture names and stale extension advice. Explain why you write extensions out on a shared suite and how you spot a fixture-not-found failure quickly when the command logs nothing.
Own the convention: whether fixture names carry extensions, how the folder is laid out for a suite several teams edit, and how you keep advice about removed features such as CoffeeScript fixtures out of your onboarding docs.
## Where the path is resolved `cy.fixture()` never takes a path from your project root. The string you pass is joined onto the **`fixturesFolder`** configuration value, which defaults to `cypress/fixtures`, so in an expense-report suite `cy.fixture('receipts')` is a request for `cypress/fixtures/receipts`. Nested paths behave the same way: `cy.fixture('approvals/pending.json')` reads `cypress/fixtures/approvals/pending.json`. Two consequences fall straight out of that: - A file that does not live under the fixtures folder — a reimbursement CSV the app just downloaded, a generated report, `package.json` — is simply **out of reach** of this command. `cy.readFile()` is the command that takes a project-root-relative path. - If a project sets `fixturesFolder` to `false`, `cy.fixture()` is disabled entirely and throws rather than falling back to some other directory. ## The extension ladder Cypress tries the **literal path first**. If a file named exactly `cypress/fixtures/receipts` exists, extension or not, that is what you get. Only when the literal path is missing does Cypress guess, matching the same stem against a fixed list and taking the **first** hit: 1. `.json` 2. `.js` 3. `.html` 4. `.txt` 5. `.csv` 6. `.png`, `.jpg`, `.jpeg`, `.gif`, `.tif`, `.tiff` 7. `.zip` That order is the list's own — not alphabetical, not newest-file-first, and not influenced by which file you edited last. So if a team keeps both `receipts.json` and `receipts.csv` around, `cy.fixture('receipts')` silently resolves the JSON one forever. Nothing warns you that the CSV was skipped, which is why writing the extension out (`cy.fixture('receipts.csv')`) is worth the extra five characters whenever two files share a stem. ## What you receive depends on which extension won The whole point of this command is that it does not just hand you bytes — it parses. | Extension | What `.then()` receives | |---|---| | `.json` | a parsed JavaScript object or array | | `.js` | the evaluated object literal in the file | | `.html`, `.txt`, `.csv` | the file's text as a string | | `.png`, `.jpg`, `.jpeg`, `.gif`, `.tif`, `.tiff`, `.zip` | a base64-encoded string | | anything else | the text, read as `utf8` | So `cy.fixture('receipts')` and `cy.fixture('receipts.csv')` can hand the same test two completely different kinds of value: an array of expense objects you can index into, or one long string you would have to split yourself. A `.json` file that will not parse fails the test with a message naming the file — Cypress validates JSON and JavaScript fixtures rather than passing garbage downstream. ## The encoding argument short-circuits the parse `cy.fixture()` accepts an encoding as its second argument, and passing one changes the deal: - Pass **nothing** and you get the extension-driven behaviour in the table above. - Pass an encoding — even `'utf8'` — and Cypress returns the **raw file content** instead of parsing it, so `cy.fixture('receipts.json', 'utf8')` yields the JSON *text*, not an object. - Pass `null` and you get a `Cypress.Buffer` regardless of extension, which is what you want for a scanned receipt image you intend to hash or byte-compare. The encoding also forms part of the fixture cache key, so asking for the same file under two encodings is two separate reads rather than one. ## Cypress 16 dropped CoffeeScript Built-in CoffeeScript support was removed in **Cypress 16**: the default `@cypress/webpack-batteries-included-preprocessor` no longer bundles `coffee-loader`, and `.coffee` is no longer resolved for specs, support files, or `cy.fixture()`. Older blog posts and answers that list `.coffee` in the fixture extension order are describing a version that no longer exists. If a legacy project still has `.coffee` fixtures, the migration path is to convert them to JavaScript or JSON, or to wire the loader up in your own webpack configuration. ## When nothing matches If neither the literal path nor any extension in the list exists, the command fails with a fixture-not-found error that prints the relative path it tried and the extension list it searched. Two things make that failure easier to read: - `cy.fixture()` itself does **not** appear in the Command Log, so you are looking for the error, not for a greyed-out command entry. - The path in the error is relative to the project, which makes an accidental `cy.fixture('cypress/fixtures/receipts.json')` — a doubled folder prefix — obvious as soon as you read it.
- Both receipts.json and receipts.csv exist. What does cy.fixture('receipts') read?The extension list decides, not the filesystem. `.json` is tried before `.csv`, so `cypress/fixtures/receipts.json` wins and you get a parsed object. Nothing warns you that the CSV was ignored, so pass the extension explicitly whenever two fixture files share a stem.
- How do you read a receipt image as bytes rather than as a base64 string?Pass `null` as the encoding: `cy.fixture('scans/receipt.png', null)` yields a `Cypress.Buffer` regardless of the file extension. Without it, Cypress base64-encodes binary fixtures, which is convenient for building a data URI but useless if you want to check a byte length or a hash.
saying these in an interview costs you the question
- Thinks cy.fixture() takes a path from the project root
- Assumes every fixture arrives as a parsed object
- Believes .coffee fixtures still resolve in Cypress 16
- Expects alphabetical or newest-first extension matching
- Says cy.fixture() can read any file in the repository