Skip to main content
SeleniumDecoded

File Uploads

Handle file uploads in Selenium tests by interacting with file input elements.

Selenium 3 & 4 Stable

File uploads are a common form interaction. Selenium handles them by sending the file path directly to the file input element.

Basic File Upload

The key is to use sendKeys() with the absolute file path on the <input type="file"> element:

Simple File Upload
Selenium 3 & 4 Stable
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.io.File;
// Locate the file input element
WebElement fileInput = driver.findElement(By.id("file-upload"));
// Get absolute path to file
File file = new File("src/test/resources/test-document.pdf");
String absolutePath = file.getAbsolutePath();
// Upload by sending the file path
fileInput.sendKeys(absolutePath);
// Click submit to complete upload
driver.findElement(By.id("submit")).click();
// Verify upload success
WebElement successMsg = driver.findElement(By.id("uploaded-files"));
Assert.assertTrue(successMsg.getText().contains("test-document.pdf"));
from selenium.webdriver.common.by import By
import os
# Locate the file input element
file_input = driver.find_element(By.ID, "file-upload")
# Get absolute path to file
file_path = os.path.abspath("tests/resources/test-document.pdf")
# Upload by sending the file path
file_input.send_keys(file_path)
# Click submit to complete upload
driver.find_element(By.ID, "submit").click()
# Verify upload success
success_msg = driver.find_element(By.ID, "uploaded-files")
assert "test-document.pdf" in success_msg.text
const { By } = require('selenium-webdriver');
const path = require('path');
// Locate the file input element
const fileInput = await driver.findElement(By.id('file-upload'));
// Get absolute path to file
const filePath = path.resolve('test/resources/test-document.pdf');
// Upload by sending the file path
await fileInput.sendKeys(filePath);
// Click submit to complete upload
await driver.findElement(By.id('submit')).click();
// Verify upload success
const successMsg = await driver.findElement(By.id('uploaded-files'));
const text = await successMsg.getText();
expect(text).to.include('test-document.pdf');
using OpenQA.Selenium;
using System.IO;
// Locate the file input element
IWebElement fileInput = driver.FindElement(By.Id("file-upload"));
// Get absolute path to file
string filePath = Path.GetFullPath("TestData/test-document.pdf");
// Upload by sending the file path
fileInput.SendKeys(filePath);
// Click submit to complete upload
driver.FindElement(By.Id("submit")).Click();
// Verify upload success
IWebElement successMsg = driver.FindElement(By.Id("uploaded-files"));
Assert.That(successMsg.Text, Does.Contain("test-document.pdf"));

Hidden File Inputs

Many modern sites hide the actual file input and use custom styling. You may need to make it visible first:

