0

While my python selenium code works well, I identified several sections of it in which I am waiting to click on an XPATH located item and therefore tried to define a function to do so as follows:

def click_xpath(browser, xpath_string: str):
    """ locates a button by XPATH
        and clicks on it
    """
    WebDriverWait(browser, 10).until(
        EC.element_to_be_clickable((By.XPATH, xpath_string))
    ).click()
    return browser

and call it as follows:

driver = click_xpath(driver, "/html/body/div[5]/div[3]/div/button")

but then the next instruction:

find_textbox = driver.find_element_by_id("search")

fails with the following:

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

The previous working code that I attempted substituting by calling my function was:

WebDriverWait(driver, 10).until(
   EC.element_to_be_clickable((By.XPATH, "/html/body/div[5]/div[3]/div/button"))
).click()

which worked well, with subsequent uses of driver proceeding normally.

What am I overlooking? Thanks

PS Assuming this can be done, what type hind should I use for the return object of my function?

2 Answers 2

1

I guess the problem here is as following:
When you clicking the element after waiting for the element to be clickable with click_xpath it works correctly but when you trying to click it immediately with

find_textbox = driver.find_element_by_id("search")

You are getting the error since you are trying to click the element too early.
So, you are simply missing a delay there.
Try changing from

find_textbox = driver.find_element_by_id("search")

To

find_textbox =  WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.ID, search)))

I think this will resolve your problem

Sign up to request clarification or add additional context in comments.

6 Comments

So ideally it should be TimeoutException shouldn't it? ElementNotInteractableException: is a very specific error that does not occur due to time delay, agree?
These are different exceptions, thrown in different cases, you know. TimeoutException will be thrown in case the expected condition could not be matched in the defined timeout period. This mostly occur in case the locator is wrong, element is invisible etc. While ElementNotInteractableException will occur in case element is out of viewport or still not completely rendered or covered by some other element. However in case of element defined by "search" id - it will normally be located on the top part of the screen, so I guess here the case is missing wait condition.
OMG I apologise for the trivial mistakes (the missing parenthesis was just a copy and paste mistake but the missing ones on the click method was a real one). That was the source of errors. Timeout you've talked about was not an issue but still a good practice. Thank you very much.
it's OK. The only way to get real experience it to make a code, meet all kinds of errors and mistakes and learn on your own all these mistakes.
@Prophet: Whatever you said it's correct, but if the issue was viewport then how explicit wait will resolve the issue? I still feel the question is irrelevant with respect to explicit wait.
|
1

I think

.click 

should be

.click()

also, there is no need to return a driver/browser from this method click_xpath

cause it says just click on the XPath node, right?

also, a ) is missing here

driver = click_xpath(driver, "/html/body/div[5]/div[3]/div/button"

I would use something like this:

def click_xpath(browser, xpath_string):
    WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, xpath_string))).click()
    print('Clicked on the', xpath_string, ' node')

somenode = click_xpath(driver, "/html/body/div[5]/div[3]/div/button")

and the second question that you asked, what

what type hind should I use for the return object of my function?

.click() method returns void, so if you are using it on a web element then there is no need to return anything. However, you could do the below in case you are very knee on returning.

Also, note that, WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, xpath_string))) will return a web element if found.

Code:

def click_xpath(browser, xpath_string):
    web_element = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, xpath_string)))
    print('Clicked on the', xpath_string, ' node')
    return web_element

somenode = click_xpath(driver, "/html/body/div[5]/div[3]/div/button")
somenode.click()

1 Comment

Thanks for the clarification of the void return

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.