Skip to content
Bugwise
Menu
UI Components

File Upload

The button, drop zone and file list that send documents to a server. Learn native file inputs, drag and drop, mobile document pickers and per-file progress, and the type, size, file name and partial-failure bugs testers find in every upload.

35 min Inputs & selection iOS · Android · Web Also called: File picker, Dropzone, Attachment

You attach a scanned invoice to an expense claim, upload a signed rental contract, send a CSV of transactions to your accountant, add your CV to a job application. Then you press Submit and trust that every file arrived, complete and readable.

Sometimes it didn’t. The scanner saved the file as SCAN_0042.PDF and the app said “file type not supported”. The hotel invoice uploaded for two minutes before the app mentioned a 10 MB limit. One of three receipts failed on the train and quietly vanished from the list. File upload looks like one button, but it’s a small system of its own, and testers who know what to feed it find bugs every time.

What is a file upload?

A file upload component lets the user choose one or more files from their device and send them to a server. It usually has three jobs:

  1. Picking: a button that opens the system file picker, and on the web often a drop zone for drag and drop.
  2. Checking: is the type allowed, is it under the size limit, are there too many files?
  3. Uploading: sending each file, showing its progress, and handling cancel, failure and retry.

You’ll find it in expense apps (receipts), banking and insurance (statements, claims), job portals (CV), email and chat (attachments), cloud storage, and admin tools (CSV imports).

Anatomy

  1. 1

    Label and rules

    Says what to upload and the limits: allowed types, max size, max number of files. Shown before the user picks anything.

  2. 2

    Drop zone

    An area where files can be dropped (web, desktop). A shortcut, never the only way in.

  3. 3

    Browse button

    Opens the system file picker. A real, labelled button that works with touch, mouse, keyboard and screen readers.

  4. 4

    File row

    Icon, name (long names truncate in the middle, so the extension stays visible) and size.

  5. 5

    Per-file progress

    Each file shows its own progress and state: uploading, processing, uploaded, failed.

  6. 6

    Cancel / Remove

    Cancel stops a running upload; Remove takes a file out. Each button names its file for screen readers.

  7. 7

    Error + Retry

    A failed file stays in the list with a reason and a Retry button. It never silently disappears.

  8. 8

    Summary

    "2 of 3 uploaded · 1 failed". Tells the user whether it is safe to press Submit.

The states of one file

Every file in the list goes through its own life cycle, and the whole component is only “done” when all files are. A good list shows each file’s state separately:

StateWhat the user seesWhat to check
Rejected“Not added” with the reasonThe reason is specific: type, size, count, empty file
UploadingProgress bar, percentage, CancelThe bar moves; Cancel really stops the request
ProcessingBar full, “Processing…”The app doesn’t look frozen at 100%
UploadedCheck mark, RemoveThe server has the right file, complete and openable
FailedError text, Retry, RemoveThe file stays in the list; Retry works
Canceled“Canceled”, Retry or goneMatches the spec; nothing half-uploaded is kept

Designs & variants

The same idea appears as a plain browser input, a drop zone, a single “Upload CV” field, a paperclip in a chat, or the system document picker on a phone.

Most of these respond to taps. The first one is a real browser file input: try it with files from your own device.

Try it: the dialog filters to PDFs, but "All files" is one click away.

Native file input

Web

<input type="file"> with accept and multiple. Looks different in every browser, but keyboard and screen reader support come for free.

CV / Résumé

PDF or DOCX, max 5 MB

Single file field

Web · Forms

One file only, for a CV or an ID. After picking, the file shows with Replace and Remove instead of the button.

Here are the documents for the trip

Boarding pass.pdf
Message

Attachment in a composer

iOS · Android · Web

A paperclip in chat or email. Attachments appear as removable chips. Icon-only, so it needs an accessible name.

Upload your ID document

Choose File
Photo Library
Take Photo or Video
Choose File

Mobile browser file input

iOS Safari

On phones the same <input type="file"> opens a menu: photos, camera or files. The accept list changes which options appear.

CancelRecentsOpen
Search
Recents Shared Browse

Document picker (Files)

iOS

The system picker for documents. Apps get only the files the user picks, so no permission prompt is needed. Tap files to select them.

Recent
ImagesDocumentsAudio

