Selenium FindElement 阻塞,直到文件上传完成
Posted
技术标签:
【中文标题】Selenium FindElement 阻塞,直到文件上传完成【英文标题】:Selenium FindElement blocks until file upload is complete 【发布时间】:2014-04-02 05:47:46 【问题描述】:短片:
当我使用 SendKeys(path) 触发文件上传到代理元素(由 ExecuteScript 放置)然后通过 jquery.fileupload 插件代理到我的隐藏文件时,文件上传正常,但是当我尝试发出 @ 987654321@,它会阻塞直到服务器响应。
长篇:
我正在使用 2.4 C# web 驱动程序、默认 firefox 驱动程序和 jquery 文件上传插件(蓝色小鬼)。
流程从单击按钮打开“概览对话框”开始,其中包含我的
<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()
。
进度一直持续到响应,此时最终对话框会显示一些结果,并且可以使用另一个按钮将其关闭。
所以,简而言之:
-
打开一个对话框
将对话框中的模板设置为简介
选择一个文件
将对话框中的模板更改为进度
开始 ajax(或 iframe)上传
在对话框中更改模板以完成
Selenium 无法访问 fileUpload 输入(隐藏),所以为了让 Selenium 触发文件上传,我最终不得不执行一些这样的脚本:
添加一个新的输入元素:
jQuery('', id: 'tmpId', type: 'file', name:'files[]').appendTo('modalDivId')
触发回调:
$('#tmpId').bind('change', function (e) $('#fileUpload').fileupload('add', 文件:e.target.files || [名称:this.value], 文件输入:$(this) ); );
所以,现在在创建 tmpId 输入元素之后,我的 selenium 脚本会这样做:
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。
有什么想法吗?
【问题讨论】:
【参考方案1】:表单是否在流程中的任何地方提交?我的意思是提交是在任何地方触发还是刷新或单击 elemnet 或类似的?问题是 webdriver 是一个阻塞 API,当加载/刷新或类似的被触发时,webdriver 将检查各种内容以检查页面是否完成加载(即 document.readyState == 'complete')等。
无论如何,应该可以覆盖这个策略,你可以尝试调查page load strategies。
【讨论】:
表单正在通过 add 回调中的 jquery 插件 (data.submit()) 提交。那么,您是说我创建的 webdriver 在 ajax 发布期间可能被阻塞(等待它“完成”)?听起来我不能在每次通话的基础上覆盖这个策略?我想如果我改变策略,它会弄乱我其余的测试。我想知道我是否可以使用多个驱动程序。我会调查一下,然后回来标记答案。 我真的不太了解页面加载策略的使用,它们是在 FFDriver v2.40(最新,一周前发布)时引入的。您还可以尝试的一件事是设置 pageLoadTimeout 并使用显式等待来确保页面已加载。 “听起来我不能在每次调用的基础上覆盖这个策略?” - 我很确定这是每个驱动程序的事情。【参考方案2】:如果你想等待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 秒等。它将在持续时间内等待,直到元素被解除阻塞
如果您认为我误解了您的阙,我认为这是最好的解决方案,请告诉我
【讨论】:
你错过了这个问题。 “我真的很想在上传期间访问 DOM。有什么想法吗?” 您想验证进度条是否正确,您是否在进度条上放置了任何块 ui以上是关于Selenium FindElement 阻塞,直到文件上传完成的主要内容,如果未能解决你的问题,请参考以下文章