5

Selenium-2.37.0

Firefox 24.0 (although have also tried on Chrome)

Mac OS X Mountain Lion 10.8.5

Solutions involving Windows, Windows-specific automation tools/libraries or O/S other than Mac OS X are not acceptable answers

Firstly may I remark that very similar questions have be asked often here on Stackoverflow, I have examined every offered answer, and none of them work for the CuteWebUI_Uploader_Resource AJAX file uploader, as I will illustrate in detail below.

I have an Enterprise Java web application with data and files and wish to automate mapping and uploading a selected subset of the data and files from that web application against (into) a separate ASP.NET web application, which uses the CuteWebUI toolkit and the CuteWebUI_Uploader_Resource from CuteSoft.

At the time of writing the http://cutesoft.net server has been down for some days; Googling gives some CuteSoft forum hits that may help with this problem, but I currently can't access them.

Like many file uploaders, the CuteWebUI AJAX file uploader has a Browse button and an Upload button.

I want to be able to upload directly into the CuteWebUI AJAX file uploader without using that Browse button (and without having to play any tricks using the Browse dialog on Mac OS X, because the files I wish to upload will not be available to a browser on a local filesystem, but instead are stored on a server accessible to the Java web application via Java, although for testing I can have them on a local filesystem, as shown below).

I appreciate that this problem has been answered many times for other file uploaders (see exhaustive list at end of this posting), and the process usually described as a solution for most file uploaders is roughly:

  • Identify the INPUT field for the file upload path (sometimes hidden) populated by the Browse button. Sometimes one needs to unhide this using a JavascriptExecutor and ensure it is a text field, then use sendKeys to populate it.

  • Identify the matching SUBMIT Upload button and click() it.

This does not work for the CuteWebUI AJAX file uploader.

The system I am targeting does indeed have an INPUT element that by name would suggest it is used to store the file upload path, but in fact when I try it by hand (and examine it using Firebug and Selenium IDE) its value is not populated at all, and instead a completely new temporary table of uploadable files appears.

The following HTML shows the situation before any file browse or upload has been attempted. I have omitted some style markup and some irrelevant values:

<script src="/CuteWebUI_Uploader_Resource.axd?type=script&amp;_ver=" type="text/javascript"></script>
<input 
type="hidden" 
autocomplete="off" 
name="fileuploader_433"
id="fileuploader_433"
isuploaderfield="1" 
value="">
<button>Browse</button>
<span style="display: none;"></span>
<button style="display: none;">Cancel upload</button>
<img 
showprogressbar="1" 
canceluploadmsg="Cancel upload" 
resourcehandler="/CuteWebUI_Uploader_Resource.axd" 
uploadtype="Auto" 
cancelallmsg="Cancel all Uploads" 
uploadurl="/Handlers/UploadHandler.ashx" 
insertext="Upload a file" 
uploadingmsg="Uploading.." filetoolargemsg=".." maxfileslimitmsg=".." 
inserttext="Browse"
numfilesshowcancelall="2147483647" 
barstyle="Continuous" 
showprogressinfo="0" 
multiplefilesupload="0" 
windowsdialoglimitmsg=".." 
manualstartupload="1" 
extensions=""
contextvalue=".." 
onerror="this.onload()" 
onload="this.style.display=&quot;none&quot; ; 
if(!window.CuteWebUI_AjaxUploader_Initialize){
var xh=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHttp');
xh.open('GET','/CuteWebUI_Uploader_Resource.axd?type=script&amp;amp;_ver=',false);xh.send('');eval(xh.responseText)}CuteWebUI_AjaxUploader_Initialize(this.id);" 
src="/CuteWebUI_Uploader_Resource.axd?type=file&amp;file=continuous.gif" 
pageupload="1" 
namespace="CuteWebUI" 
uniqueid="fileuploader_433" 
id="fileuploader_433_Loader_unique" 
style="display: none;">
<button 
onclick="return submitbutton_click('433')" 
class="submitbutton" 
name="SubmitButton" 
id="SubmitButton">Upload</button>

