无法使用 Selenium Java 中的 sendKeys() 将文件上传到“浏览”按钮

Posted

技术标签:

【中文标题】无法使用 Selenium Java 中的 sendKeys() 将文件上传到“浏览”按钮【英文标题】:Unable to upload a file to the "browse" button using sendKeys() in Selenium Java 【发布时间】:2020-05-09 13:38:28 【问题描述】:

我正在尝试自动化上传文件功能。我曾尝试使用不同的 xpath 来获取 input element,但似乎我可能做的不对。 我的输入元素没有 id

<input name="qqfile" title="file input" style="margin: 0px; padding: 0px; top: 0px; height: 100%; right: 0px; font-family: Arial; font-size: 3500px; position: absolute; cursor: pointer; opacity: 0;" type="file" qq-button-id="7ca76e6f-e8ac-49f4-ab1e-c143e4af60d8">

并且在同一个html中还有另一个同名的input元素。

<input name="qqfile" title="file input" style="margin: 0px; padding: 0px; top: 0px; height: 100%; right: 0px; font-family: Arial; font-size: 3500px; position: absolute; cursor: pointer; opacity: 0;" type="file" multiple="" qq-button-id="b5ebbdcb-6f33-4f10-a569-5dba94f54d0e">

因此,当我使用 By.xpath("//input[contains(@name,'qqfile')] 时,我得到一个 Element not visible exception 我认为这是因为上下文中存在具有相同名称的 2 个元素。 如何唯一标识每个元素?

附加 HTML 代码:

<div tabindex="15" id="annUploadDoc"><div class="qq-uploader-selector qq-uploader" qq-drop-area-text="Drop files here">
            <div class="qq-total-progress-bar-container-selector qq-total-progress-bar-container qq-hide">
                <div class="qq-total-progress-bar-selector qq-progress-bar qq-total-progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
            </div>
            <div class="qq-upload-drop-area-selector qq-upload-drop-area" style="display: none;" qq-hide-dropzone="">
                <span>Drop files here to upload</span>
            </div>
            <div class="qq-upload-button-selector qq-upload-button" style="overflow: hidden; position: relative; direction: ltr;">
                <div class="btn upload btn-style-3">
                    <div>Browse</div>
                </div>
            <input name="qqfile" title="file input" style="margin: 0px; padding: 0px; top: 0px; height: 100%; right: 0px; font-family: Arial; font-size: 3500px; position: absolute; cursor: pointer; opacity: 0;" type="file" qq-button-id="fd389870-bdb2-480e-8138-8f2ff762de22"></div>
            <span class="qq-drop-processing-selector qq-drop-processing qq-hide">
                <span>Processing dropped files...</span>
                <span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
            </span>
            <ul class="qq-upload-list-selector qq-upload-list" aria-live="polite" aria-relevant="additions removals"></ul>

            <dialog class="qq-alert-dialog-selector">
                <div class="qq-dialog-message-selector"></div>
                <div class="qq-dialog-buttons">
                    <a class="qq-cancel-button-selector" href="javascript:void(0)">Close</a>
                </div>
            </dialog>

            <dialog class="qq-confirm-dialog-selector">
                <div class="qq-dialog-message-selector"></div>
                <div class="qq-dialog-buttons">
                    <a class="qq-cancel-button-selector" href="javascript:void(0)">No</a>
                    <a class="qq-ok-button-selector" href="javascript:void(0)">Yes</a>
                </div>
            </dialog>

            <dialog class="qq-prompt-dialog-selector">
                <div class="qq-dialog-message-selector"></div>
                <input type="text">
                <div class="qq-dialog-buttons">
                    <a class="qq-cancel-button-selector" href="javascript:void(0)">Cancel</a>
                    <a class="qq-ok-button-selector" href="javascript:void(0)">Ok</a>
                </div>
            </dialog>
        </div></div>

【问题讨论】:

你能添加更多的html吗?也许你应该附加到父元素 @Evgeniy 即使我尝试获取父元素并附加到它,也没有任何反应。 sendKeys() 不起作用。我想这可能是因为我只需要将它附加到输入元素? 请添加更多的html,我会尝试写xpath @EvgeniyChiruk 我在问题中添加了额外的 HTML。请检查并帮助我。 【参考方案1】:

第二个元素有multiple属性,你可以搜索没有它的元素

By.xpath("//input[contains(@name,'qqfile')][not(@multiple)]")

或者用 cssSelector

By.cssSelector("[name='qqfile']:not(multiple)")

style 属性使&lt;input&gt; 字段不可见。如果 UI 操作无法使其可见,您可以使用 JavaScript 设置 value 属性

String pathToFile = "path";
WebElement fileField = driver.findElement(By.xpath("//input[contains(@name,'qqfile')][not(@multiple)]"));
driver.executeScript("arguments[0].value = 'arguments[1]';", fileField, pathToFile);

【讨论】:

我按照您的要求尝试了,但出现错误 org.openqa.selenium.ElementNotVisibleException: Element is not displayed (WARNING: The server did not provide any stacktrace information) 但是该元素存在并已加载,因为如果我尝试获取它的父元素,它不会引发任何错误。 @PratikshaB style 属性使其隐藏,也许您需要先单击某些内容才能使其可见? @PratikshaB 你可以看到“选择文件”按钮吗? 我可以看到“浏览”按钮 @PratikshaB 在另一个元素中浏览,&lt;div&gt;&lt;input&gt; 之前。【参考方案2】:

试试这个 xpath:

By.xpath("//div[@id='annUploadDoc']//input[contains(@name,'qqfile')]")

【讨论】:

我尝试了 Xpath,但我得到了同样的错误 org.openqa.selenium.ElementNotVisibleException: Element is not display (WARNING: The server did not provide any stacktrace information)你能帮我解决这个问题吗?我不确定为什么会收到此错误。 我觉得这个链接可以帮到你:groups.google.com/forum/#!topic/selenium-users/LdM4hKdIfv4【参考方案3】:

输入是隐藏的,因为父 div 在样式中有 hidden 属性。 我猜您正在明确等待输入元素的可见性(可能是您正在使用的方法)。如果您的定位器是正确的,那么只需使用驱动程序实例即可。

driver.findElement(By.cssSelector("your path")).sendKeys("file path")

它不会给你元素不可见的异常。

【讨论】:

我尝试了您的解决方案,但现在没有得到元素不可见异常:org.openqa.selenium.NoSuchElementException: Unable to find element with css selector == "//input[ @name='qqfile'][not(@multiple)]" 现在很明显定位器不正确。如果不是,则元素可能位于框架中或驱动程序实例位于其他选项卡上 如果你能帮我定位一下。该元素不在不同的框架中。我已经检查过了。并且驱动程序实例位于同一个选项卡上,因为它能够在表单上执行下一个操作。 上述共享的html只有一个带有name属性的input元素。如果没有完整的 html 页面,很难猜测定位器。你可以试试下面的 css,看看你能在 dom 中看到多少个元素。 css: #annUploadDoc 输入[标题][qq-button-id] 我使用您的 CSS 进行了搜索。 html 页面中只有一个带有该 css 的元素!你现在能帮我识别定位器吗?【参考方案4】:

我找到了解决问题的方法。 我使用的是 IEDriver。显然,IEDriver 以某种方式呈现网页元素。 切换到 ChromeDriver 后,使用 SendKeys() 上传工作正常。

【讨论】:

以上是关于无法使用 Selenium Java 中的 sendKeys() 将文件上传到“浏览”按钮的主要内容,如果未能解决你的问题,请参考以下文章

聚焦文本字段中的 TYPE 值(如 selenium RC 中的 TYPE)- Selenium webdriver

无法使用 Selenium Java 中的 sendKeys() 将文件上传到“浏览”按钮

无法使用Selenium和Java 11导入org.openqa.selenium.WebDriver

无法在 IE 上使用 Java 中的 Selenium WebDriver 获取新窗口句柄

Selenium-Webdriver (Java) 无法始终执行“悬停和单击”功能

无法使用Selenium Java脚本在模式对话框中单击项目