How do you fix the "element not interactable" exception?
Asked Answered
F

20

74

I know this has been asked lots of times before but how do you get around the "element not interactable" exception?

Here is my code:

button = driver.find_element_by_class_name(u"infoDismiss")
type(button)
button.click()
driver.implicitly_wait(10)

Here is the HTML:

<button class="dismiss infoDismiss">
    <string for="inplay_button_dismiss">Dismiss</string>
</button>

And here is the error message:

selenium.common.exceptions.ElementNotInteractableException: Message: 

After is says message there is literally nothing.

I have spent lots of time searching the web, not finding anything that solves my issue. I would really appreciate an answer.

Edit: Changed "w" to driver so it is easier to read

Update: I have just realized that I've found the HTML of the wrong button! The real button HTML is below:

<button class="dismiss">
    <string for="exit">Dismiss</string>
</button>

Also, I've used the answers and comments and edited my code to look like this:

button = driver.find_element_by_css_selector("button.dismiss")
w.implicitly_wait(10)
ActionChains(w).move_to_element(button).click(button)

And now I get a new error:

selenium.common.exceptions.WebDriverException: Message: Tried to run command without establishing a connection

The error happens in line 1: button = driver.find_element_by_css_selector("button.dismiss")

Footie answered 22/5, 2017 at 17:47 Comment(2)
Are you sure that this button is the only element with "infoDismiss" class name? Try button = w.find_element_by_css_selector("button.dismiss.infoDismiss")Keppel
No, I've just checked and there is definitely only oneFootie
M
62

A possibility is that the element is currently unclickable because it is not visible. Reasons for this may be that another element is covering it up or it is not in view, i.e. it is outside the currently view-able area.

Try this:

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By

button = driver.find_element(By.CLASS_NAME, u"infoDismiss")
driver.implicitly_wait(10)
ActionChains(driver).move_to_element(button).click(button).perform()
Marable answered 22/5, 2017 at 18:32 Comment(6)
I've tried that but it still doesn't seem to click it. It doesn't click it but it doesn't raise an error either.Footie
I suggest you check if it is ACTUALLY being clicked. Add some click event listeners on the element to see if a click is being performed instead of visually inspecting a click.Marable
Rolodophone, in that situation you describe, please try ActionChains(driver).move_to_element(button).click(button).perform(), that is, add ".perform()".Sarmatia
@Sarmatia made the correction, thanks for the heads up.Marable
I am facing a similar problem, my question raised here: #63317296 . button=driver.find_element_by_xpath("//*[@id='submitMe']") driver.implicitly_wait(10) ActionChains(driver).move_to_element(button).click(button).perform() I get error Message: javascript error: Failed to execute 'elementsFromPoint' on 'Document': The provided double value is non-finite.Linder
It can also be outside of sight because the browser window is too small. Try options.add_argument("--disable-notifications")Timaru
W
31

I just ran into a similar issue and was able to fix it by waiting until the button was "clickable".

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

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome('./chromedriver', options=chrome_options)

browser.get(('YOURWEBSITEHERE.COM'))

button = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button.dismiss')))
button.click()
Waterborne answered 20/7, 2019 at 14:30 Comment(6)
I would name this a "work around" then a solution. But, well... :-DMalicious
Where does the variable browser come from?Invaluable
@Invaluable I edited the comment to answer your questionWaterborne
@Malicious I do not think it is a "work around", this waits until the button is interactable (clickable) which is the issue in the posted situation :)Waterborne
Good Answer, not a workaround! - I tried many things before reading this post. In my case the element is definitely becoming visible before it is clickable, presumably because I only just revealed it with the previous click.Papal
should be the accepted answer! Seems to be actually the right way. Not waiting for some random time but rather wait until it is clickable.Shudder
M
24

For those discovering this now and the above answers didn't work, the issue I had was the screen wasn't big enough. I added this when initializing my ChromeDriver, and it fixed the problem:

