3

I have a question that was somehow discussed here ([python][selenium] on-screen position of element) but that doesn't currently do what I'm trying to achieve.

My goal is the following: element.location gives the position of the top left corner of element in the browswer. I have a website in which, even if it's probably not a good selenium practice, I want to be able to click on such element purely based on its position because it has never changed and likely never will. Assuming element.location gives {'x': 253, 'y': 584}, this is the code I tried so far with no luck

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver.maximize_window()
url = "https://learn.letskodeit.com/p/practice"
driver.get(url)
open_window_elem = driver.find_element_by_id("openwindow")

# from wherever the mouse is, I move to the top left corner of the broswer
action = ActionChains(driver)
action.move_by_offset(-1000, -1000)    
action.click()
action.perform()

y_coordinate = open_window_elem.location["y"]
x_coordinate = open_window_elem.location["x"]

action = ActionChains(driver)
action.move_by_offset(x_coordinate, y_coordinate)
action.click()
action.perform()

Nothing happens when I run this code. I would except to open a new window. Can somebody help?

Angelo
  • 1,594
  • 5
  • 17
  • 50
  • why to go with location when you have other fail proof options to access the locator? – Abhishek_Mishra Aug 23 '18 at 10:10
  • @Abhishek_Mishra good question. I'm creating an automated script that will first try to get and click the element using normal locators but since the element HTML syntax keeps changing, I'm building a second way to click on this element purely based on its location so that when the DOM changes, at least my script keeps working, giving me the time to fix my code (based on Page Object model) – Angelo Aug 23 '18 at 12:03
  • to get the co-ordinates you need to first get the WebElement, in case the DOM is changed, it will fail there only. Have a look here : https://stackoverflow.com/questions/6775351/clicking-at-coordinates-without-identifying-element – Abhishek_Mishra Aug 23 '18 at 13:03
  • Possible duplicate of [Clicking at coordinates without identifying element](https://stackoverflow.com/questions/6775351/clicking-at-coordinates-without-identifying-element) – Abhishek_Mishra Aug 23 '18 at 13:06
  • the position of the element never changes. I know its x,y coordinates are always the same. That's why, no matter what the DOM is, I would like selenium to click on that x,y point on the screen – Angelo Aug 23 '18 at 13:06
  • That link is actually very helpful. I found most of the python-selenium related solution not perfectly working but I managed to come up with a working solution I'm sharing below. Thank you – Angelo Aug 23 '18 at 13:28

3 Answers3

3

It is better to click in the middle of the element than in its corner. Sometimes corners are not clickable. Coordinates x and y of "openwindow" element these are the coordinates of its upper left corner.

I suggest calculating the coordinates of the element's center. To do this, first check the width and height of the element:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver.maximize_window()
url = "https://learn.letskodeit.com/p/practice"
driver.get(url)

open_window_elem = "//button[@id='openwindow']"

x = int(driver.find_element_by_xpath(open_window_elem).location['x'])
y = int(driver.find_element_by_xpath(open_window_elem).location['y'])
width = int(driver.find_element_by_xpath(open_window_elem).size['width'])
height = int(driver.find_element_by_xpath(open_window_elem).size['height'])

action = webdriver.common.action_chains.ActionChains(driver)
action.move_by_offset(x + width/2, y + height/2)
action.click()
action.perform()
drazewski
  • 1,739
  • 1
  • 19
  • 21
2

This is a solution that is based on the last answer available on (Clicking at coordinates without identifying element) that I had to adjust since it was not working on the website I posted in my original code:

# WORKING EXAMPLE 3
# assumptions is I know what coordinate I want to use
# in this example we use x = 253, y = 584
# remember: y = 584 -> it will move down  (a negative value moves up)
zero_elem = driver.find_element_by_tag_name('body')
x_body_offset = zero_elem.location["x"]
y_body_offset = zero_elem.location["y"]
print("Body coordinates: {}, {}".format(x_body_offset, y_body_offset))

x = 253
y = 310

actions = ActionChains(driver)
actions.move_to_element_with_offset(driver.find_element_by_tag_name('body'), -x_body_offset, -y_body_offset).click()
actions.move_by_offset( x, y ).click().perform()

Basically, the body coordinates are not necessarily 0,0 that's why I had to use x_body_offset and y_body_offset.

Angelo
  • 1,594
  • 5
  • 17
  • 50
0

Try this:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver.maximize_window()
url = "https://learn.letskodeit.com/p/practice"
driver.get(url)
open_window_elem = driver.find_element_by_id("openwindow")

# from wherever the mouse is, I move to the top left corner of the broswer
action = ActionChains(driver)
action.move_by_offset(-1000, -1000)    
action.click().perform()

y_coordinate = open_window_elem.location["y"]
x_coordinate = open_window_elem.location["x"]

action = ActionChains(driver)
action.move_by_offset(int(x_coordinate), int(y_coordinate))
action.click().perform()
anish
  • 88
  • 6
  • Thanks Anish, but it still doesn't work on my end, meaning, if it works it should click on the "Open Window" element, but it doesn't. – Angelo Aug 23 '18 at 12:08