Upload and Download functionality with Selenium RC
April 10th, 2009Recently, I had the challenge of writing some automation for a workflow which included uploading a file, and then downloading a file later in the workflow. The team with whom I am working had used some Selenium for their tests, and preferred to keep doing so, if possible, but their efforts prior to my arrival on the team to get the upload/download portions of the code working with Selenium had been unsuccessful.
The problem basically boils down to two points:
The JavaScript interpreters in most browsers have specific protections built in to prevent JavaScripts from filling in “file” fields, such that when they tried “type” “filefield” “myfile.txt”, nothing would happen in the browser.
When attempting to use the click command on the “browse” button of the field, moreover, causes a modal dialog which holds focus such that the click command does not return, because it is waiting for feedback from the browser, until the modal file picking dialog closes.
So, you can’t type into the file field, and you can’t click on it to open the file dialog, because even if you can type into it, using native key pressing, or another automation tool such as AutoIt or AutoHotKey, which can grab window focus, and send typing events, you’re still kind of hosed, because until your script returns from the click event, which it won’t because there’s this modal window stuck out there, blocking it. KeyDown and KeyUp don’t trigger any action in the control, good or bad.
So what to do? Well, there are solutions, even fairly easy ones, but they are probably going to involve at least a little platform and browser-specific kludges, which you can hopefully write into functions, and then never worry about again. In some browsers, I was able to use the focus(locator) command, and then do native system typing with KeyPressNative, or AutoIt, which allows me to grab the appropriate window first, and simply send the desired text. However, in some browsers, this will not work, as the field will bring up the dialog when you begin to type into the field. Below, you can find my solution.
System.out.println(”focusing on file field”);
selenium.focus(”uploadfile”);
if (T1.Browser.startsWith(”*ie”))
{
System.out.println(”Doing the ie tabbing”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyDownNative(java.awt.event.KeyEvent.VK_SHIFT + “”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyUpNative(java.awt.event.KeyEvent.VK_SHIFT + “”);
System.out.println(”Submitting file: ” + fname);
Process fileup = Runtime.getRuntime().exec(”C:\\autoit\\install\\AutoIt3.exe C:\\testfiles\\scripts\\submitFileName.au3 \”" + fname + “\”");
fileup.waitFor();
selenium.click(”ok”);
} else {
if (T1.Browser.startsWith(”*firefox”))
{
getSystemFocus(”PCMS”);
selenium.focus(”uploadfile”);
System.out.println(”Doing the firefox tabbing”);
selenium.setSpeed(”200″);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + “”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_SPACE + “”);
getSystemFocus(”PCMS”);
System.out.println(”Space Pressed”);
System.out.println(”Submitting file: ” + fname);
Process fileup = Runtime.getRuntime().exec(”C:\\autoit\\install\\AutoIt3.exe C:\\testfiles\\scripts\\submitFileNameFF.au3 \”" + fname + “\”");
fileup.waitFor();
selenium.focus(”ok”);
selenium.keyPressNative(java.awt.event.KeyEvent.VK_SPACE + “”);
System.out.println(”Dismissing the security warning”);
Process secwarning = Runtime.getRuntime().exec(”C:\\autoit\\install\\AutoIt3.exe C:\\testfiles\\scripts\\secwarning.au3″);
secwarning.waitFor();
System.out.println(”Dismissing the security warning”);
selenium.setSpeed(”1200″);
There are a couple of small problems with this solution as a general solution, but it does work for multiple browsers on Windows. Not the least problem is that this will fail when running on a non-local RC server. That can be gotten around by calling psexec or some similar command on the hostname of the rc server, but this works only in a Windows setup. For non-windows machines, a similar strategy could be done, and you could probably eliminate AutoIt and any outside tool by calling keyPressNative commands for each character of the file string, but you may run into difficulties with system focus of the window.
What would be ideal is a java tool which can grab window focus, and then type in the appropriate file string, given as parameters, but I wasn’t able to find or implement both of these requirements in sufficient time.