21

I saw that lots of people have Problems uploading a file in a test Environment with Selenium WebDriver. I use the selenium WebDriver and java, and had the same problem. I finally have found a solution, so i will post it here hoping that it helps someone else.

When i need to upload a file in a test, i click with Webdriver in the button and wait for the window "Open" to pop. And then i copy the path to the file in the clipboard and then paste it in the "open" window and click "Enter". This is working because when the window "open" pops up, the focus is always in the "open" button.

You will need these classes and method:

import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;


public static void setClipboardData(String string) {
   StringSelection stringSelection = new StringSelection(string);
   Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}

And that is what i do, just after opening the "open" window:

setClipboardData("C:\\path to file\\example.jpg");
//native key strokes for CTRL, V and ENTER keys
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);

And that´s it. It is working for me, i hope it works for some of you.

Ripon Al Wasim
  • 36,924
  • 42
  • 155
  • 176
Alex
  • 253
  • 1
  • 3
  • 12

4 Answers4

29

Actually, there is an in-built technique for this, too. It should work in all browsers and operating systems.

Selenium 2 (WebDriver) Java example:

// assuming driver is a healthy WebDriver instance
WebElement fileInput = driver.findElement(By.xpath("//input[@type='file']"));
fileInput.sendKeys("C:/path/to/file.jpg");

The idea is to directly send the absolute path to the file to an element which you would usually click at to get the modal window - that is <input type='file' /> element.

Petr Janeček
  • 37,768
  • 12
  • 121
  • 145
  • 1
    Thanks, the problem is that "sendKeys" is not working for me cause i upload the file through an ajax call before i send the form. But maybe it helps others. :) – Alex May 24 '12 at 08:14
  • 3
    But. It just fills in the path, any ajax calls __should be resolved__ after the `` loses focus (which means that after the `sendkeys()` call, you need to click outside the `` or start filling some other one for `onchange` scripts to trigger). – Petr Janeček May 24 '12 at 08:19
  • Yes, you are right, but the fileupload that i use, uses a fake input field that only shows the name of the file uploaded. The ajax is not triggered when this field loses the focus. It is not really an easy process and can´t be tested like that, tho i would much prefer it was that way. – Alex May 24 '12 at 08:33
  • 1
    Fun. I'd really be interested to see the internals of that. Hopefully I won't :). – Petr Janeček May 24 '12 at 08:35
  • Id like to add, you may want to use `C:\\path\\to\\file.jpg` instead of `C:/path/to/file.jpg`. – obesechicken13 Oct 22 '12 at 19:38
  • Yeah I could only get it to work using `C:\\path\\to\\file.jpg` or `file:/C:/path/to/file.jpg`, the `file:/` was key for me. – smithleej Jun 11 '14 at 10:51
  • thanks much! That worked like a charm for me . But the only thing I had to do is to find 'input' element on a sublayout withing which I were working - http://gyazo.com/8e4ad312d13d57a0d371087882ec0ce0 . It was not the same with the element calling modal attach file popup. And also it's worth mentioning that I've used CSS selector div#addDetailImageModal input[type="file"] and absolute path represented in the following form: "C:\\Selenium\\emenu_food.png" . + upvote from me ;-) – eugene.polschikov Mar 17 '15 at 11:00
3

Thanks Alex,

Java Robot API helped me for uploading file. I was fedup with File Upload using WebDriver. Following is the code I used (Small modification to yours):

Robot robot = new Robot();
robot.delay(1000);

robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
robot.delay(1000);
Ripon Al Wasim
  • 36,924
  • 42
  • 155
  • 176
0

Thanks Alex! I needed this since I could not get the sendKeys function to work when used via Play framework 2.1 (fluentlenium wrapper). I am testing over Firefox [17.0.7] for Mac and had to make a few mods to get it working. Below is an approximation of the final snippet I used.

    val file = new File(PATH_TO_IPA)
    val stringSelection: StringSelection = new StringSelection(file.getAbsolutePath)
    Toolkit.getDefaultToolkit.getSystemClipboard().setContents(stringSelection, null)
    val robot: Robot = new Robot()
    // Cmd + Tab is needed since it launches a Java app and the browser looses focus
    robot.keyPress(KeyEvent.VK_META)
    robot.keyPress(KeyEvent.VK_TAB)
    robot.keyRelease(KeyEvent.VK_META)
    robot.keyRelease(KeyEvent.VK_TAB)
    robot.delay(500)
    robot.keyPress(KeyEvent.VK_META)
    robot.keyPress(KeyEvent.VK_SHIFT)
    robot.keyPress(KeyEvent.VK_G)
    robot.keyRelease(KeyEvent.VK_META)
    robot.keyRelease(KeyEvent.VK_SHIFT)
    robot.keyRelease(KeyEvent.VK_G)
    robot.keyPress(KeyEvent.VK_META)
    robot.keyPress(KeyEvent.VK_V)
    robot.keyRelease(KeyEvent.VK_META)
    robot.keyRelease(KeyEvent.VK_V)
    robot.keyPress(KeyEvent.VK_ENTER)
    robot.keyRelease(KeyEvent.VK_ENTER)
    robot.delay(500)
    robot.keyPress(KeyEvent.VK_ENTER)
    robot.keyRelease(KeyEvent.VK_ENTER)
legrandviking
  • 2,348
  • 1
  • 22
  • 29
  • Happy to hear it. ah! and thanks for sharing your solution :) – Alex Jul 30 '13 at 08:50
  • Hey Mashhood could you help me with converting your version of the keypress file upload on mac for use with the python bindings of selenium: http://selenium.googlecode.com/svn/trunk/docs/api/py/webdriver/selenium.webdriver.common.keys.html. I too couldn't get sendKeys to work properly for my use case. – jcuwaz Aug 04 '14 at 12:10
0

The switching of application on Mac is much better to do with AppleScript. AppleScript is integrated to system, so it will be always functional and does not depend on order of apps on Cmd+Tab. Your test/app will be less fragile. https://developer.apple.com/library/content/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html

You need only detect you are on mac and has name of the application.

Runtime runtime = Runtime.getRuntime();
            String[] args = { "osascript", "-e", "tell app \"Chrome\" to activate" };
            Process process = runtime.exec(args);
Radek
  • 165
  • 10