options.add_argument("window-size=1200x600")
Morvin answered 13/1, 2020 at 21:21 Comment(2)
Your simple solution really saved my day :D. All above solutions did not worked for me.Indeciduous
this should be the right answer !Faustinafaustine
T
17

The error "Message: element not interactable" mostly occurs when your element is not clickable or it is not visible yet, and you should click or choose one other element before it. Then your element will get displayed and you can modify it.

You can check if your element is visible or not by calling is_displayed() method like this:

print("Element is visible? " + str(element_name.is_displayed()))
Tera answered 11/5, 2020 at 10:29 Comment(0)
C
9

I honestly did it via importing it from a library:

from selenium.webdriver.common.keys import Keys

search.send_keys(Keys.RETURN) 

I spent much time on it, maximizing the button, importing timer 'wait' but somehow nothing worked except this one

I am an amateur still but I wanted to contribute here with my solution : )

Conqueror answered 11/8, 2021 at 10:12 Comment(1)
Thanks, it worked in Gmail login.Sang
C
9

right-click and copy full xpath like below example it will work for sure

driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[3]/center/input[1]").click()
Chapple answered 9/10, 2021 at 14:3 Comment(4)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Burbank
This really works thak you so muchMegacycle
This also worked for me (actually, with the relative xpath). Does anyone have an explanation why xpath does the trick in these cases?Estremadura
I hate this solution. Unfortunately... it worked. Edit: The reason this solution worked, was because I was picking the wrong element with my CSS selector. Guys, this solution is a good sanity-test, but if it works, make sure you can specify the element better in your CSS selector to see if you can find it.Hyperextension
M
2

Found a workaround years later after encountering the same problem again - unable to click element even though it SHOULD be clickable. The solution is to catch ElementNotInteractable exception and attempt to execute a script to click the element.

Example in Typescript

async clickElement(element: WebElement) {
    try {
        return await element.click();
    } catch (error) {
        if (error.name == 'ElementNotInteractableError') {
            return await this.driver.executeScript((element: WebElement) => {
                element.click();
            }, element);
        }
    }
}
Marable answered 25/7, 2019 at 11:16 Comment(0)
H
1

flex box size is determined by screen size. so you should put screen size to selenium driver.

In my case this works

        self.driver.set_window_position(0, 0)
        self.driver.set_window_size(1400, 900)
Hyderabad answered 8/10, 2021 at 2:36 Comment(0)
A
0

For the html code:

test.html

<button class="dismiss"  onclick="alert('hello')">
    <string for="exit">Dismiss</string>
</button>

the below python code worked for me. You can just try it.

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("http://localhost/gp/test.html")
button = driver.find_element_by_class_name("dismiss")
button.click()
time.sleep(5)
driver.quit()
Agent answered 28/5, 2019 at 18:59 Comment(2)
Using sleep() is considered to be a bad practice in test automation.Chaqueta
This doesn't account for any sort of issue where the element wouldn't be interactable yet, such as a loading overlay. This answer is not useful.Corenda
T
0

use id of the element except x_path.It will work 100%

Tailspin answered 17/2, 2020 at 5:7 Comment(0)
C
0

First search for the element by xpath:

    buttonNoInteractable = browser.find_element_by_xpath('/html/body/div[2]/div/div/div[2]/div/div/div[2]/div/table[2]/thead/tr/th[2]/input')

Then Wait for the element to be clickable:

    buttonNoIteractable.click()
    time.sleep(10)

Alternatively search by class name. You may need to vary the wait from 10-30 seconds.

    send = browser.find_element_by_name('stacks') send.click()
Chak answered 29/10, 2020 at 20:35 Comment(0)
H
0

The two major reason for this problem are well documented here elements not interactable reason

So 2 solutions out of which explicit wait would be better in most of the situations

Providing the solution based on python here

Implicit Wait

driver.implicitly_wait(20)

Explicit Wait in python

# impor these stataments 
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.common.by import By

# then you can run like below
userNameTextBox=wait.until(EC.visibility_of_element_located((By.NAME, "login")))
userNameTextBox.send_keys(username)