Document picker (Storage Access Framework)

Android

The system 'Open from' picker. Also covers Google Drive and other providers. Tap files to select several.

The native file input

On the web, everything starts with <input type="file">. Two attributes matter most for testers:

  • accept (for example accept=".pdf,.docx" or accept="application/pdf") filters what the picker shows. It’s a hint, not a check: desktop dialogs offer an “All files” option, and files dropped onto a drop zone ignore accept completely.
  • multiple allows picking several files at once. Without it, the second file replaces the first, which surprises users who expected to add more.

Custom-designed upload buttons usually hide the real input and trigger it from a styled button. That’s fine, as long as the visible control is a real, focusable button.

Drag and drop is a shortcut, not the way in

A drop zone is great on a desktop with a file explorer open. It’s useless on a phone, for keyboard users, for many screen reader users and for anyone who finds dragging hard. Drag and drop must always come with a Browse button that does the same thing. Testers also check what happens when a file is dropped outside the zone: the browser shouldn’t simply open the PDF and leave the page (with the user’s half-filled form).

Mobile document pickers

Phones don’t let apps browse the whole file system. Instead, the app asks the system picker, the user chooses, and the app gets access to just those files. No storage permissionApp permissionsThe user's approval for an app to use things like the camera, location, contacts or notifications.Open in glossary → is needed for this.

iOSAndroid
PickerDocument picker (the Files app UI: Recents, Shared, Browse)Storage Access Framework picker (“Open from”, Recent, Downloads, Drive)
SourcesOn My iPhone, iCloud Drive and installed providers like Google Drive or DropboxDevice storage, Downloads, and providers like Google Drive
MultipleOnly if the app enables itOnly if the app requests it
Typical trapsCloud files not downloaded yet, file names with emoji, files from other apps that disappear laterFiles without a real name or size, Drive files that need a download first, older OS versions

On a mobile website, the same <input type="file"> opens a system menu instead of a desktop dialog (on iPhone: Photo Library, Take Photo or Video, Choose File). The accept list changes which options appear, so test on real phones, not only in a desktop browser.

Push it to the limits

This is a correct uploader for an expense claim. Change the rules and the network: the same files are uploaded again each time, so you can compare. Then add files from the test kit at the bottom (drag them, or tap them).

🧪 Upload lab

A correct uploader for an expense claim. Change the rules and the network: the same files are uploaded again, so you can compare the results.

Receipts and documents

PDF, DOCX, CSV or ZIP · up to 10 MB each · max 10 files, 60 MB in total

Drag files here, or

0 of 0 uploaded · 0 B of 60 MB
  • No files yet.

