Skip to main content

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-TypeUse it when …
UploadThe test step needs to push this file into the application under test (e.g. a CV PDF on a job-application form).
Download ValidationThe file is a reference copy of something the application under test is expected to produce. Assign it to a download step as evidence.

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 Upload file 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 named report.pdf".
  • No file assigned to the step — if a file chooser is triggered anyway, the runner falls back to listing every Upload file in the tenant and picking one. This is a last-resort behaviour: don't rely on it. Assign the file explicitly.
tip

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 setInputFiles returns. 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.

Reference files (Download Validation)

You can attach a Download Validation file to a step to indicate "this is what the download should look like". The downloaded file appears next to the reference in the execution view, so a reviewer can compare them side-by-side. Use this for documentation of "expected vs. actual".

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").

tip

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.

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.open and target="_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 — three worked examples

Upload a CV PDF.

  1. In Settings → Files, upload cv.pdf with usage-type Upload, give it the library name CV.
  2. On the step "Upload the CV", open the step Settings sidebar and attach the CV file.
  3. Write the step in natural language: "Click 'Choose file' and upload the CV".

Download a generated invoice and keep a reference for review.

  1. In Settings → Files, upload invoice-reference.pdf with usage-type Download Validation.
  2. On the step that triggers the download, attach the reference file via the step Settings sidebar.
  3. Write: "Click 'Download invoice'". The runner captures the produced PDF and stores it as evidence next to the reference.

Verify a value inside a downloaded report.

  1. Step 1: "Click 'Generate report'" — the runner captures the PDF.
  2. Step 2: "Open the downloaded report" — the file is opened in a new tab.
  3. 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.