即使WebElement不可见,is_displayed()方法也返回true

时间:2019-12-16 12:34:08

标签: python python-3.x selenium selenium-webdriver automated-tests

我正在进行一项测试,该测试有时会记录可滚动表中显示的一些数据:

<div class='table-body'>
   <div class='scroll-wrapper>
      <div class='row'>
         <button class='button' type='button'></button>
         <div class='inner-data></div>
      </div>
      <div class='row'>
         <button class='button' type='button'></button>
         <div class='inner-data></div>
      </div>
      <div class='row'>
         <button class='button' type='button'></button>
         <div class='inner-data></div>
      </div>
   </div>
</div>

表中显示的总行数显示在屏幕上,允许我使用 while 循环,以确保收集所有数据。 但是,正如您在html代码上看到的那样,每行都有一个按钮,我正在为每一行单击。这是我的问题:在某个时候,我的方法find_elements_by_css_selector(div.row)找到了一个在窗口中不可见的WebElement ,并尝试单击其<button>。 因此,我得到以下错误:

ElementNotInteractableException: Message: Element <button class="btn" type="button"> could not be scrolled into view

我尝试使用is_displayed()方法和is_enabled()检查该元素在屏幕上是否可见,很遗憾,它们始终返回 True

你们有什么解决方案吗?

2 个答案:

答案 0 :(得分:-1)

此错误消息...

ElementNotInteractableException: Message: Element <button class="btn type="button"> could not be scrolled into view

...表示所需元素无法滚动到视图中并且不可交互。

如果您查看相关的HTML,则<button>标签为:

<button class='button' type='button'></button>

在父标签<div>内,如下所示:

<div class='row'>

您已通过定位器策略定位了<div>标签:

find_elements_by_css_selector(div.row)

但是对于其他某些元素,返回错误ElementNotInteractableException

<button class="btn      type="button">
observe the ^^^class^^^ attribute value

这不是您想要的元素。因此,您会看到错误。


解决方案

作为针对<button>标签的解决方案,您需要更深入地研究一步,进一步为visibility_of_all_elements_located()引入诱因 WebDriverWait ,然后单击每个元素,您可以使用以下任一Locator Strategies

  • 使用CSS_SELECTOR

    for element in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "div.table-body > div.scroll-wrapper div.row > button.button[type='button']"))):
        WebDriverWait(driver, 20).until(EC.visibility_of(element)).click()
    
  • 使用XPATH

    for element in WebDriverWait(driver, 30).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[@class='table-body']/div[@class='scroll-wrapper']//div[@class='row']/button[@class='button' and @type='button']"))):
        WebDriverWait(driver, 20).until(EC.visibility_of(element)).click()
    
  • 注意:您必须添加以下导入:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

答案 1 :(得分:-1)

感谢您的回答@DebanjanB。您的解决方案效果很好:

try:
    WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS-SELECTOR, "button"))):
    element.click()
except TimeoutException:
    # The button is not clickable, I scroll down

但是,我知道仅当按钮在DOM中但在我的窗口中不可见时,该按钮才是不可单击的(并且不可见)。而且即使您的解决方案有效,考虑到我在20秒后就会超时,这还是非常耗时的。我知道我可以减少WebDriverWait(driver, time)解决方案中的时间参数,但是找到了另一个解决方案:

try:
    self.driver.find_element_by_css_selector('button').click() 
except ElementNotInteractableException:
    # The button is not clickable, I scroll down

无论如何,谢谢您的帮助,我希望这个技巧可以帮助其他人;)