Selenium python- Is it possible to draw a circle around clicked GUI elements?
Question:
I am new to selenium and I am wondering if I could draw a red circle around anything my selenium script clicks before taking a screenshot of the page (I already know how to do the screenshot). I think that I could utilize:
ele.location
and
ele.size
to draw a circle, but I just do not know how. Any input is appreciated.
Answers:
You can do the following. Let say you have a button
You can select it as
button = driver.find_element('xpath', '//button')
And then outline it
outline_style = driver.execute_script("return arguments[0].style.outline", button) # Get initial outline style
driver.execute_script("arguments[0].style.outline = '#f00 solid 5px';", button) # Change outline style
button.click()
driver.execute_script("arguments[0].style.outline = arguments[1];", button, outline_style) # Set back initial outline style
Yes, it’s definitely not a circle, but if you need to somehow make a focus on element you can use this approach
Here is one other solution using canvas. In the below code for this same page, we are trying to click on the bookmark button. Check the video the element that we are trying to cllick is colored blue and then clicked.
So basically what we have done here is created a canvas on the top of our page, got the location of the element, clicked on it to show the blue circle and then we click on the element after removing the canvas. Its important to remove the canvas before doing the actual click as canvas is overlayed on top of our page.
In the below code, all you need to change is the line element_to_click = driver.find_element(By.CSS_SELECTOR, '.js-bookmark-btn.s-btn.s-btn__unset.c-pointer.py4.js-gps-track')
if you want to click on some other element on the page.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
# REPLACE YOUR CHROME PATH HERE
chrome_path = r"C:UsershpoddarDesktopToolschromedriver_win32chromedriver.exe"
def click_on_element(element):
loc_dict = element.location
circle_x, circle_y = loc_dict['x'] + element.size['width']//2, loc_dict['y'] + element.size['height']//2
locX, locY = loc_dict['x'], loc_dict['y']
createCircle = f'''
document.body.appendChild(myCanvas);
createCircle = function (event) {{
var x = {circle_x};
var y = {circle_y};
ctx.fillStyle = "#2980b9";
ctx.beginPath();
ctx.arc(x, y, 10, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
setTimeout(function () {{ ctx.clearRect(0, 0, myCanvas.width, myCanvas.height) }}, 2000);
}}
myCanvas.addEventListener("click", createCircle, true);
'''
driver.execute_script(createCircle)
elementFromPoint = f'''el = document.elementFromPoint({locX}, {locY});
el.click();'''
driver.execute_script(elementFromPoint)
removeCanvasAndClick = f'''
setTimeout(function () {{
document.body.removeChild(myCanvas);
myCanvas.removeEventListener('click', createCircle, true);
el = document.elementFromPoint({locX}, {locY});
el.click();
}}, 1000);
'''
driver.execute_script(removeCanvasAndClick)
url = 'https://stackoverflow.com/questions/73197807/selenium-python-is-it-possible-to-draw-a-circle-around-clicked-gui-elements'
s = Service(chrome_path)
driver = webdriver.Chrome(service=s)
driver.get(url)
driver.maximize_window()
# Say, we want to click on bookmark
element_to_click = driver.find_element(By.CSS_SELECTOR, '.js-bookmark-btn.s-btn.s-btn__unset.c-pointer.py4.js-gps-track')
#Create canvas
canvas = '''
myCanvas = document.createElement('canvas');
myCanvas.id = 'canvas';
myCanvas.style.position = 'absolute';
myCanvas.style.left = "0px";
myCanvas.style.top = "0px";
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
ctx = myCanvas.getContext('2d');
'''
driver.execute_script(canvas)
# Circles the element that you want to click and then clicks on it
click_on_element(element_to_click)
Check out the youtube video below, for the run on this same page.
I am new to selenium and I am wondering if I could draw a red circle around anything my selenium script clicks before taking a screenshot of the page (I already know how to do the screenshot). I think that I could utilize:
ele.location
and
ele.size
to draw a circle, but I just do not know how. Any input is appreciated.
You can do the following. Let say you have a button
You can select it as
button = driver.find_element('xpath', '//button')
And then outline it
outline_style = driver.execute_script("return arguments[0].style.outline", button) # Get initial outline style
driver.execute_script("arguments[0].style.outline = '#f00 solid 5px';", button) # Change outline style
button.click()
driver.execute_script("arguments[0].style.outline = arguments[1];", button, outline_style) # Set back initial outline style
Yes, it’s definitely not a circle, but if you need to somehow make a focus on element you can use this approach
Here is one other solution using canvas. In the below code for this same page, we are trying to click on the bookmark button. Check the video the element that we are trying to cllick is colored blue and then clicked.
So basically what we have done here is created a canvas on the top of our page, got the location of the element, clicked on it to show the blue circle and then we click on the element after removing the canvas. Its important to remove the canvas before doing the actual click as canvas is overlayed on top of our page.
In the below code, all you need to change is the line element_to_click = driver.find_element(By.CSS_SELECTOR, '.js-bookmark-btn.s-btn.s-btn__unset.c-pointer.py4.js-gps-track')
if you want to click on some other element on the page.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
# REPLACE YOUR CHROME PATH HERE
chrome_path = r"C:UsershpoddarDesktopToolschromedriver_win32chromedriver.exe"
def click_on_element(element):
loc_dict = element.location
circle_x, circle_y = loc_dict['x'] + element.size['width']//2, loc_dict['y'] + element.size['height']//2
locX, locY = loc_dict['x'], loc_dict['y']
createCircle = f'''
document.body.appendChild(myCanvas);
createCircle = function (event) {{
var x = {circle_x};
var y = {circle_y};
ctx.fillStyle = "#2980b9";
ctx.beginPath();
ctx.arc(x, y, 10, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
setTimeout(function () {{ ctx.clearRect(0, 0, myCanvas.width, myCanvas.height) }}, 2000);
}}
myCanvas.addEventListener("click", createCircle, true);
'''
driver.execute_script(createCircle)
elementFromPoint = f'''el = document.elementFromPoint({locX}, {locY});
el.click();'''
driver.execute_script(elementFromPoint)
removeCanvasAndClick = f'''
setTimeout(function () {{
document.body.removeChild(myCanvas);
myCanvas.removeEventListener('click', createCircle, true);
el = document.elementFromPoint({locX}, {locY});
el.click();
}}, 1000);
'''
driver.execute_script(removeCanvasAndClick)
url = 'https://stackoverflow.com/questions/73197807/selenium-python-is-it-possible-to-draw-a-circle-around-clicked-gui-elements'
s = Service(chrome_path)
driver = webdriver.Chrome(service=s)
driver.get(url)
driver.maximize_window()
# Say, we want to click on bookmark
element_to_click = driver.find_element(By.CSS_SELECTOR, '.js-bookmark-btn.s-btn.s-btn__unset.c-pointer.py4.js-gps-track')
#Create canvas
canvas = '''
myCanvas = document.createElement('canvas');
myCanvas.id = 'canvas';
myCanvas.style.position = 'absolute';
myCanvas.style.left = "0px";
myCanvas.style.top = "0px";
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
ctx = myCanvas.getContext('2d');
'''
driver.execute_script(canvas)
# Circles the element that you want to click and then clicks on it
click_on_element(element_to_click)
Check out the youtube video below, for the run on this same page.