Screen reader hears (aria-live)

    The client catches the duplicate, the server catches the renamed PNG. Now try exact-case checking, turning client checks off, or an unstable network.

    Your test files

    Drag a file onto the drop zone, or tap it to add it.

    A few things to try, and what they teach:

    • Extension, exact case rejects SCAN_0042.PDF. Users don’t care about letter case, and many scanners and older systems write uppercase extensions.
    • MIME type (File.type) looks smarter, but the browser usually guesses the type from the extension. holiday-photo.pdf (a PNG renamed to .pdf) still passes. Only the server, looking at the actual bytes, can catch it.
    • Client-side checks off shows why the app should check early: the 48 MB ZIP uploads completely before the server says no. The server still protects itself, but the user wasted time and mobile data.
    • Unstable network: failed files stay in the list with Retry. Nothing silently disappears.

    File names are test data

    The name is the part of a file that developers forget most. Keep these in your test kitTest dataThe input values, accounts and records you use while testing.Open in glossary →:

    NameWhat can go wrong
    SCAN_0042.PDFUppercase extension rejected
    Lease agreement (signed) final.docxSpaces and brackets break links or downloads
    A 120-character nameOverflows the row, pushes the Remove button off-screen, or is cut by the server
    Mietvertrag_endgültig.pdf, Résumé.pdf, 报告.pdf, 🧾.pdfdiacriticsDiacriticsAccent marks on letters, like é, ü, č or ž. Search usually should ignore them.Open in glossary →, other scripts and emoji turn into ??? or ü
    invoice.pdf.exe, report. and a name without any extensionWrong type detected, or the app crashes on a missing extension
    Invoice_March.pdf twice (from two folders)Duplicate, or the second silently overwrites the first on the server

    When to use it

    • The user has to provide a document that already exists on their device or in the cloud: receipts, contracts, statements, CVs.
    • The content is too big or too structured to type: a CSV import, a ZIP of project files.
    • Several files belong together and should be checked and submitted as one set (an insurance claim with photos, invoices and a police report).

    Good and bad uses

    Drag and drop plus a Browse button

    Drag files here, or

    Browse files

    Works with a mouse, a finger, a keyboard and a screen reader.

    Drag and drop only

    Drop your files here

    On a phone or with a keyboard there is simply no way to add a file.

    Rules shown before picking

    Upload your bank statement

    PDF or CSV · up to 10 MB

    statement_2025_full_year.pdf

    24.3 MB is over the 10 MB limit. Not uploaded.

    The user knows the limit up front, and the oversized file is stopped instantly with a specific message.

    Rules revealed by the error

    Upload your bank statement

    statement_2025_full_year.pdf

    Upload failed (after 2 min 10 s)

    No limit mentioned, two minutes of uploading, then a generic failure.

    Long names truncate in the middle

    Hotel_invoice_Grand_Hotel_Europa_Innsbruck_2026-09-14_booking_884213.pdf

    1.4 MB · Uploaded

    The extension and the Remove button stay visible.

    Long names push everything out

    Hotel_invoice_Grand_Hotel_Europa_Innsbruck_2026-09-14_booking_884213.pdf

    1.4 MB · Uploaded

    The name runs off the card and takes the Remove button with it.

    Also don’t ask for a file when a few typed fields would do (an IBAN, a date, a policy number), and don’t make users upload something the app could fetch itself.

    Common bugs

    #BugWhat you seeTypical severity
    1Browse not keyboard reachableThe drop zone works with a mouse, but Tab never reaches a buttonHigh (for affected users)
    2Case-sensitive type checkSCAN_0042.PDF or .JPG rejectedMedium–High
    3Limits hiddenSize or count limit shown only after a long upload failsMedium
    4Wrong file removedTapping Remove on one file removes a different oneHigh (wrong documents submitted)
    5Failure swallowedA failed file disappears, or the claim is sent without itHigh
    6Long names break the layoutName overflows, Remove button off-screen, text overlapsMedium
    7No progress or cancelSpinner forever, no way to stop a wrong 200 MB uploadMedium
    8DuplicatesSame file attached twice, or a second file with the same name overwrites the firstMedium
    9Server trusts the clientRenamed or oversized files are accepted when sent directlyHigh (security)
    10Partial failure hidden“Upload complete” while 1 of 3 files failedHigh
    11Special characters mangledMietvertrag_endgültig.pdf arrives as Mietvertrag_endgültig.pdfLow–Medium
    12Submit during uploadSubmit works while files are still uploading; the claim arrives without themHigh

    Find the bug

    This expense claim form has six upload bugs. Explore it like a tester:

    • Click in Description, then use only Tab and Enter to add a receipt.
    • Add every file from Files on your computer, by dragging and by tapping. Read every message and the network log.
    • Add two or three files, then remove the top one.
    • Turn on Unstable network and add several small files. Count them.

    🐞 Bug hunt: Expense claim receipts

    This demo has 6 hidden bugs. Explore it like a tester, then check your findings.

    Found0/6
    expenses.example.com

    New expense claim

    Receipts

    PDF, DOCX, XLSX or CSV

    Drop receipts here or browse

      0 files attached

      Files on your computer

      Drag a file onto the drop zone, or tap it to add it.

      Device settings

      Network log

      • Add a receipt to see upload requests…
      1. 1

        Hint: Click in the Description field, then press Tab. Where does focus go?

      2. 2

        Hint: Add the file from the scanner.

      3. 3

        Hint: Read the hint under "Receipts", then add Hotel_folio_scan_600dpi.pdf and watch.

      4. 4

        Hint: Add Taxi_receipt.pdf, then Flight_LH1234.pdf. Remove the top one.

      5. 5

        Hint: Turn on Unstable network and add three or four small files one by one.

      6. 6

        Hint: Add the hotel invoice with the very long name. Try to remove it.

      How to test it

      Upload limits are perfect for boundary value analysis: with a 10 MB limit, test 9.9 MB, exactly 10 MB and 10.1 MB, plus a 0-byte file. With “max 5 files”, try 4, 5 and 6, and also 3 + 3 in two rounds.

      Checklist

      File upload test checklist

      0 of 16 checked

      Example test cases

      TC-FU-001Add a receipt with the keyboard only

      Preconditions

      • Web, desktop browser, no mouse

      Steps

      1. Tab to the Browse files button
      2. Press Enter
      3. Pick Taxi_receipt.pdf in the dialog and confirm

      Expected result

      Focus ring is visible on Browse. The picker opens; after picking, focus returns near the upload area and the file appears with progress. A screen reader announces "Taxi_receipt.pdf added".

      TC-FU-002Uppercase extension is accepted

      Steps

      1. Add SCAN_0042.PDF (a valid PDF)

      Test data

      Also: report.Pdf, contract.DOCX

      Expected result

      The file is accepted and uploaded like a lowercase .pdf.

      TC-FU-003File size at the boundaries

      Preconditions

      • Limit is 10 MB per file

      Steps

      1. Add a 9.9 MB PDF
      2. Add a PDF of exactly 10 MB
      3. Add a 10.1 MB PDF
      4. Add a 0-byte PDF

      Expected result

      9.9 MB and 10 MB upload. 10.1 MB is rejected instantly, before any upload request, with "Larger than 10 MB". The empty file is rejected with "This file is empty".

      TC-FU-004Server rejects a renamed file

      Preconditions

      • Test environment
      • Proxy tool or DevTools available

      Steps

      1. Rename a PNG image to holiday-photo.pdf
      2. Upload it through the app
      3. Send it again directly to the upload endpoint, bypassing the app

      Expected result

      Both attempts are rejected (for example 415) with a clear message. Nothing is stored.

      TC-FU-005Remove the correct file

      Steps

      1. Add A.pdf, B.pdf and C.pdf
      2. Remove B.pdf
      3. Remove the top file
      4. Remove the bottom file

      Expected result

      Each time exactly the file in that row disappears. The counter and the submitted claim match the list.

      TC-FU-006Partial failure with retry

      Steps

      1. Add three files
      2. Switch the network off while the second one uploads
      3. Switch it back on
      4. Tap Retry on the failed file

      Expected result

      Files 1 and 3 upload (or wait for the network). File 2 shows "Upload failed" with Retry and stays in the list. Submit is blocked or warns. After Retry, all three are uploaded.

      TC-FU-007Long and unicode file names

      Steps

      1. Add a file with a 120-character name
      2. Add Mietvertrag_endgültig.pdf and 报告.pdf
      3. Submit, then open the claim and download each file

      Expected result

      Names truncate in the middle with the extension visible; Remove stays visible. After download, names and contents are unchanged.

      TC-FU-008Pick several documents on Android

      Preconditions

      • Android device with a PDF in Downloads and one in Google Drive

      Steps

      1. Tap Attach
      2. In the system picker, long-press to select both files
      3. Tap Select

      Expected result

      Both files appear with their real names and sizes and upload. The Drive file is downloaded first if needed, with progress.

      Tip: click a test case to expand it.

      Accessibility

      • A real, labelled button. The control that opens the picker must be a real button with a clear name like “Browse files” or “Attach receipt”. An icon-only paperclip needs an accessible name. Test keyboard navigationKeyboard navigationUsing a website with only the keyboard: Tab to move, Enter or Space to activate, Esc to close.Open in glossary →: Tab reaches it, Enter and Space open the picker (WCAG 2.1.1 Keyboard, Level A).
        Dev note
        A <button> (or a native file input).
      • Drag and drop is optional. Everything must work without dragging. That’s what keyboard, switch, screen readerScreen readerSoftware that reads the screen aloud for blind and low-vision users, like VoiceOver or TalkBack.Open in glossary → and most touch users rely on.
      • Rules are instructions. Allowed types and limits are visible text near the control (WCAG 3.3.2 Labels or Instructions, Level A).
        Dev note
        The text is connected with aria-describedby.
      • Announce what happens. “Invoice.pdf added”, “uploaded” and “failed” should reach screen readers without moving focus, through a live region, per WCAG 4.1.3 Status Messages (Level AA). Errors are text, not only a red border (WCAG 3.3.1 Error Identification, Level A).
        Dev note
        aria-live="polite", or role="status".
      • Name every row action. “Remove Invoice_March.pdf”, “Retry Flight_LH1234.pdf”, not five buttons called ”×”. Progress bars need a name and value.
        Dev note
        role="progressbar" with aria-valuenow, or a native <progress>.
      • Focus after actions. After picking files, focus returns to the upload area. After removing a file, focus moves to a sensible place (the next row or the Browse button), not to the top of the page.
      • Touch targetsTouch targetThe area of the screen that responds to a tap, which should be large enough for a finger.Open in glossary →: Browse, Remove and Retry are at least 44×44 pt on iOS and 48×48 dp on Android. On the web, WCAG 2.5.8 (AA) asks for at least 24×24 CSS px; 44×44 px (2.5.5, AAA) is the comfortable target.
      • Not color alone. Failed and uploaded states use an icon and text, not just red and green. Text needs 4.5:1 contrast, icons and borders 3:1 (WCAG 1.4.3 / 1.4.11).

      Mobile vs web

      • Apps open the document picker. Multiple selection and allowed types are set by the app; check both match the spec.
        Dev note
        UIKit UIDocumentPickerViewController, SwiftUI fileImporter.
      • Picked files can live in iCloud Drive or another provider and may need to download first. Test with a file that isn’t on the device yet, and in airplane mode.
      • Test Cancel in the picker: the app should simply return, not show an error or an empty attachment.
      • Uploads should survive locking the phone or switching apps, or fail clearly (Background and foreground).
      • In Safari, the file input offers Photo Library, camera and Files. Choosing a photo there is where Image Upload topics (HEIC, EXIF) start.
      • Apps use the Storage Access Framework picker. It needs no storage permission; an app that asks for full storage access just to attach a PDF is worth questioning (App permissions).
        Dev note
        ACTION_OPEN_DOCUMENT / ACTION_GET_CONTENT, or the Activity Result APIs in modern apps.
      • Name and size come from the provider and can be missing; check the list still shows something sensible.
        Dev note
        The app gets a content:// link, not a file path.
      • Test files from Downloads, Google Drive and an SD card or USB drive if the device has one, and selecting several files with a long-press.
      • Rotate the device and switch apps while the picker is open: the app must not lose the files already attached (Interruptions).
      • <input type="file"> with accept and multiple. Remember: accept only filters the dialog; “All files” and drag and drop bypass it.
      • Drag and drop: one file, several files, a folder, a non-allowed type, and a drop outside the zone.
      • Use the DevTools Network panel: is the request multipart/form-data, does the size match, what status comes back? Throttle to “3G” to watch progress and cancel (DevTools for testers).
      • Reloading or closing the tab during an upload should warn the user or resume cleanly.
      • Test Chrome, Safari and Firefox: the native input looks and behaves differently in each, and so do drop events.

      Check your understanding

      Quick quiz

      0/5 answered · 0 correct

      1. 1.An upload form has accept=".pdf" on its file input. Does that guarantee only PDFs reach the server?

      2. 2.The drop zone works with a mouse, but Tab never reaches a Browse button. What kind of bug is it?

      3. 3.The size limit is 10 MB. Which set of files is best for boundary testing?

      4. 4.Three files are uploaded and one fails. What should the user see?

      5. 5.Why should a long file name truncate in the middle?

      Key takeaways

      • File upload is three jobs: picking, checking and uploading. Each file has its own state: rejected, uploading, processing, uploaded, failed, canceled.
      • Drag and drop is a shortcut. A real, labelled Browse button must do the same, for keyboard, screen reader and phone users.
      • Show the rules up front (types, size, count) and reject bad files before uploading, with a specific message.
      • Client checks are convenience. The server must check the real content, size and count. Type checks must ignore letter case.
      • File names are test data: long, unicode, spaces, uppercase extensions, the same name twice.
      • Partial failures must stay visible with Retry; Remove must remove exactly that file; Submit must not run ahead of uploads.

      Finished this page?Nice work, this page is complete!

      Mark it as done to track your progress. It's saved in this browser, no account needed.

      Its review cards are now in Bites ⚡
      Esc

      Type to search the whole site.