17
votes

Is there a way to interact with a File Upload box in webdriver? The form field where the path gets put in is read only so I can't write to that.

7

7 Answers

21
votes

You can do this without injecting JavaScript. You just need to get hold of the form field and type into it. Something like (using the Ruby API):

driver.find_element(:id, 'upload').send_keys('/foo/bar')
11
votes

You can set the value of your input field using JavaScript. Considering that the id of the field is fileName the following example will set the value of the input to the file C:\temp\file.txt:

String script = "document.getElementById('fileName').value='" + "C:\\\\temp\\\\file.txt" + "';";
((IJavaScriptExecutor)driver).ExecuteScript(script);

In this example, driver is your WebDriver instance.

Please note that you have to use four backslashes (\) for Windows-like paths because you are required to pass double back-slashes to the JavaScript so you have to escape both with two additional slashes. The other option is to use a forward slash (e.g. "C:/tmp/file.txt") and that should also work.

7
votes

For C#, SendKeys() works but you have to use \ in your file path instead of /

For example, the follow works :

string filePath = @"drive:\path\filename.filextension";
driver.FindElement(By.Id("fileInput")).SendKeys(filePath);

But the following doesn't work :

string filePath = "drive:/path/filename.filextension";
driver.FindElement(By.Id("fileInput")).SendKeys(filePath);
3
votes

The problem I found is the upload dialog hangs the webdriver until closed. That is, the element.click which invokes the upload dialog does not return until that upload dialog is closed. To be clear, upload dialog means an OS-native file selection.

Here is my solution (it's a bit complicated but *shrug* most workarounds for selenium webdriver problems must get complicated).

# presumes webdriver has loaded the web page of interest
element_input = webdriver.find_element_by_css_selector('input[id="uploadfile"]')
handle_dialog(element_input, "foobar.txt")

def handle_dialog(element_initiating_dialog, dialog_text_input):
    def _handle_dialog(_element_initiating_dialog):
        _element_initiating_dialog.click() # thread hangs here until upload dialog closes
    t = threading.Thread(target=_handle_dialog, args=[element_initiating_dialog] )
    t.start()
    time.sleep(1) # poor thread synchronization, but good enough

    upload_dialog = webdriver.switch_to_active_element()
    upload_dialog.send_keys(dialog_text_input)
    upload_dialog.send_keys(selenium.webdriver.common.keys.Keys.ENTER) # the ENTER key closes the upload dialog, other thread exits


Using python 2.7, webdriver 2.25.0, on Ubuntu 12, with firefox.

1
votes

I am in search of 3rd party libraries too,

Unless there is no any other Window Then this works for me :

in C# add reference for System.Windows.Forms

using System.Windows.Forms;

string url = "http://nervgh.github.io/pages/angular-file-upload/examples/image-preview/";
string path = @"C:\Users\File_Path";
IWebDriver d = new ChromeDriver();
d.Navigate().GoToUrl(url);
d.FindElement(By.XPath("//input[@type='file']")).Click();
hread.Sleep(5000);
System.Windows.Forms.SendKeys.SendWait(path);
System.Windows.Forms.SendKeys.SendWait(@"{Enter}");
0
votes

in my case i can upload file like solution that write hear but dialog window stuck the process, the driver cant reference to close this window, so i kill him manually:

 foreach (var p in Process.GetProcessesByName("chrome"))
        if (p.MainWindowTitle.ToLower().Contains("open"))
               p.Kill();
-1
votes

We can use following (ruby API)

@driver.find_element(:xpath, "html/body/div[1]/div[2]/div[1]/form/div[4]/div[7]/table/tbody/tr[1]/td[2]/input").send_keys "C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg"

This is helped me to upload image.