如何避免“元素当前不可见,因此可能无法与” Selenium Webdriver

Posted

技术标签:

【中文标题】如何避免“元素当前不可见,因此可能无法与” Selenium Webdriver【英文标题】:How I can avoid "Element is not currently visible and so may not be interacted with " Selenium Webdriver 【发布时间】:2012-05-25 08:57:16 【问题描述】:

我正在使用 selenium webdriver 2.210 + JAVA 进行测试。我有一个示例代码用于选择 gmail 中的所有邮件。但是当我尝试放置时,代码会抛出“元素当前不可见,因此可能无法与之交互”错误通过 webdriver 获取 URL 后延迟 5 秒。是否可以使此代码延迟工作?

    driver.get("https://mail.google.com/mail/u/0/?shva=1#all");
        delay(5);  ////*......Working fine without this...........*////
    driver.switchTo().frame(driver.findElement(By.id("canvas_frame")));
driver.findElement(By.xpath("//div[@class = 'T-Jo-auh']")).click();

提前致谢

【问题讨论】:

您需要尝试理解(并告诉我们)为什么会发生这种情况。一段时间后,页面上的第一个(!)//div[@class = 'T-Jo-auh'] 元素真的不可见吗?当您使用 Firebug 找到它时,您会看到什么?您可以尝试List<WebElement> list = driver.findElements("//div[@class = 'T-Jo-auh']");,然后通过使用isDisplayed() 进行测试,在列表中查找第一个可见元素 【参考方案1】:

我不确定,但每个 watir-webdriver 元素都有 - (Object) wait_until_present(timeout = 30) 方法。

如果此步骤是可选的,您应该检查可见性:

element = driver.findElement(By.xpath("//div[@class = 'T-Jo-auh']"));

if (element.isDisplayed()) 
  element.click();

请注意,我不是java专家,上面的代码没有经过测试。试一试。

【讨论】:

wait_until_present() 不在 WebDriver 中,但可以在 a similar way 中完成。这里的问题是元素存在,只是不可见(在这种情况下,WebDriver 拒绝与之交互)。此外,您的 visible() 方法称为 isDisplayed() 感谢斯莱尼克的澄清!用 JS 使元素可见会是作弊吗? :)【参考方案2】:

Selenium 不会与隐藏或不向用户显示的 WebElement 交互。在这种情况下,用户单击与 div 元素或类似的东西进行交互的情况并不罕见,这反过来又会触发实际的按钮,该按钮出于视觉目的而被隐藏。我建议在您的页面上运行 Firefox 中的 selenium IDE 中的步骤。查看当您单击“隐藏”元素时是否触发了多个事件。如果实际上触发了多个事件,请在您的 WebDriver 代码中遵循。

【讨论】:

【参考方案3】:

尝试将 selenium webdriver 降级到 2.20.0。

我在 ruby​​ gem 版本 2.21.0 和 2.21.2 中遇到了类似的错误。

在我的情况下,如果按钮通过 .Ajax 调用添加到页面,Web 驱动程序总是返回 button.visible? = false

我的测试之前的工作时间更长,但没有任何相关变化。 所以我认为这是当前版本的 webdriver 中的一个错误。

【讨论】:

【参考方案4】:

如果您的应用程序使用 jQuery,您可以使用 javascript 进行点击。我创建了这个简单的帮助程序来单击 WebDriver 拒绝找到的元素:

public static void jqClick(String selector, JavascriptExecutor driver) 
    driver.executeScript("$('" + selector + "').click()");

作为“驱动程序”,您可以使用例如org.openqa.selenium.firefox.FirefoxDriver

这是唯一对我有用的解决方案。

【讨论】:

【参考方案5】:

您确定您正在查看正确的元素吗?我遇到了类似的问题,结果页面上有两个相似的元素,一个可见,另一个不可见。 FindElement 函数正在返回不可见的那个。

我通过使用 FindElements 而不是 FindElement 解决了这个问题,然后使用 Linq 提取可见的那个。

【讨论】:

一开始没人会想到的证据。谢谢 ! :-) “我通过使用 FindElements 而不是 FindElements 解决了这个问题”。可能一个 FindElements 应该是别的东西? 那应该是“FindElements 而不是 FindElement” :) 明白了!谢谢,现在我还要检查元素是否显示,然后再对那个 web 元素进行一些操作...@Kesty ....我从没想过【参考方案6】:

或者,您可以使用 Selenium 中提供的 JavascriptExecutor 类。完成此操作后,您可以执行任何 JavaScript 来操作网页上的 DOM。

参考::http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/JavascriptExecutor.html

【讨论】:

【参考方案7】:

在我的例子中(在 c# 中从 Selenium WebDriver 调用 PhantomJSDriver)我必须将窗口大小设置为足够大以使元素可见:

driver.Manage().Window.Size = new Size(1000, 800);

我在阅读此处的问题时发现了解决方法: https://github.com/ariya/phantomjs/issues/11637

【讨论】:

【参考方案8】:
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.getElementById('id').setAttribute('visibility', 'true');");

driver.findElement(By.id("id")).click();

通过更改元素的可见性,您可以执行您的操作。 您可以使用 selenium 或 JavascriptExecutor 进行单击

【讨论】:

【参考方案9】:

以下是您可以解决问题的摘要(Protractor/Javascript 中的示例):

maximize the browser window(在 Chrome+Mac 上,目前你是have to do it differently):

browser.driver.manage().window().maximize();

确认没有其他元素与定位器匹配。如果存在与实际不可见的定位器匹配的另一个元素,则会出现此错误。

等待element to be clickable:

var EC = protractor.ExpectedConditions,
    elm = element(by.id("myid"));

browser.wait(EC.elementToBeClickable(elm), 5000);

元素的scroll into view:

var elm = element(by.id("myid"));
browser.executeScript("arguments[0].scrollIntoView();", elm);

点击via javascript:

var elm = element(by.id("myid"));
browser.executeScript("arguments[0].click();", elm);

移动到元素并通过“浏览器操作”点击:

var elm = element(by.id("myid"));
browser.actions()
    .mouseMove(elm)
    .click()
    .perform();

【讨论】:

【参考方案10】:

PhantomJS 用户应注意 ma​​ximize-window 答案。即使屏幕截图显示它完全可见,javascript 对话框也很有可能被认为位于视口之外。由于它清晰可见,因此某些滚动查看操作不会改变任何内容,并且所有其他操作也无用。 (其他基于 WebKit 引擎的浏览器也是如此,例如 MacOS Safari 和旧版 Chrome)

【讨论】:

【参考方案11】:

这很奇怪,但我必须在 Java 中明确设置浏览器大小。

driver.manage().window().setSize(new Dimension(1000, 800));

【讨论】:

以上是关于如何避免“元素当前不可见,因此可能无法与” Selenium Webdriver的主要内容,如果未能解决你的问题,请参考以下文章

元素当前不可见,因此可能无法与之交互,Selenium Dropdown Box Python

Selenium 不可见使用 XSLT 模板创建的元素

如何通过 ipmitool 将条目写入系统事件日志 (SEL)?

如何在 perl $sel->click 下使用 Selenium 点击 Javascript

避免在 SQL Server 中的 INSERT INTO SELECT 查询中重复

Javascript - 如何删除 nodeName 或 HTML 标记但不理会内部标记?