The following Selenium in Java correctly unhides and populates the fileuploader_433 INPUT field, but on executing the click() on the submit I still get a popup window asserting I have to use the browse button with the message "Please use browse for file upload":

    String name_fileuploader = "fileuploader_434";
    JavascriptExecutor jse = (JavascriptExecutor) driver;
    jse.executeScript("document.getElementsByName('" + name_fileuploader + "')[0].setAttribute('type', 'text');");
    WebElement element_uploader = driver.findElement(By.xpath("//input[@name='" + name_fileuploader + "']"));
    element_uploader.clear();
    String filepath="/path/to/file.pdf";
    element_uploader.sendKeys(filepath);        
    driver.findElement(By.xpath("(//button[@id='SubmitButton'])[2]")).click();

Firebug confirms that even if you do it by hand, that INPUT field is never used ! Instead, a new file queue table appears:

<script src="/CuteWebUI_Uploader_Resource.axd?type=script&amp;_ver=" type="text/javascript"></script>
<input type="hidden" autocomplete="off" name="fileuploader_434" id="fileuploader_434" isuploaderfield="1" value="">
<button>Browse</button>
<table .. class="AjaxUploaderQueueTable">
<tbody>
<tr class="AjaxUploaderQueueTableRow">
<td>
<img src="/CuteWebUI_Uploader_Resource.axd?type=file&amp;file=circle.png&amp;_ver=null" title="">
</td>
<td>file.pdf</td><td>
<img src="/CuteWebUI_Uploader_Resource.axd?type=file&amp;file=stop.png&amp;_ver=null" title="Remove" style="cursor: pointer;">
</td>
</tr>
</tbody>
</table>
<span style="display: none;"></span>
<button style="display: none;">Cancel upload</button>
<img showprogressbar="1" canceluploadmsg="Cancel upload" ..   
resourcehandler="/CuteWebUI_Uploader_Resource.axd" uploadtype="Auto"  
cancelallmsg="Cancel all Uploads" uploadurl="/Handlers/UploadHandler.ashx" [snip]
onerror="this.onload()" onload="this.style.display=&quot;none&quot; ; 
if(!window.CuteWebUI_AjaxUploader_Initialize){var xh=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHttp');xh.open('GET','/CuteWebUI_Uploader_Resource.axd?type=script&amp;amp;_ver=',false);xh.send('');eval(xh.responseText)}CuteWebUI_AjaxUploader_Initialize(this.id);" 
src="/CuteWebUI_Uploader_Resource.axd?type=file&amp;file=continuous.gif" 
pageupload="1" namespace="CuteWebUI" uniqueid="fileuploader_434"
id="fileuploader_434_Loader_unique" style="display: none;">

<button onclick="return submitbutton_click('434')" class="submitbutton" name="SubmitButton" id="SubmitButton">Upload</button>

Please note that:

  • the hidden INPUT element is never populated with a file path value !

  • instead, the string file.pdf without the full file path appears in a new TABLE with class="AjaxUploaderQueueTable" below the Browse button.

That inserted AjaxUploaderQueueTable is clearly only cosmetic; it seems that the filepath selected during the Browse operation is stored server-side. I have searched for the full filepath after selecting with the Browse button using Firebug and it is not present in the page.

I am open - for the sake of testing only - to suggestions that instead involve tricks manipulating the Browse dialog in Mac OS X, but that approach does not meet my eventual requirements, because I can't rely on that approach for the final task of uploading many files from an Enterprise Java web application into the targeted ASP.NET web application. I must side-step the Browse dialog completely.

Background research

All of the following have related questions and answers but none of these solve the problem for the CuteWebUI AJAX file uploader:

How to type some text in hidden field in Selenium WebDriver using Java

How to handle windows file upload using Selenium WebDriver?

How to force Selenium WebDriver to click on element which is not currently visible?

how does selenium webdriver upload files to the browser?

How to deal with file uploading in test automation using selenium or webdriver

https://stackoverflow.com/questions/18886970/selenium-webdriver-upload-file-sendkeys-dont-work

File Upload using Selenium WebDriver and Java

How to handle with uploading files from modal window Selenium WebDriver Java

Handling a popup window using selenium

http://selenium.10932.n7.nabble.com/Handling-browser-pop-up-dialog-to-upload-a-file-td29153.html

This probably relevant forum link from CuteSoft is down:

Jul 24, 2012 - Hi,I'm doing automated testing for my web system using selenium webdriver, the problem is that I can't interact with ajaxuploader component

And a WebDriver forum posting with the INPUT unhide trick: https://groups.google.com/forum/#!topic/webdriver/JAXC_qEbQvI

Community
  • 1
  • 1
  • I'm having the exact same issue - did you ever figure out a solution? (The forum post from CuteSoft is now accessible but does not have any answers either) – Stuart Dec 04 '13 at 16:47

1 Answers1

4

I've found a solution for this; it comes with some caveats but it works for my situation. Hopefully it will help you too.

The biggest caveat is that I only know that it works with the current version of AjaxUploader as downloaded today. I'd been using an older version that worked differently; I can't specify a version number since CuteSoft seem pathologically inclined to make the version numbers of AjaxUploader almost impossible to figure out. I can't find a version number for the current version OR the older one that I was using.

The other caveat is that it relies on there only being one AjaxUploader control on the page at a time. It appears that AjaxUploader DOES create an <input type='file'> element, but it's left dangling in a div at the top of the <body> tag, without any id or name attribute or anything else to link it to a particular uploader. I'm not sure what AjaxUploader does when more than one of it are present: maybe it creates multiple file inputs and tracks which is which by javascript; maybe it shares one. For my situation I didn't need to solve that part so I didn't try it.

Anyway, the trick is to find the file input as follows:

webDriver.findElements(By.cssSelector("body > div > input[type='file']")).get(0).sendKeys(fileName);

Note that the selector here has nothing to do with the ID or any other characteristics of the particular upload button you're using. It's just "the first file input inside a div directly inside the body tag". That's where AjaxUploader inserts its file input.

There appears to be no need to interact with any of the rest of the UI, including the Browse button: sendKeysing the filename to the right file input causes the upload to begin immediately. (This is an edit; I originally thought that clicking the button was necessary too but it doesn't seem to be)

Note that to make sure the timing of your test works correctly, you probably want to follow this click up with a wait operation that waits until the file has finished uploading (eg by waiting for the HTML that the AjaxUploader inserts after uploading is complete) before proceeding to whatever you want to do next.

Stuart
  • 1,868
  • 2
  • 14
  • 14
  • Thanks, am testing, Webel – Webel IT Australia - upvoter Dec 08 '13 at 01:20
  • Using the input[type="submit"] element(s) you identified under the body in a top-level div I got it working also for the case with multiple file uploaders, but there was one catch and one difference. For some reason the fileName holder for the 2nd file uploader was the 1st input under that top-level div, so I used an Xpath "(/html/body/div/input)[1]" (not "(/html/body/div/input)[2]" as one might expect). Also, I did not use the Browse buttons, they just opened a file dialog, after the sendKeys(fileName) I just performed a click on the 2nd Upload button with xpath "(//*[@id='SubmitButton'])[2]" – Webel IT Australia - upvoter Dec 09 '13 at 02:05
  • Also, on performing a click() on the Upload button the status field in the file table just said 'processing' (but I could tell it had uploaded fine by reloading the page in either the WebDriver window or in another browser instance window). After reloading the web browser window the file upload table showed the file and a Delete link. There is also a Save button in the web application I am targetting, but it did not seem to make any difference to the file upload (but it did for other form data of course). I was able to repeat this process to upload multiple files to one of the file uploaders. – Webel IT Australia - upvoter Dec 09 '13 at 02:09
  • I'd actually just come back here to update because I discovered the "no need to click on the Browse button" thing myself - in my case it was mostly just "doing nothing" to do that but occasionally caused a race condition and made my test fail. I'll edit the answer accordingly. Glad it helped! – Stuart Dec 11 '13 at 17:57