Selenium C# ElementNotVisibleException:元素不可交互,但该元素实际上是可见的

Posted

技术标签:

【中文标题】Selenium C# ElementNotVisibleException:元素不可交互,但该元素实际上是可见的【英文标题】:Selenium C# ElementNotVisibleException: element not interactable but the element is actually visible 【发布时间】:2019-05-04 01:20:32 【问题描述】:

我正在使用 Selenium.WebDriver for C# 在 Quora 上提问,只需在记事本中输入我的问题。

一切都很好,因为我不得不发布它。

要发布它,我需要单击跨度内的链接,如下所示:

<span id="__w2_wEA6apRq1_submit_question">
  <a class="submit_button modal_action" href="#" id="__w2_wEA6apRq1_submit">Add Question</a>
</span>

为了点击它,我已经尝试过这个方法,我已经用过我之前的所有按钮点击:

选择元素并点击它:

var element = driver.FindElement(By.CssSelector(".submit_button.modal_action"));
element.Click();

这样做我可以获得元素,但不幸的是它会抛出“ElementNotVisibleException”。调试我的应用程序时,我可以看到 Displayed 属性设置为 False,但事实并非如此,因为在我的 ChromeDriver 中我可以清楚地看到该按钮。

为了避免点击元素,我尝试了IjavascriptExecutorDriver.ExecuteJavaScript();通过脚本点击链接:

IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].click()", element);

Driver.ExecuteJavaScript(); 使用了相同的逻辑,但我得到了相同的结果,但是当我将相同的脚本写入 DevTools 的控制台选项卡时,它可以完美运行。

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

您可能会遇到在执行检查后按钮变为显示(可见)的情况,因此您可以尝试以下延迟以确保在检查时显示按钮:

public static void WaitForElementToBecomeVisibleWithinTimeout(IWebDriver driver, 
    IWebElement element, int timeout)

    new WebDriverWait(driver,                 
        TimeSpan.FromSeconds(timeout)).Until(ElementIsVisible(element));


private static Func<IWebDriver, bool> ElementIsVisible(IWebElement element)

    return driver =>
    
        try
        
            return element.Displayed;
        
        catch (Exception)
        
            // If element is null, stale or if it cannot be located
            return false;
        
    ;

如果按钮在视口中不可见(即需要滚动才能可见),那么您可以滚动它

public static void ScrollElementToBecomeVisible(IWebDriver driver, IWebElement element)

    IJavaScriptExecutor jsExec = (IJavaScriptExecutor)driver;
    jsExec.ExecuteScript("arguments[0].scrollIntoView(true);", element);

【讨论】:

感谢您的回答,我尝试使用您提供的方法,但响应超时,尝试 10 秒。还有其他提示吗?【参考方案2】:

根据您共享的 html,单击带有文本为 添加问题 的元素,因为该元素位于 模态对话框 中,您需要诱导 WebDriverWait 为所需的 ElementToBeClickable 并且您可以使用以下任一Locator Strategies 作为解决方案:

LinkText:

new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.LinkText("Add Question"))).Click();

CssSelector:

new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("span[id$='_submit_question']>a.submit_button.modal_action"))).Click();

XPath:

new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//span[contains(@id,'_submit_question')]/a[@class='submit_button modal_action' and contains(.,'Add Question')]"))).Click();

【讨论】:

感谢您的支持,但不幸的是这不起作用,我尝试了所有三种方法,它们都抛出了超时异常.. TimeoutExceptionfailed ExpectedConditions 的结果。通过findElement()Thread.sleep() 结合使用来调试您的代码。如果您能够找到该元素,请使用观察结果更新问题。

以上是关于Selenium C# ElementNotVisibleException:元素不可交互,但该元素实际上是可见的的主要内容,如果未能解决你的问题,请参考以下文章

Selenium:使用 C# 在 IWebElement 上触发鼠标滚轮

C# + Selenium + ChromeDriver 爬取网页

如何在 c# 中使用 Selenium 刷新网页?

如何在 C# Selenium 中向 FirefoxDriverService 添加配置文件规范?

C#使用Selenium

Selenium + C#:ExecuteAsyncScript 不起作用