How to Upload Files using Selenium

Yosuva ArulanthuC#, Java, Python, Ruby, Selenium, Test Automation, TestingLeave a Comment

Uploading a file is a common piece of functionality found on the web. But when trying to automate it you get prompted with a dialogue box that is just out of reach for Selenium.

In these cases, people often look to a third-party tool to manipulate this window (e.g., AutoIt). While this can help solve your short-term need, it sets you up for failure later by chaining you to a specific platform (e.g., AutoIt only works on Windows), effectively limiting your ability to test this functionality on different browsers & operating system combinations.

A workaround for this problem is to side-step the system dialogue box entirely. We can do this by using Selenium to insert the full path of the file we want to upload (as text) into the form and then submit the form.

Let’s step through an example.

Sample Code

NOTE: We are using a file upload example found on the-internet.

Java

// filename: Upload.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
import java.io.File;
public class Upload {
    WebDriver driver;

    @Before
    public void setUp() throws Exception {
        driver = new FirefoxDriver();
    }

    @Test
    public void uploadFile() throws Exception {
        String filename = "some-file.txt";
        File file = new File(filename);
        String path = file.getAbsolutePath();
        driver.get("http://the-internet.herokuapp.com/upload");
        driver.findElement(By.id("file-upload")).sendKeys(path);
        driver.findElement(By.id("file-submit")).click();
        String text = driver.findElement(By.id("uploaded-files")).getText();
        assertThat(text, is(equalTo(filename)));
    }

    @After
    public void tearDown() throws Exception {
        driver.quit();
    }   

}



Python

# filename: upload.py

import os
import unittest
from selenium import webdriver
class Upload(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()

    def tearDown(self):
        self.driver.quit()
    def test_example_1(self):
        driver = self.driver
        filename = 'some-file.txt'
        file = os.path.join(os.getcwd(), filename)
        driver.get('http://the-internet.herokuapp.com/upload')
        driver.find_element_by_id('file-upload').send_keys(file)
        driver.find_element_by_id('file-submit').click()

        uploaded_file = driver.find_element_by_id('uploaded-files').text
        assert uploaded_file == filename, "uploaded file should be %s" % filename

if __name__ == "__main__":
    unittest.main()

Ruby

# filename: upload.rb

require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers

def setup
  @driver = Selenium::WebDriver.for :firefox
end

def teardown
  @driver.quit
end

def run
  setup
  yield
  teardown
end

run do
  filename = 'some-file.txt'
  file = File.join(Dir.pwd, filename)

  @driver.get 'http://the-internet.herokuapp.com/upload'
  @driver.find_element(id: 'file-upload').send_keys file
  @driver.find_element(id: 'file-submit').click

  uploaded_file = @driver.find_element(id: 'uploaded-files').text
  expect(uploaded_file).to eql filename
end

C#

// filename: FileUpload.cs
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
public class FileUpload
{
    IWebDriver Driver;

    [SetUp]
    public void SetUp()
    {
        Driver = new FirefoxDriver();
    }

    [TearDown]
    public void TearDown()
    {
        Driver.Quit();
    }
// ...
    [Test]
    public void UploadFileFromDisk()
    {
        string File = "SomeFile.txt";
        string FilePath = @"C:\Temp\" + File;

        Driver.Navigate().GoToUrl("http://the-internet.herokuapp.com/upload");
        Driver.FindElement(By.Id("file-upload")).SendKeys(FilePath);
        Driver.FindElement(By.Id("file-submit")).Click();

        IWebElement FileUploaded = Driver.FindElement(By.Id("uploaded-files"));
        Assert.IsTrue(FileUploaded.Text == File, "The File Did Not Upload Correctly");
    }
}

Next, we visit the page with the upload form, input the string value of path (e.g., the full path to the file plus the filename with it’s extension), and submit the form. After the file is uploaded to the page it will display the filename it just processed. We use this text to perform our assertion (making sure the uploaded file is what we expect).

When we save this file and run it here is what will happen:

  • Open the browser
  • Visit the upload form page
  • Inject the file path into the form and submit it
  • Page displays the uploaded filename
  • Grab the text from the page and assert it’s what we expect
  • Close the browser

This approach will work across all browsers. But if you want to use it with a remote instance (e.g., a Selenium Grid or Sauce Labs), then you’ll want to have a look at FileDetector.

Leave a Reply

Your email address will not be published.