Selenium FindElement阻止文件上载完成

时间:2014-03-01 00:38:11

标签: javascript file-upload selenium jquery-file-upload

简短:

当我使用SendKeys(路径)触发文件上传到代理元素(由ExecuteScript放置)然后通过jquery.fileupload插件代理到我的隐藏时,文件上传很好,但是当我尝试发出{ {1}},它会阻塞,直到服务器响应。

The Long:

我正在使用2.4 C#网络驱动程序,默认的firefox驱动程序和jquery文件上传插件(蓝色imp)。

通过单击按钮打开“概述对话框”(具有我的

)开始流程
FindElement

在对话框组成后,我有

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

正常用法让用户单击标签,触发输入,然后触发并添加回调,检查大小/类型,如果确定,则更改为PROGRESS对话框,然后执行jquery('#fileUpload').fileupload(self.fileUploadOptions);

继续进行直到响应,此时最后一个对话框显示一些结果,可以用另一个按钮解除。

所以,简而言之:

  1. 打开一个对话框
  2. 将对话框中的模板设置为简介
  3. 选择文件
  4. 在对话框中更改模板以进行
  5. 启动ajax(或iframe)上传
  6. 在对话框中更改模板以完成
  7. Selenium无法访问fileUpload输入(隐藏),所以为了让Selenium触发文件上传,我最终不得不执行这样的脚本:

    1. 添加新的输入元素:

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

    2. 触发回调:

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

    3. 所以,现在在创建tmpId输入元素之后,我的selenium脚本会这样做:

      data.submit()

      此触发器添加回调,检查文件,将模板更改为“进度”,然后开始上传。 假设上传需要60秒,服务器将响应,然后模板将触发“完成”

      问题是虽然:

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

      立即返回,所以我打电话给

      tmpInput.SendKeys(path);
      

      这个BLOCKS直到文件上传完成(60秒)。即使进度条正在更新。

      然后返回成功。

      因为我想要验证这个进度模板,所以我真的想在上传过程中访问DOM。

      有什么想法吗?

2 个答案:

答案 0 :(得分:1)

表单是否在流程中的任何位置提交?我的意思是提交被触发到任何地方或刷新或点击elemnet或类似?问题是webdriver是一个阻塞API,当触发加载/刷新或类似时,webdriver将检查各种事情以检查页面是否已完成加载(即document.readyState =='complete')等。

无论如何,应该可以覆盖此策略,您可以尝试调查page load strategies

答案 1 :(得分:0)

如果你想等待ajax操作,可以使用类似这样的东西

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

如果页面中没有ajax活动,上面的代码将返回true,但我建议您使用等待

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

如果你想让你的等待时间为60,120秒等,则会在持续时间内等待,直到元素被解除阻塞

我认为这是最好的解决方案,如果你认为我误解了你的阙请告诉我