我们在 Jenkins box(运行 Linux)上使用 Selenium-Webdriver 来驱动 Firefox 来测试一个相当复杂的网络应用程序。 Web 应用程序需要上传照片进行测试,我们通过使用输入文件对话框的发送键实现了这一点。不幸的是(可能由于 uploader 的工作方式,它是 plupload 并通过 XHR 而非 FORM post 上传)文件选择器对话框永远不会关闭。虽然这有点烦人,但过去测试仍然顺利通过。从 selenium-2.45.0 切换到 selenium-2.53.1 并将 FireFox 升级到 45 我们发现我们的测试现在失败了,因为元素由于文件选择器对话框而不再可见(至少我们假设这是元素不再可见的原因对点击使用react是因为它们在文件对话框后面)。
我意识到无法单击关闭对话框按钮,并且我已尝试通过各种方式向浏览器发送转义键以关闭对话框,但我尝试过的都不起作用:
((RemoteWebDriver)driver).getKeyboard().pressKey(Keys.ESCAPE);
由于在测试中运行的 Jenkins 服务器与由 Selenium 驱动的 Firefox 在不同的服务器上,因此 Roboto 和 AutoIt 不是一个选项。是否有某种方法可以触发不涉及与对话框交互的对话框关闭。我的想法是在页面中注入(inject)一些 javascript 以围绕文件输入创建一个表单,然后提交该表单(无处可去),然后重新加载页面,但事实证明这是不成功的。
最佳答案
可能有一个点击事件传输到 <input type="file">
元素,打开文件对话框。
克服此问题的一种方法是禁用内部 click
通过覆盖方法。这段 JavaScript 将禁用内部 click
对于每个 <input type="file">
元素:
((JavascriptExecutor)driver).executeScript(
"HTMLInputElement.prototype.click = function() { " +
" if(this.type !== 'file') HTMLElement.prototype.click.call(this); " +
"}; " );
然后调用.sendKeys("full file path")
上传文件在 <input type="file">
上元素。
在某些情况下,<input type="file">
只驻留在内存中。如果是这种情况,您必须将其插入到页面中:
((JavascriptExecutor)driver).executeScript(
"HTMLInputElement.prototype.click = function () {" +
" if (this.type !== 'file') {" +
" HTMLElement.prototype.click.call(this);" +
" }" +
" else if (!this.parentNode) {" +
" this.style.display = 'none';" +
" this.ownerDocument.documentElement.appendChild(this);" +
" this.addEventListener('change', () => this.remove());" +
" }" +
"}");
参见 https://gist.github.com/florentbr/d7bee068932bdf6e00af3b9f01af9af6
关于java - Selenium 关闭文件选择器对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39259460/