问题
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:
- open a dialog
- set template in dialog to intro
- select a file
- change template in dialog to progress
- kick off the ajax (or iframe) upload
- 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:
Add a new input element:
jQuery('', {id: 'tmpId', type: 'file', name:'files[]'}).appendTo('modalDivId')
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?
回答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.
回答2:
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
来源:https://stackoverflow.com/questions/22108482/selenium-findelement-blocks-until-file-upload-is-complete