File Upload With selectFile¶
What was run¶
Two real uploads via cy.get().selectFile() against the local upload page: one from a real file on disk,
one generated entirely in memory with no file ever written to disk at all.
it("selects a real local file via selectFile", () => {
cy.visit("/upload.html");
cy.get("#file-input").selectFile("cypress/fixtures/real-upload.txt");
cy.get("#upload-result").should("have.text", "Selected: real-upload.txt");
});
it("selects a real file built from an in-memory buffer, no disk file needed", () => {
cy.visit("/upload.html");
cy.get("#file-input").selectFile({
contents: Cypress.Buffer.from("generated in-memory content"),
fileName: "generated.txt",
mimeType: "text/plain",
});
cy.get("#upload-result").should("have.text", "Selected: generated.txt");
});
✓ selects a real local file via selectFile (113ms)
✓ selects a real file built from an in-memory buffer, no disk file needed (45ms)
Both real uploads worked cleanly. This network's own Selenium Mastery Path hit a genuine real
ERR_ACCESS_DENIED uploading from a path under ~/Desktop (fixed by moving the file to /tmp) — this
lesson's real cypress/fixtures/real-upload.txt path, also outside any special-cased directory, uploaded
without any such error.
How It Actually Works¶
cy.get("#file-input").selectFile(path) reads a real file from disk (relative to the project root) and
directly sets it as the input element's file list, dispatching the real change event the browser fires
after a person picks a file — no OS file-picker dialog is simulated or needed, the same underlying approach
Selenium's send_keys() uses on a file input. The in-memory form ({ contents: Cypress.Buffer.from(...),
fileName, mimeType }) skips the real disk read entirely: Cypress constructs a real File object directly
from the given bytes and filename, which is genuinely useful for generating test fixtures on the fly
(a CSV with specific edge-case rows, an image of a specific exact size) without maintaining a library of
real files in the repository.
The real contrast with Selenium's sandboxed ERR_ACCESS_DENIED traces back to the same in-browser
architecture from Lesson 1: Cypress's own Node-side process
reads the real file and hands it to the browser context it's already directly embedded in, rather than a
separate out-of-process browser enforcing its own filesystem-access sandboxing against a path it didn't
choose and doesn't fully trust.
Common mistakes¶
- Assuming
selectFile()needs a real file on disk in every case — the in-memory buffer form in this lesson's second test is often more maintainable for generated or parameterized test data. - Using an absolute path when a path relative to the project root would be more portable across machines
and CI runners — this lesson's
"cypress/fixtures/real-upload.txt"works regardless of where the repo is checked out. - Forgetting that
selectFile()sets the files directly without simulating drag-and-drop by default — a page whose upload logic specifically listens fordropevents (rather than the input'schangeevent) needsselectFile(path, { action: "drag-drop" })instead of the default click-to-select simulation.
Exercise¶
Generate a real in-memory CSV buffer with exactly 1,000 rows (Cypress.Buffer.from(bigCsvString)) and
upload it via selectFile(), then check the real elapsed time Cypress reports for that command compared to
this lesson's small text-file uploads. Confirm whether selectFile()'s real performance scales
noticeably with payload size in this environment, or stays effectively constant for file sizes this small.