Files: Upload, Download and Open
Tests frequently need to deal with files — uploading a CV PDF, downloading a generated invoice, opening a report in a new tab. This chapter explains how msg.ZenTestAI handles those at execution time, how to wire files into your test steps, and what limitations to be aware of.
The Files library
All files that a test can upload live in the central file library under Settings → Files (see File Upload for managing the library itself). Files are tenant-scoped, persist between runs, and are referenced by their internal id — so renaming or replacing a file does not break existing test steps that point to it.
Each file has a Usage-Type, which determines how the runner treats it:
| Usage-Type | Use it when … |
|---|---|
| Upload | The test step needs to push this file into the application under test (e.g. a CV PDF on a job-application form). |
Downloads produced during a run are not stored in the file library — they are captured as execution artifacts and shown next to the step that produced them in the execution view.
Uploads
Connecting a file to a step
In the test details, open the step's Settings sidebar and use the Files picker. You can attach one or several Upload-type files from the library. The chosen files become part of the step's context and travel with the test when it runs.
How the runner uploads
When the step runs, the AI agent watches for any <input type="file"> element it needs to interact with. As soon as that file input is targeted, the runner calls Playwright's native setInputFiles with the file(s) you assigned to the step — no manual file-chooser dialog has to be solved, the upload happens via the browser's normal file-input API.
What this means for you:
- Single file — write the prompt naturally ("Upload the CV"). The runner picks the only
Uploadfile assigned to the step. - Multiple files on one step — the AI looks at the
<input>element's attributes (multiple,accept,webkitdirectory) to decide whether to upload all the assigned files at once, or pick the right one by file name / type. You can also disambiguate in the prompt: "Upload the file namedreport.pdf". - No file assigned to the step — if a file chooser is triggered anyway, the runner falls back to listing every
Uploadfile in the tenant and picking one. This is a last-resort behaviour: don't rely on it. Assign the file explicitly.
Keep file uploads to one per step. Multi-file uploads are harder to debug and harder for the AI to disambiguate when they fail.
What the runner does not do for uploads
- No drag-and-drop uploads. Applications that only accept files via HTML5 drag-and-drop (without a fallback
<input type="file">) are not supported. If you can target the file input directly, do so. - No post-upload assertion. The runner considers the upload successful as soon as
setInputFilesreturns. If you need to verify that the application actually accepted the file (e.g. a filename pill appeared), add a separate assertion step.
Downloads
How the runner captures downloads
The runner listens for browser download events at all times — there is no special "download" step type and no checkbox to flip. Anything the application triggers as a download (a form submission, a Content-Disposition: attachment response, an anchor with download, a PDF navigated to directly, …) is captured automatically.
Captured downloads are:
- saved to a temporary location for the duration of the test execution,
- attached as evidence to the step that triggered them, viewable in the execution UI,
- remembered in the test's context so a later step can refer back to "the downloaded file".
PDFs that would normally render inline in the browser are intercepted and treated as downloads as well, so the same flow works for "view this PDF" links.
Multiple downloads in one step
The runner tracks every download a step produces, not just the first one. If a single click triggers multiple downloads (e.g. "Export all"), each file is captured and listed under the step's evidence.
Opening a previously downloaded file
A common pattern is download in one step → open in the next → assert on the content. msg.ZenTestAI supports this:
Step 1: Click the "Download invoice" link
Step 2: Open the downloaded invoice
Step 3: Verify that the invoice contains the customer name "Acme Ltd"
In Step 2, the runner recognises "open the downloaded …" (or similar wording) as a request to navigate to one of the files the current execution has already captured. It opens the file in a new tab, and the test continues against that tab from the next step.
When more than one file has been downloaded in the same execution, refer to the one you mean by file name or position ("open the most recent download", "open the file report-2026-05.pdf").
If you need the application under test to consume a previously downloaded file as an upload (e.g. download a template, edit it, re-upload it), assign the file as if it were an Upload and the runner will re-use it in the next step's file-input interaction.
Capturing a download into a parameter
Opening a download (above) works within a single test run. To carry a downloaded file beyond that test — so a later test, or a later run, can reuse it — remember it in a parameter.
Add a Remember Parameter Value step (the Advanced Features action category in the step editor) and write it in natural language, ending with the target parameter:
Step 1: Click the "PDF" link in the Dictionary section
Step 2: Remember the just downloaded file in parameter [[downloaded-file]]
Typing [[downloaded-file]] turns it into a parameter chip. When the test runs, the captured download is stored in that parameter as a file value rather than plain text. After the run, open the test's info panel in the execution view: under Parameters & Calculations the downloaded-file parameter shows the captured file with a download button (here, dictionary.pdf) so you can pull it straight from the result.
Passing a captured file between tests
Because a file lives in a normal parameter, it flows between tests in an execution plan exactly like any other value. Put the producing test in an earlier group and the consuming test in a later group; on the consumer's Parameter Bindings dialog the file parameter is wired up automatically by Map by name (or pin it explicitly with From a specific source test). File-typed bindings render a download icon, so you can confirm at a glance that a real file — not just a string — is being handed from one test to the next.
A downstream test can then upload that same file again (assign it as an Upload as described above), letting you chain "download in test A → re-upload in test B" flows across an entire plan.
Because the captured file is exposed to your scripts, it can be inspected or modified along the way before a later step or test consumes it — opening the door to more complex automation than a plain download-and-reopen.
Limitations and gotchas
- No content assertions out of the box. The runner does not extract PDF text, OCR images, or compare file contents byte-for-byte. To assert on a downloaded file's contents, open it (see above) and assert against what the browser renders — works well for PDFs that have a selectable text layer or HTML reports.
- Authenticated downloads work — the download inherits the browser's session. No extra configuration needed.
- Downloads from sub-iframes are handled the same as main-frame downloads.
window.openandtarget="_blank"downloads are captured automatically; you don't have to switch tabs first.- Files are ephemeral. Anything downloaded during a run is not promoted back into the Files library and is removed once execution evidence is cleaned up. To keep a download permanently, upload it manually to the library.
- Size limits apply to the files you upload to the library, not to what the application under test produces. See File Upload for the current limits.
Putting it together — two worked examples
Upload a CV PDF.
- In Settings → Files, upload
cv.pdfwith usage-typeUpload, give it the library name CV. - On the step "Upload the CV", open the step Settings sidebar and attach the CV file.
- Write the step in natural language: "Click 'Choose file' and upload the CV".
Verify a value inside a downloaded report.
- Step 1: "Click 'Generate report'" — the runner captures the PDF.
- Step 2: "Open the downloaded report" — the file is opened in a new tab.
- Step 3: "Verify that the report contains the total amount of EUR 12.345,67" — runs against the rendered PDF in the new tab.
See also: File Upload for managing files in the library, Prompting for the natural-language step syntax, and Handling of tabs for working with the new tab that "Open …" produces.