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