Click intercepted, other element would receive the click. Allow this other element to receive the click

Question:

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 class="_4xvap4u"></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)

Asked By: r-d-r-b-3

||

Answers:

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 class="_4xvap4u"></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.

Answered By: Michael Mintz