2

The Short:

When I trigger a file upload using SendKeys(path) to a proxy element (placed on by ExecuteScript) that then proxies to my hidden through the jquery.fileupload plugin, the file uploads fine, but when I try and issue a FindElement, it blocks until the server responds.

The Long:

I am using the 2.4 C# web driver, default firefox driver, and jquery file upload plugin (blue imp).

The flow begins by clicking a button to open an 'overview dialog box', which has my

<input id="fileUpload" type="file" name="files[]" accept="video/quicktime,video/x-ms-wmv">
<lablel for="fileUpload">Select a file</label>

After composition of the dialog box, I have

jquery('#fileUpload').fileupload(self.fileUploadOptions);

Normal usage has the user click the label, which triggers the input, which then triggers and add callback, which checks size/types, and if OK, then changes to a PROGRESS dialog box, and does a data.submit().

Progress continues until the response, at which time a final dialog box shows some results and can be dismissed with another button.

So, in brief:

  1. open a dialog
  2. set template in dialog to intro
  3. select a file
  4. change template in dialog to progress
  5. kick off the ajax (or iframe) upload
  6. change template in dialog to finish

Selenium couldn't access the fileUpload input (hidden), so to get Selenium to trigger the file upload, I ended up having to execute some script like this:

  1. Add a new input element:

    jQuery('', {id: 'tmpId', type: 'file', name:'files[]'}).appendTo('modalDivId')

  2. Trigger a callback:

    $('#tmpId').bind('change', function (e) { $('#fileUpload').fileupload('add', { files: e.target.files || [{name: this.value}], fileInput: $(this) }); });

So, now after creating the tmpId input element, my selenium script does this:

var path="\path\to\files";
var tmpInput = WebDriver.FindElement(By.Id("tmpId));
tmpInput.SendKeys(path);

This triggers add callback, checks the file, changes to the template to 'progress', and starts the upload. Assuming the upload takes 60 seconds, the server will respond and then the template will trigger to 'finish'

The problem is that although:

tmpInput.SendKeys(path);

returns 'immediately', so I call

var a = WebDriver.FindElement(By.Id("tmpId"));

And this BLOCKS until the file upload is complete (60 seconds). Even though the progress bar is updating.

And then returns success.

Because I have this progress template I want to validate, I would really like to access the DOM during the upload.

Any thoughts?

2 Answers 2

1

Is the form being submitted anywhere in the process? I mean is the submit being triggered anywhere or refresh or click on elemnet or similar? The thing is that webdriver is a blocking API and when loading/refreshing or similar is being triggered, the webdriver will check for various things to check if the page is finished loading (ie document.readyState == 'complete') etc.

Anyway, it should be possible to override this strategy, you can try to investigate page load strategies.

Sign up to request clarification or add additional context in comments.

3 Comments

The form is being submitted through the jquery plugin (data.submit()) in the add callback. So, are you saying that the webdriver I created is probably blocking during the ajax post (waiting for it to 'complete')? And it sounds like I can't override this strategy on a per call basis? I imagine if I change the strategy, it will mess up the rest of my tests. I wonder if I can use multiple drivers. I will look into this and get back to mark the answer.
I really don't know much about using the page load strategies, they were introduced to FFDriver as of v2.40 (the latest, released a week ago). One thing you could also try is to set the pageLoadTimeout and use explicit waits for making sure the page is loaded.
"And it sounds like I can't override this strategy on a per call basis?" - I am pretty sure that this is a per driver thing.
1

If you want to wait for the ajax operation you can use something like this

            var ajaxIsComplete = javaScriptExecutor != null && (bool)javaScriptExecutor.ExecuteScript("return jQuery.active == 0");

The above code will return true if there is no ajax activity in the page but i suggest you use the wait

        var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(time));
        wait.Until(ElementIsClickable(locator);

If you want you give the wait time like 60, 120 seconds etc .it will wait during the duration until element becomes unblocked

I think this the best solution if you think i misunderstood your Que please let me know

2 Comments

You missed the question. "I would really like to access the DOM during the upload. Any thoughts?"
you want to validate the progress bar correct ,do you have any block ui being placed over the progress bar

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.