简写:
当我使用SendKeys(path)触发文件上传到代理元素(由ExecuteScript放置),然后通过jquery.fileupload插件代理我隐藏的文件时,文件上传正常,但是当我尝试发出FindElement,它将阻塞直到服务器响应为止.
The Long:
我正在使用2.4 C#Web驱动程序,默认的firefox驱动程序和jquery文件上传插件(蓝色imp).
该流程从单击一个按钮以打开概述对话框"开始,该对话框包含我的
<input id="fileUpload" type="file" name="files[]" accept="video/quicktime,video/x-ms-wmv"> <lablel for="fileUpload">Select a file</label>对话框组成后,我有
jquery('#fileUpload').fileupload(self.fileUploadOptions);通常的用法是用户单击标签,该标签触发输入,然后触发并添加回调,该回调检查大小/类型,如果确定,则更改为PROGRESS对话框,并执行data.submit(). /p>
进度一直持续到响应为止,这时,最后一个对话框显示了一些结果,可以使用另一个按钮将其取消.
所以,简而言之:
Selenium无法访问fileUpload输入(隐藏),因此要让Selenium触发文件上传,我最终不得不执行如下脚本:
添加新的输入元素:
jQuery('',{id:'tmpId',类型:'file',名称:'files []'}).appendTo('modalDivId')
触发回调:
$('#tmpId').bind('change',函数(e){ $('#fileUpload').fileupload('add',{ 文件:e.target.files || [{name:this.value}], fileInput:$(此) }); });
因此,现在在创建tmpId输入元素之后,我的硒脚本将执行以下操作:
var path="\path\to\files"; var tmpInput = WebDriver.FindElement(By.Id("tmpId)); tmpInput.SendKeys(path);这会触发添加回调,检查文件,将模板更改为进度"并开始上传. 假设上传需要60秒,服务器将响应,然后模板将触发完成"
问题在于,尽管:
tmpInput.SendKeys(path);立即"返回,所以我打电话
var a = WebDriver.FindElement(By.Id("tmpId"));并且此阻止直到文件上传完成(60秒).即使进度条正在更新.
然后返回成功.
因为我有要验证的进度模板,所以我真的很想在上传过程中访问DOM.
有什么想法吗?
解决方案如果要等待ajax操作,则可以使用类似这样的
var ajaxIsComplete = javaScriptExecutor != null && (bool)javaScriptExecutor.ExecuteScript("return jQuery.active == 0");如果页面中没有ajax活动,则上面的代码将返回true,但我建议您使用wait
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(time)); wait.Until(ElementIsClickable(locator);如果您希望提供60、120秒等的等待时间,它将在持续时间内一直等待,直到元素变为不受阻碍为止
如果您认为我误解了您的Que,我认为这是最好的解决方案,请让我知道
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:
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?
解决方案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
更多推荐
Selenium FindElement阻止,直到文件上传完成
发布评论