Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload a file in Selenium with no text box

I have been looking for a solution to uploading a file in Selenium 2.

The problem is that the web element that I'm trying to upload is usable in two ways: Drag and drop, or click on a button. There is no field entry box. Not that I haven't tried using sendKeys. I've tried it on the button, and all surrounding elements.

The second part to this problem is that I write on a Windows machine, but the automation occurs on a Linux machine. That means that AutoIt won't work. This is the HTML of the upload box.

<div class="up-target" id="up-drop-zone">
    <div class="up-drop-zone-pre hidden">
        <p>Please choose a folder to upload</p>
    </div>
    <div class="up-drop-zone-decor">
        <p>Drop one or more files here</p>
        <p>or</p>
        <button name="uploadFile" class="upload">Select Files</button>
        <input type="file" id="up-drop-zone-input" name="files[]" multiple="true">
    </div>
</div>

I am using Java, and open to other methods outside of Selenium (However, I do only have select maven repositories).

Thank You!

like image 772
Nathan Merrill Avatar asked Jan 29 '13 21:01

Nathan Merrill


Video Answer


2 Answers

Unfortunately, you can't do that as of now (January 2013, Selenium 2.29.1), because Selenium doesn't support <input type="file" multiple> elements.

There is a feature enhancement request for this made by the project developers themselves, it's just not yet implemented. You can star it there to move it upwards in the priority list.

Also, as far as I know, you can't really drag a file from desktop to a WebElement in a reliable way.

A workaround might be the use of AutoIT (Windows only) or the Robot class (will also work only on setups similar to yours) and type the path "blindly" into the dialog:

driver.findElement(By.id("up-drop-zone-input")).click();
Robot r = new Robot();
r.keyPress(KeyEvent.VK_C);        // C
r.keyRelease(KeyEvent.VK_C);
r.keyPress(KeyEvent.VK_COLON);    // : (colon)
r.keyRelease(KeyEvent.VK_COLON);
r.keyPress(KeyEvent.VK_SLASH);    // / (slash)
r.keyRelease(KeyEvent.VK_SLASH);
// etc. for the whole file path

r.keyPress(KeyEvent.VK_ENTER);    // confirm by pressing Enter in the end
r.keyRelease(KeyEvent.VK_ENTER);

It sucks, but it should work. Note that you might need these: How can I make Robot type a `:`? and Convert String to KeyEvents (plus there is the new and shiny KeyEvent#getExtendedKeyCodeForChar() which does similar work, but is available only from JDK7).

like image 191
Petr Janeček Avatar answered Oct 04 '22 12:10

Petr Janeček


I found the only way I could get it working was to use AutoIt (thanks to answers by LittlePanda and user3903359).

I improved on the script as I found performing any other actions while the test was running could stop it working. The trick was to find the window then make it active before entering the text.

The timeout is to prevent multiple AutoIt scripts hanging around in the background which means when you stop the test and try to do your own work they then kick off and try to start typing!

Note that the window is named differently in different browsers (e.g. "Open" in Chrome).

$windowHandle = WinWait("Choose File to Upload", "", 3) ; 3 second timeout - NB the window name will be different in different browsers!

If $windowHandle == 0 Then
   MsgBox(0, "", "Upload popup not found")
Else
   ;MsgBox(0, "", "Upload popup found: " & $windowHandle)
   WinActivate($windowHandle)
   Send("C:\\path\to\myfile.txt")
   Send("{ENTER}")
EndIf

Running the AutoIt script from Java is I assume as per all the other answers:

Runtime.getRuntime().exec("MyAutoItScript.exe");

Running the AutoIt script from C#:

var process = Process.Start(@"C:\\path\to\myAutoItScript.exe");
process.WaitForExit();
Thread.Sleep(200); // IE fix for Modal dialog present exception
like image 41
SharpC Avatar answered Oct 04 '22 13:10

SharpC