Handling Hidden File Inputs
Selenium 3 & 4 Stable
import org.openqa.selenium.JavascriptExecutor;
// File input is hidden with display:none or visibility:hidden
WebElement fileInput = driver.findElement(By.cssSelector("input[type='file']"));
// Make visible using JavaScript
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(
"arguments[0].style.display='block';" +
"arguments[0].style.visibility='visible';" +
"arguments[0].style.opacity='1';",
fileInput
);
// Now send the file path
fileInput.sendKeys("/path/to/file.pdf");
# File input is hidden with display:none or visibility:hidden
file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
# Make visible using JavaScript
driver.execute_script("""
arguments[0].style.display='block';
arguments[0].style.visibility='visible';
arguments[0].style.opacity='1';
""", file_input)
# Now send the file path
file_input.send_keys("/path/to/file.pdf")
// File input is hidden with display:none or visibility:hidden
const fileInput = await driver.findElement(By.css("input[type='file']"));
// Make visible using JavaScript
await driver.executeScript(`
arguments[0].style.display='block';
arguments[0].style.visibility='visible';
arguments[0].style.opacity='1';
`, fileInput);
// Now send the file path
await fileInput.sendKeys('/path/to/file.pdf');
using OpenQA.Selenium;
// File input is hidden with display:none or visibility:hidden
IWebElement fileInput = driver.FindElement(By.CssSelector("input[type='file']"));
// Make visible using JavaScript
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript(@"
arguments[0].style.display='block';
arguments[0].style.visibility='visible';
arguments[0].style.opacity='1';
", fileInput);
// Now send the file path
fileInput.SendKeys(@"C:path o ile.pdf");

Multiple File Upload

Some inputs accept multiple files using the multiple attribute:

Upload Multiple Files
Selenium 3 & 4 Stable
WebElement fileInput = driver.findElement(By.id("multi-upload"));
// For multiple files, join paths with newline
String file1 = new File("file1.pdf").getAbsolutePath();
String file2 = new File("file2.pdf").getAbsolutePath();
String file3 = new File("file3.pdf").getAbsolutePath();
// Send all paths separated by newline
fileInput.sendKeys(file1 + "\n" + file2 + "\n" + file3);
file_input = driver.find_element(By.ID, "multi-upload")
# For multiple files, join paths with newline
import os
files = [
os.path.abspath("file1.pdf"),
os.path.abspath("file2.pdf"),
os.path.abspath("file3.pdf")
]
# Send all paths separated by newline
file_input.send_keys("\n".join(files))
const fileInput = await driver.findElement(By.id('multi-upload'));
// For multiple files, join paths with newline
const path = require('path');
const files = [
path.resolve('file1.pdf'),
path.resolve('file2.pdf'),
path.resolve('file3.pdf')
];
// Send all paths separated by newline
await fileInput.sendKeys(files.join('\n'));
IWebElement fileInput = driver.FindElement(By.Id("multi-upload"));
// For multiple files, join paths with newline
string[] files = {
Path.GetFullPath("file1.pdf"),
Path.GetFullPath("file2.pdf"),
Path.GetFullPath("file3.pdf")
};
// Send all paths separated by newline
fileInput.SendKeys(string.Join("\n", files));

Drag and Drop Upload Zones

Some sites use drag-and-drop zones. These require JavaScript to simulate file drop:

Drag-Drop Upload Zone
Selenium 4 Medium
// For drag-drop zones, we need to trigger events via JavaScript
// First, check if there's a hidden file input associated with the drop zone
WebElement dropZone = driver.findElement(By.id("drop-zone"));
// Many drop zones have a hidden input - find and use it
WebElement hiddenInput = driver.findElement(
By.cssSelector("#drop-zone input[type='file'], input[type='file'][name='file']")
);
hiddenInput.sendKeys(new File("upload.pdf").getAbsolutePath());
// If no hidden input, you may need to use a library or different approach
# For drag-drop zones, we need to trigger events via JavaScript
# First, check if there's a hidden file input associated with the drop zone
drop_zone = driver.find_element(By.ID, "drop-zone")
# Many drop zones have a hidden input - find and use it
hidden_input = driver.find_element(
By.CSS_SELECTOR, "#drop-zone input[type='file'], input[type='file'][name='file']"
)
hidden_input.send_keys(os.path.abspath("upload.pdf"))
# If no hidden input, you may need to use a library or different approach
// For drag-drop zones, we need to trigger events via JavaScript
// First, check if there's a hidden file input associated with the drop zone
const dropZone = await driver.findElement(By.id('drop-zone'));
// Many drop zones have a hidden input - find and use it
const hiddenInput = await driver.findElement(
By.css("#drop-zone input[type='file'], input[type='file'][name='file']")
);
await hiddenInput.sendKeys(path.resolve('upload.pdf'));
// If no hidden input, you may need to use a library or different approach
// For drag-drop zones, we need to trigger events via JavaScript
// First, check if there's a hidden file input associated with the drop zone
IWebElement dropZone = driver.FindElement(By.Id("drop-zone"));
// Many drop zones have a hidden input - find and use it
IWebElement hiddenInput = driver.FindElement(
By.CssSelector("#drop-zone input[type='file'], input[type='file'][name='file']")
);
hiddenInput.SendKeys(Path.GetFullPath("upload.pdf"));
// If no hidden input, you may need to use a library or different approach

Remote WebDriver File Uploads

When using Selenium Grid or remote browsers, files must be transferred:

Remote File Upload
Selenium 4 Stable
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
// Set file detector for remote uploads
RemoteWebDriver remoteDriver = (RemoteWebDriver) driver;
remoteDriver.setFileDetector(new LocalFileDetector());
// Now uploads work the same way
WebElement fileInput = driver.findElement(By.id("file-upload"));
fileInput.sendKeys(new File("local-file.pdf").getAbsolutePath());
from selenium.webdriver.remote.file_detector import LocalFileDetector
# Set file detector for remote uploads
driver.file_detector = LocalFileDetector()
# Now uploads work the same way
file_input = driver.find_element(By.ID, "file-upload")
file_input.send_keys(os.path.abspath("local-file.pdf"))
// In selenium-webdriver for JavaScript, file detection
// is handled automatically for remote drivers
// Just use the local file path as normal
const fileInput = await driver.findElement(By.id('file-upload'));
await fileInput.sendKeys(path.resolve('local-file.pdf'));
using OpenQA.Selenium.Remote;
// For .NET, set the file detector
var remoteDriver = (RemoteWebDriver)driver;
remoteDriver.FileDetector = new LocalFileDetector();
// Now uploads work the same way
IWebElement fileInput = driver.FindElement(By.Id("file-upload"));
fileInput.SendKeys(Path.GetFullPath("local-file.pdf"));

Waiting for Upload Completion

Always verify the upload completed successfully:

Verify Upload Completion
Selenium 3 & 4 Stable
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
// Upload the file
fileInput.sendKeys(filePath);
// Wait for upload progress to complete
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
// Option 1: Wait for success message
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".upload-success")
));
// Option 2: Wait for progress bar to reach 100%
wait.until(ExpectedConditions.textToBe(
By.id("progress-text"), "100%"
));
// Option 3: Wait for file name to appear in list
wait.until(ExpectedConditions.textToBePresentInElementLocated(
By.id("file-list"), "uploaded-file.pdf"
));
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Upload the file
file_input.send_keys(file_path)
# Wait for upload progress to complete
wait = WebDriverWait(driver, 30)
# Option 1: Wait for success message
wait.until(EC.visibility_of_element_located(
(By.CSS_SELECTOR, ".upload-success")
))
# Option 2: Wait for progress bar to reach 100%
wait.until(EC.text_to_be_present_in_element(
(By.ID, "progress-text"), "100%"
))
# Option 3: Wait for file name to appear in list
wait.until(EC.text_to_be_present_in_element(
(By.ID, "file-list"), "uploaded-file.pdf"
))
const { until } = require('selenium-webdriver');
// Upload the file
await fileInput.sendKeys(filePath);
// Wait for upload progress to complete
// Option 1: Wait for success message
await driver.wait(
until.elementLocated(By.css('.upload-success')),
30000
);
// Option 2: Wait for file name to appear
await driver.wait(async () => {
const fileList = await driver.findElement(By.id('file-list'));
const text = await fileList.getText();
return text.includes('uploaded-file.pdf');
}, 30000);
using OpenQA.Selenium.Support.UI;
// Upload the file
fileInput.SendKeys(filePath);
// Wait for upload progress to complete
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
// Option 1: Wait for success message
wait.Until(d => d.FindElement(By.CssSelector(".upload-success")).Displayed);
// Option 2: Wait for file name to appear in list
wait.Until(d => d.FindElement(By.Id("file-list")).Text.Contains("uploaded-file.pdf"));

Best Practices

PracticeDescription
Use absolute pathsRelative paths may not resolve correctly
Create test filesInclude sample files in your test resources
Handle hidden inputsUse JavaScript to make inputs visible if needed
Wait for completionDon’t assume upload is instant
Clean upDelete test uploads after test if possible
Set file detectorRequired for remote/Grid uploads

Common Issues

IssueSolution
Element not interactableMake hidden input visible with JavaScript
File not foundUse absolute path, verify file exists
Remote upload failsSet LocalFileDetector
Upload timeoutIncrease wait time for large files

Next Steps