How Does Selenium Click on Elements That Are 50% on Screen and 50% Not on Screen

How does Selenium click on elements that are 50% on screen and 50% not on screen?

element’s in-view center point

As per the WebDriver W3C Specification an element’s in-view center point is the origin position of the rectangle that is the intersection between the element’s first DOM client rectangle and the initial viewport.

Given an element that is known to be in view, it can be calculated this way:

  1. Let rectangle be the first element of the DOMRect sequence returned by calling getClientRects on element.
  2. Let left be max(0, min(x coordinate, x coordinate + width dimension)).
  3. Let right be min(innerWidth, max(x coordinate, x coordinate + width dimension)).
  4. Let top be max(0, min(y coordinate, y coordinate + height dimension)).
  5. Let bottom be min(innerHeight, max(y coordinate, y coordinate + height dimension)).
  6. Let x be floor((left + right) ÷ 2.0).
  7. Let y be floor((top + bottom) ÷ 2.0).
  8. Return the pair of (x, y).

An element is in view if it is a member of its own pointer-interactable paint tree, given the pretense that its pointer events are not disabled.


Element Click

element_click

As per the documentation the Element Click command scrolls into view the element if it is not already pointer-interactable, and clicks its in-view center point.

Note: If the element’s center point is obscured by another element, an element click intercepted error is returned. If the element is outside the viewport, an element not interactable error is returned.


Solution

In such cases there are two possible solutionas follows:

  1. You can induce WebDriverWait setting the expected_conditions as element_to_be_clickable(). So effectively your line of code will be:

    WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".reply-button"))).click()
  2. You can use move_to_element(to_element) and click(on_element=None) method respectively. So effectively your line of code will be:

    ActionChains(driver).move_to_element(element).click(element).perform()

Reference

You can find a relevant discussion in selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element is not clickable with Selenium and Python

Selenium - element click intercepted: Element is not clickable at point

That page can be scraped without the overheads and complexities of Selenium: you can use requests/bs4 instead:

import requests
from bs4 import BeautifulSoup

headers= {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'}
s = requests.Session()
s.headers.update(headers)
for x in range(1, 10): ## pick up the range here
r = s.get(f'https://g1.globo.com/ciencia/index/feed/pagina-{x}.ghtml', headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
news = soup.select('div.feed-post-body')
for n in news:
title = n.select_one('a')
print(title.get_text(strip=True))

This returns the titles, but you can select any other elements:

O supertelescópio que vai investigar a origem das estrelas
Pesquisa liga beijos na Idade do Bronze a origem da herpes labial
Os animais que fazem arte - e podem ter vantagens evolutivas com isso
O que é a hipótese de Gaia, que defende que a Terra 'está viva'
Septuagenárias e rebeldes

If you are keen on using Selenium, then bear in mind that page will load the first three pages worth of news by detecting scrolling to the bottom of the page, and then you can click the button to take you to page 4. You also need to dismiss the cookie button, and to wait for the heavy javascript adverts from page to load.You also need to account for the actual url of the page changing on click, and to redefine the elements.

Message: element click intercepted: Element span ... /span is not clickable at point (657, 594). Other element would receive the click with Selenium

The LOAD MORE element is a Angular element so to click on it you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    driver.get("https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#cookiePolicy-btn-close>span"))).click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.buy-link.load-more-btn[value='LOAD MORE']"))).click()
  • Using XPATH:

    driver.get("https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@id='cookiePolicy-btn-close']/span"))).click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='buy-link load-more-btn' and @value='LOAD MORE']"))).click()
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
  • Browser Snapshot:

LOADMORE

How to dynamically check table is available ( waiting ) using Selenium instead of having a fixed sleep

With the following instance of WebDriverWait:

var wait = new WebDriverWait(Driver, TimeSpan.FromMilliseconds(500);

Once you click and enable the rows, to wait for the rows to exist there can be two approaches:

  • As there is some ambiguity regarding the number of rows (no row, 1 row or multiple rows), a safer approach would be to probe the Displayedness of the MyTable element as you mentioned in your comment. The element displayed algorithm is a boolean state where true signifies that the element is displayed and false signifies that the element is not displayed.

    TcAssert.WaitUntilTrue(() => this.Page.MyTable.Displayed);
  • The other approach would be to wait for the Visibility of the element MyTable. The visibility of an element is guided by what is perceptually visible to the human eye. and is based on crude approximations about an element's nature and relationship in the tree. An element is in general to be considered visible if any part of it is drawn on the canvas within the boundaries of the viewport.

Element Out Of The ScreenShot error while taking screenshot from whatsapp using selenium and VBA

As you are seeing Element Out Of The ScreenShot error presumably you may need to scroll the element within the Viewport before taking the screenshot as follows:

Set element = bot.FindElementByXPath("//span[@data-testid='status-dblcheck']")
element.ScrollIntoView().TakeScreenshot().Copy
Sheets(1).Cells(5, 5).PasteSpecial


Related Topics



Leave a reply



Submit