0

I'm working on a test which, at some point, records some datas displayed in a scrollable table:

<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>

The total number of line present in the table is displayed on the screen, allowing me to use a while loop in order to be sure to collect all the datas. However, as you can see on the html code, each row has a button i'm clicking for every row. And here is my issue : at some point, my method find_elements_by_css_selector(div.row) finds a WebElement which is not visible on the window, and tries to click on its <button>. Consequently, i get the following error:

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

I tried using is_displayed() method and is_enabled() to check if the element is visible on the screen, unfortunately they are always returning True.

Do you guys have any solutions ?

MatthiasDec
  • 145
  • 1
  • 11

2 Answers2

0

This error message...

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

...implies that the desired element could not be scrolled into view and is not interactable.

If you observe the relevant HTML the <button> tags are:

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

which are within the parent <div> tag as follows:

<div class='row'>

You have targetted the <div> tag with your Locator Strategy:

find_elements_by_css_selector(div.row)

But the error ElementNotInteractableException is returned for some other element:

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

Which is of coarse not your desired element. Hence you see the error.


Solution

As a solution to target the <button> tags you need to dig deeper one step further inducing induce WebDriverWait for the visibility_of_all_elements_located() and click each of the elements and you can use either of the following Locator Strategies:

  • Using 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()
    
  • Using 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()
    
  • Note : You have to add the following imports:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
-1

Thanks for your answer @DebanjanB. Your solution works well:

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

However, i know that the button is not clickable (and not visible) only when it's in the DOM but not visible on my window. And even if your solution works, it's quite time consuming, considering that i've a timeout after 20s. I know that I can decrease the time parameter in the WebDriverWait(driver, time) solution, but I found another solution:

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

Anyway, thanks for you help, and I hope this trick can help others ;)

MatthiasDec
  • 145
  • 1
  • 11