please note that all should be in CAPS after By , be it id , xpath, etc

Expected conditions for explicit wait

Horde answered 15/6, 2021 at 9:9 Comment(0)
L
0

I had a problem where 2 buttons had the exact same ID. Full XPath was one way to solve the issue, but in an ever changing enviornment, full XPaths are quite often subject to change.

The first time I used Chrome.FindElement(By.Id("btnOpenLayawaysContinue") it worked, but the 2nd time it did not, because the 2nd time referred back to the first element which was in the DOM but not visible on the page.

So what I did is I built a list, and did a for-each with a try-catch inside

TheBtns = Chrome.FindElements(By.Id("btnOpenLayawaysContinue")).ToList();
foreach(IWebElement Btn in TheBtns) {
    try {
        Btn.Click();
        Thread.Sleep(1000);
        return;
    } catch {}
}
Lakeshialakey answered 20/8, 2021 at 3:10 Comment(0)
S
0

First of all I change chrome driver

  1. install pip install webdriver-manager

  2. Change services to new webdriver

     from selenium import webdriver
     from selenium.webdriver.chrome.service import Service as ChromeService
    
     service = ChromeService(ChromeDriverManager().install())  
     driver = webdriver.Chrome(service=service, options=chrome_options)
    

(Mention in comments if you need my webdriver chrome_options)

Then i use Actions to click elements. In my example, i gether facebook 'more info' buttons and clicking on this elements

more_btns = driver.find_elements(By.XPATH, '//div[@class="qi72231t" and contains(text(), "Ещё")]')

    for btn in more_btns:
        try:
            driver.implicitly_wait(10)
            ActionChains(driver).move_to_element(btn).click(button).perform()
        except:
            print('ERROR using ActionChains(driver).move_to_element(btn).click(button).perform()')

In Facebook my first iteration throw error but all next buttons works fine

Slattern answered 23/8, 2022 at 7:54 Comment(1)
What variable is button? Same as btn ?Pneumectomy
A
0

My case was a bit weird, I was trying to target the input (radio) button directly using xpath, but then I tried to target the label that contains that input (radio) and it worked...

Antipus answered 19/10, 2022 at 22:55 Comment(0)
M
0

This code will work for every type of click

button=browser.find_element(By.XPATH, '*//span[text()="Price"]') 
time.sleep(3)
browser.execute_script("arguments[0].click();", button)

'*//span[text()="Price"]') Replace span with your required tag and Price with the text of tag

Mil answered 7/4, 2023 at 18:55 Comment(1)
No, Sleeping, hoping the DOM will be ready after a set period of time, will not always work. You should wait until the element is visible, not just for a set period of time.Harvin
L
0

selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable

above exception would resolve by removing time.sleep(sec) at the end of line in code

for instance: ph_add2cart=driver.find_elements(By.XPATH,"//div[@class='row']/div[@class='product")

    for crt in ph_add2cart:
        crt.click()
    time.sleep(5)

if we put time.sleep() at the end without any code then we would get exception as 'selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable'

and i tried by removing the time.sleep() and run then i got success reponse.

Lancashire answered 2/11, 2023 at 5:7 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewAnet
F
0

Sometimes the window isn't fully loaded, hence use sleep(5), in my case it worked.

Factfinding answered 30/4, 2024 at 17:41 Comment(0)
R
-1

It will be better to use xpath

from selenium import webdriver
driver.get('www.example.com')
button = driver.find_element_by_xpath('xpath')
button.click()
Relativize answered 1/5, 2019 at 10:8 Comment(1)
Why do you think so?Chaqueta
B
-1

I have found that using Thread.sleep(milliseconds) helps almost all the time for me. It takes time for the element to load hence it is not interactable. So i put Thread.sleep() after selecting each value. So far this has helped me avoid the error.

try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}

        Select nationalityDropdown=new Select(driver.findElement(By.id("ContentPlaceHolderMain_ddlNationality")));

        nationalityDropdown.selectByValue("Indian");

        try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}     
Barty answered 26/12, 2019 at 6:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.