Home > Software engineering >  Click intercepted, other element would receive the click. Allow this other element to receive the cl
Click intercepted, other element would receive the click. Allow this other element to receive the cl

Time:09-30

Goal:

I want to click the body by below code ;

WebDriverWait(driver,1).until(EC.element_to_be_clickable((By.XPATH, '//body'))).click()

Problem :

My solution needs to be flexible and in case that there is an overlay the click gets intercepted and it throws an error ;

Message: element click intercepted: Element <body>...</body> is not clickable at point (502, 337). 
Other element would receive the click: <div ></div>

Question :

I searched for ages how to achieve to "allow the click" and in this case click the other element which the error displays.

So instead of my orginal click (body) i want to continue in case it's intercepted and click the element thats overlays the body (div / iframe which the error displays). I need this to be flexible so whatever is overlaying and would receive the click (div / iframe /modal / etc)

CodePudding user response:

In this scenario, a regular selenium click is going to throw that exception if there's an overlay, but you can execute JS from selenium to get around that issue. How to simulate a click with JavaScript?

css_selector = "body"
script = (
    """var simulateClick = function (elem) {
           var evt = new MouseEvent('click', {
               bubbles: true,
               cancelable: true,
               view: window
           });
           var canceled = !elem.dispatchEvent(evt);
       };
       var someLink = document.querySelector('%s');
       simulateClick(someLink);"""
    % css_selector
)
driver.execute_script(script)

(If your css_selector contains quotes, you may need to escape them first, such as with re.escape(CSS_SELECTOR), before running that.)

And if you're looking for an easier way to do a JS click within selenium, there's a Python Selenium framework, https://github.com/seleniumbase/SeleniumBase, which already has a method for that: self.js_click("SELECTOR").


If it's always the same element overlay, you can click it first with an if statement if visible.

def is_element_visible(selector, by="css selector"):
    try:
        element = driver.find_element(by, selector)
        if element.is_displayed():
            return True
    except Exception:
        pass
    return False

if is_element_visible("div._4xvap4u"):
    driver.find_element("css selector", "div._4xvap4u").click()

WebDriverWait(driver,1).until(EC.element_to_be_clickable((By.XPATH, '//body'))).click()

If that selector is not guaranteed to be unique from the exception message Other element would receive the click: <div ></div>, then it makes for a good feature request to https://github.com/SeleniumHQ/selenium. But if it is guaranteed to be a unique selector, you could parse it out and then click it.

  • Related