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 elementWebElement fileInput = driver.findElement(By.id("file-upload"));
// Get absolute path to fileFile file = new File("src/test/resources/test-document.pdf");String absolutePath = file.getAbsolutePath();
// Upload by sending the file pathfileInput.sendKeys(absolutePath);
// Click submit to complete uploaddriver.findElement(By.id("submit")).click();
// Verify upload successWebElement successMsg = driver.findElement(By.id("uploaded-files"));Assert.assertTrue(successMsg.getText().contains("test-document.pdf"));from selenium.webdriver.common.by import Byimport os
# Locate the file input elementfile_input = driver.find_element(By.ID, "file-upload")
# Get absolute path to filefile_path = os.path.abspath("tests/resources/test-document.pdf")
# Upload by sending the file pathfile_input.send_keys(file_path)
# Click submit to complete uploaddriver.find_element(By.ID, "submit").click()
# Verify upload successsuccess_msg = driver.find_element(By.ID, "uploaded-files")assert "test-document.pdf" in success_msg.textconst { By } = require('selenium-webdriver');const path = require('path');
// Locate the file input elementconst fileInput = await driver.findElement(By.id('file-upload'));
// Get absolute path to fileconst filePath = path.resolve('test/resources/test-document.pdf');
// Upload by sending the file pathawait fileInput.sendKeys(filePath);
// Click submit to complete uploadawait driver.findElement(By.id('submit')).click();
// Verify upload successconst 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 elementIWebElement fileInput = driver.FindElement(By.Id("file-upload"));
// Get absolute path to filestring filePath = Path.GetFullPath("TestData/test-document.pdf");
// Upload by sending the file pathfileInput.SendKeys(filePath);
// Click submit to complete uploaddriver.FindElement(By.Id("submit")).Click();
// Verify upload successIWebElement 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:hiddenWebElement fileInput = driver.findElement(By.cssSelector("input[type='file']"));
// Make visible using JavaScriptJavascriptExecutor 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 pathfileInput.sendKeys("/path/to/file.pdf");# File input is hidden with display:none or visibility:hiddenfile_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
# Make visible using JavaScriptdriver.execute_script(""" arguments[0].style.display='block'; arguments[0].style.visibility='visible'; arguments[0].style.opacity='1';""", file_input)
# Now send the file pathfile_input.send_keys("/path/to/file.pdf")// File input is hidden with display:none or visibility:hiddenconst fileInput = await driver.findElement(By.css("input[type='file']"));
// Make visible using JavaScriptawait driver.executeScript(` arguments[0].style.display='block'; arguments[0].style.visibility='visible'; arguments[0].style.opacity='1';`, fileInput);
// Now send the file pathawait fileInput.sendKeys('/path/to/file.pdf');using OpenQA.Selenium;
// File input is hidden with display:none or visibility:hiddenIWebElement fileInput = driver.FindElement(By.CssSelector("input[type='file']"));
// Make visible using JavaScriptIJavaScriptExecutor 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 pathfileInput.SendKeys(@"C:path oile.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 newlineString 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 newlinefileInput.sendKeys(file1 + "\n" + file2 + "\n" + file3);file_input = driver.find_element(By.ID, "multi-upload")
# For multiple files, join paths with newlineimport osfiles = [ os.path.abspath("file1.pdf"), os.path.abspath("file2.pdf"), os.path.abspath("file3.pdf")]
# Send all paths separated by newlinefile_input.send_keys("\n".join(files))const fileInput = await driver.findElement(By.id('multi-upload'));
// For multiple files, join paths with newlineconst path = require('path');const files = [ path.resolve('file1.pdf'), path.resolve('file2.pdf'), path.resolve('file3.pdf')];
// Send all paths separated by newlineawait fileInput.sendKeys(files.join('\n'));IWebElement fileInput = driver.FindElement(By.Id("multi-upload"));
// For multiple files, join paths with newlinestring[] files = { Path.GetFullPath("file1.pdf"), Path.GetFullPath("file2.pdf"), Path.GetFullPath("file3.pdf")};
// Send all paths separated by newlinefileInput.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 zoneWebElement dropZone = driver.findElement(By.id("drop-zone"));
// Many drop zones have a hidden input - find and use itWebElement 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 zonedrop_zone = driver.find_element(By.ID, "drop-zone")
# Many drop zones have a hidden input - find and use ithidden_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 zoneconst dropZone = await driver.findElement(By.id('drop-zone'));
// Many drop zones have a hidden input - find and use itconst 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 zoneIWebElement dropZone = driver.FindElement(By.Id("drop-zone"));
// Many drop zones have a hidden input - find and use itIWebElement 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 approachRemote 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 uploadsRemoteWebDriver remoteDriver = (RemoteWebDriver) driver;remoteDriver.setFileDetector(new LocalFileDetector());
// Now uploads work the same wayWebElement 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 uploadsdriver.file_detector = LocalFileDetector()
# Now uploads work the same wayfile_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 detectorvar remoteDriver = (RemoteWebDriver)driver;remoteDriver.FileDetector = new LocalFileDetector();
// Now uploads work the same wayIWebElement 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 filefileInput.sendKeys(filePath);
// Wait for upload progress to completeWebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
// Option 1: Wait for success messagewait.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 listwait.until(ExpectedConditions.textToBePresentInElementLocated( By.id("file-list"), "uploaded-file.pdf"));from selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as EC
# Upload the filefile_input.send_keys(file_path)
# Wait for upload progress to completewait = WebDriverWait(driver, 30)
# Option 1: Wait for success messagewait.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 listwait.until(EC.text_to_be_present_in_element( (By.ID, "file-list"), "uploaded-file.pdf"))const { until } = require('selenium-webdriver');
// Upload the fileawait fileInput.sendKeys(filePath);
// Wait for upload progress to complete// Option 1: Wait for success messageawait driver.wait( until.elementLocated(By.css('.upload-success')), 30000);
// Option 2: Wait for file name to appearawait 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 filefileInput.SendKeys(filePath);
// Wait for upload progress to completeWebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
// Option 1: Wait for success messagewait.Until(d => d.FindElement(By.CssSelector(".upload-success")).Displayed);
// Option 2: Wait for file name to appear in listwait.Until(d => d.FindElement(By.Id("file-list")).Text.Contains("uploaded-file.pdf"));Best Practices
| Practice | Description |
|---|---|
| Use absolute paths | Relative paths may not resolve correctly |
| Create test files | Include sample files in your test resources |
| Handle hidden inputs | Use JavaScript to make inputs visible if needed |
| Wait for completion | Don’t assume upload is instant |
| Clean up | Delete test uploads after test if possible |
| Set file detector | Required for remote/Grid uploads |
Common Issues
| Issue | Solution |
|---|---|
| Element not interactable | Make hidden input visible with JavaScript |
| File not found | Use absolute path, verify file exists |
| Remote upload fails | Set LocalFileDetector |
| Upload timeout | Increase wait time for large files |
Next Steps
- JavaScript Executor - Advanced DOM manipulation
- Waits - Wait strategies for async uploads
- Forms and Inputs - Complete form handling