Uploading with Selenium



With Selenium WebDriver it's possible to test file uploads. In your test, you indicate which file you want to upload, WebDriver then sends the file from your computer, base64 encoded, to our Selenium grid.


See the Ruby and Java examples below on how to do this.


Below are 2 examples: 1. uploading a file before the test starts, or 2. uploading a file during a test.

1. Upload a file before your test starts



With TestingBot you can specify a URL in your desired capabilities which links to the file you want to be present on our test VMs.
TestingBot will then first download the URL and save it on the test VM so your test can use the file.


You specify the download URL as "upload" and use "uploadFilePath" in your desired capabilities to indicate where TestingBot needs to put the downloaded file.


require 'rubygems'
require "test/unit"
require 'selenium-webdriver'
class UploadTest < Test::Unit::TestCase
   def setup
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps.version = "39"
      caps.platform = :XP
      caps[:name] = "Test File Upload"
      caps[:upload] = "http://path.to.my.file.com/file.ext"
      caps[:uploadFilepath] = "C:\\test\\file.ext" # use C:\test\filename.ext on Windows and /tmp/filename.ext on Linux/OSX
      @driver = Selenium::WebDriver.for(
        :remote,
        :url => "https://key:secret@hub.testingbot.com/wd/hub",
        :desired_capabilities => caps)
   end

   def test_upload
      @driver.navigate.to "http://sl-test.herokuapp.com/guinea_pig/file_upload"
      element = @driver.find_element(:id, 'myfile')
      element.send_keys   "C:\\test\\file.ext" # use C:\test on Windows and /tmp on Linux/OSX
      @driver.find_element(:id, "submit").click
      @driver.find_element(:tag_name, "img")
      assert "mypicture.jpg (image/jpeg)" == @driver.find_element(:tag_name, "p").text
  end

  def teardown
      @driver.quit
  end

end


2. Upload a file during your test


Java Example

With Java, we make use of LocalFileDetector which sends the local file to the browser.


In the example below, we'll upload an image "mypicture.jpg", then check if the file was uploaded successfully.

import junit.framework.*;

import org.openqa.selenium.*;
import org.openqa.selenium.remote.*;

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;

import java.net.URL;

public class UploadTest extends TestCase {

  public static void testUpload() {
    String apiKey = "SIGN_UP_FREE";
    String apiSecret = "SIGN_UP_FREE";

    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("browserName", "IE");
    caps.setCapability("version", "9");
    caps.setCapability("name", "Test File Upload");
    caps.setCapability("platform", "WINDOWS");

    try {
      RemoteWebDriver driver = new RemoteWebDriver(new URL("https://" + apiKey + ":" + apiSecret + "@hub.testingbot.com/wd/hub"), caps);
      driver.setFileDetector(new LocalFileDetector());

      driver.get("http://sl-test.herokuapp.com/guinea_pig/file_upload");
      WebElement upload = driver.findElement(By.id("myfile"));
      upload.sendKeys("~/mypicture.jpg");
      driver.findElement(By.id("submit")).click();
      driver.findElement(By.tagName("img"));
      Assert.assertEquals("mypicture.jpg (image/jpeg)", driver.findElement(By.tagName("p")).getText());
      driver.quit();
    }
    catch (Exception ex) {
        System.out.println(ex.getMessage());
    }
  }
}

The important parts of this test are: use LocalFileDetector and "sendKeys" the filename you'd like to upload.


Ruby Example


require 'rubygems'
require "test/unit"
require 'selenium-webdriver'
class UploadTest < Test::Unit::TestCase
 def setup
    caps = Selenium::WebDriver::Remote::Capabilities.firefox
    caps.version = "39"
    caps.platform = :XP
    caps[:name] = "Test File Upload"
    @driver = Selenium::WebDriver.for(
      :remote,
      :url => "https://key:secret@hub.testingbot.com/wd/hub",
      :desired_capabilities => caps)
    @driver.file_detector = lambda do |args|
       # args => ["/path/to/file"]
       str = args.first.to_s
       str if File.exist?(str)
    end
 end

 def test_upload
    @driver.navigate.to "http://sl-test.herokuapp.com/guinea_pig/file_upload"
    element = @driver.find_element(:id, 'myfile')
    element.send_keys   "~/mypicture.jpg"
    @driver.find_element(:id, "submit").click
    @driver.find_element(:tag_name, "img")
    assert "mypicture.jpg (image/jpeg)" == @driver.find_element(:tag_name, "p").text
end

def teardown
    @driver.quit
end

end

The important parts of this test are: use file_detector and "send_keys" the filename you'd like to upload.