selenium: wrong link clicked when window is small - python

I'm writing some automated GUI testing with selenium (Python binding + Firefox driver). On this page we're having problem with, there is button that I want to click but it's at the lower part of the page (I'm selecting the button via id). The default size of the Firefox window isn't large enough to show it. So the actual clicked element is one from the tab bar which is always visible.
If I manually resize the window during the test, it runs smoothly.
This looks like a bug to me TBH. I'm wondering if this is a known feature and a work around exists.

You can use Actions Chains to scroll to the element
actions = ActionChains(driver)
actions.move_to_element(element).perform()
That will make the button visible and you will be able to click on it. You can also use explicit wait to make sure the button is visible.

You can call location_once_scrolled_into_view on the element. It is a property that returns the elements location, but it has the added side-effect of scrolling to the element first if it is not in view already.
element.location_once_scrolled_into_view.

Related

RobotFramework - Unable to click element using selenium library but Execute Javascript click works

I am using RobotFramework to automate one application. I am using the selenium library. For the whole application, selenium keywords "Click Button" and "Click Element" throw an error stating "ElementClickInterceptedException: Message: element click intercepted: Element **** is not clickable at point (376, 289). Other element would receive the click: ..."
I am able to identify the element using ID and it is not under any iframe or shadow-root element. but still I am not able to click on the element. I also tried with adding wait commands to see if it is sync issue but it is not. I tried to click using Action class, mouse move and click etc but did not work.
I tried to take the screenshot of the element using "Capture Element Screenshot" and it captures the screenshot of an empty place however, when I try to locate element in the browser dev tool, it locate it exactly
Only working solution I found is to run "Execute Javascript" keyword to click on the element such as
Execute Javascript $('#id').click();
Question:
Though I am able to make it work, I am curious to know what could be the issue in the application. I am not able to share the application dom code due to restriction. Sorry for that
This means that the element you trying to click is
Out of the visible screen (view port) so you need to scroll the page to make that element accessible or
It is covered by some other element - for example you should open a drop down menu etc or
You trying to click the element while it is still not fully rendered - in this case you need to add some delay to make the element fully rendered and be ready to accept clicks.
Selenium generally imitates human GUI actions. So, as a human user you can't click element inside drop-down without opening it. And you can't click element out of the visible screen. This is why Selenium .click() methods can't click such elements.
JavaScript click is more powerful tool, it can click invisible, covered etc. elements. It doesn't imitate human GUI actions.

How can I click "invisible" reCAPTCHA buttons using Selenium web automation?

I am using Python and Selenium to automate this website: https://prenotami.esteri.it
The script I made fills out a form and then clicks a button to advance to the next page. These actions are carried out using Selenium's find_element_by_xpath() function. Recently, the website added a reCAPTCHA that pops up after the button is clicked, and must be completed before advancing.
I have already written a Python script that is capable of surpassing this type of captchas by using the audio option. However, in this particular website, I am not able to find the xpath to the audio button of the reCAPTCHA. Although there is an iframe that contains the reCAPTCHA, there seems not to be anything inside it.
In the first attached image you can see how this website's reCAPTCHA looks like in HTML, compared to other website that is visible in the second image, where a #document can be seen inside the iframe.
My intention is to run this program using headless Chrome, so I can't relay in any mouse control functions offered by pyautogui for example.
I've been scratching my head around this problem for a while, so any advice is useful. Thanks!
Edit: after some research I have found that this type of reCAPTCHA that doesn't need to check a "I am not a robot" checkbox is called "invisible reCAPTCHA". The captcha only pops up if the detected activity is suspicious (for example clicking too fast). I have tried adding random waits and movements to mimic human behaviour, but the captcha still appears after some tries. Since I don't think there is a way to avoid the captcha from appearing 100% of the times, the question of how to click the buttons using Selenium's find_element_by_xpath() function remains the same. Leaving this as a note just in case someone finds it useful.
Ever tried to use the following function:
add_argument("-auto-open-devtools-for-tabs")
I managed to interact with captcha
If the position is always fixed, you can use PyAutoGUI to move the mouse and click on it
import pyautogui
pyautogui.click(100, 100) # button coordinates
Since, it is in iframe, we need to move our selenium pointing to iframe and then use your xpath.
driver.switch_to.frame("c-la7g7xqfbit4")
capchaBtn = driver.find_element_by_xpath("(//button[#id='recaptcha-audio-button'])[2]")

Finding XPath without using inspecting element?

I am making an automation for download data from a weather institution.
The issue is that in my effort to make it more independent I am trying to make Selenium to Tab keys to a certain spot, so the Browser focus can "Walk" to the download button. When I call the click() function it doesn't do anything. So I tried to Extract the XPath with the function get_attribute("xpath") but it returns None. How I can extract the XPath?
I am going to paste the issue down here:
Bandera=driver.find_element_by_xpath('/html/body/div[2]/div[2]/div/div[3]/div/div/div/div[1]/div/div/div[2]/div/table/tbody/tr[1]/td[1]/div/input')
Bandera.click()
Bandera.click()
## So Here i just select and dis-select a checkbox just to be near the Download button.
actions = ActionChains(driver)
actions.send_keys(Keys.TAB * 1 )
actions.perform()
#Here i just tabed to the button
Accion=driver.switch_to.active_element
#Maybe, here is when i lost the focus of the button?
Descarga_Actual=Accion.get_attribute("xpath")
Thank you and sorry to borrow your time.
To make a click on hover I would use the following sequence:
your_dropdown_locator.click()
dropdown_option = driver.find_element_by_xpath("dropdown option locator")
actions = ActionChains(driver)
actions.move_to_element(dropdown_option)
actions.click().perform()
But, this is the approach that is usually used for dropdowns.
You use: driver.find_element_by_xpath('/html/body/div[2]/div[2]/div/div[3]/div/div/div/div[1]/div/div/div[2]/div/table/tbody/tr[1]/td[1]/div/input') This is the main problem of your code.
If you pasted html code of this dropdown (or button you need to click), people would help you to find a better locator. XPath/CSS must be unique. In your case the locator is very bad.
Also, I see no sense making Bandera.click() two times.
In your case, as I understand, you just need to click the button. So the locator is your main problem.
You need to find the correct locator, to wait till the button is clickable and then to click it.
Another problem in what you are trying to do:
get_attribute("xpath") looks like incorrect expectation of how get_attribute function works. Check at least here what this function means Python Selenium: Find object attributes using xpath

handle invisible elements/popups with selenium in python

is there a way to interact with invisible popups/elements in selenium using python ?
by invisible or hidden , i do not mean the elements with attribute hidden , neither do i mean that these elements are invisible from the user.
these invisible elements are those that do not appear in the inspect element section
for example: on a webapp screen where right click opens up a small options window which which has different options related to that webapp and its not the traditional browser right click options popup
by default this options popup does not appear in the inspect element , and it only appears when user right clicks on a certain section of the screen, the contents of this options popup differs depending on which setion of the screen the right click was performed on, and it disappears as soon as another click happens anywhere , even if i click on the inspect element section the options popup will disappear.
is there any way to deal with this sort of popup?
Edit 1: when i right click on the screen while the inspect element option is selected something related to the right click popup appears in the inspect element window , but as soon as i click on it to see the element ids , it disappears from the inspect element window
To search xpath of such dynamic elements use DOM break points:
And select break on subtree modification. Now all changes will break and pause the webpage rendering
Click resume execution or press f8 till your pop gets displayed

How to click on an element based on its coordinates with selenium webdriver

So, the web app we're developing has a TV/PC mode, and i'm testing the ability to transit between these two modes. `
def pc_to_tv(self):
pc_to_tv = self.driver.find_element_by_xpath(
'html/body/div[1]/div/topbar/header/div[2]/div[2]/div[1]/button[1]')
pc_to_tv.click()
def tv_to_pc(self):
tv_to_pc = self.driver.find_element_by_xpath(
'html/body/div[1]/div/topbar/header/div[2]/div[2]/div[1]/button[2]')
tv_to_pc.click()`
The problem is, when i switch from pc to tv, the screen "zooms in", making the button appear in the same place it would be without the zoom. so, i can't click on the button with my 'tv_to_pc' method, 'cause instead on clicking on the actual button, it clicks where the button should be.
So, the solution i found was clicking on the button with coordinates, that way i'll actually click on the place i want, instead of clicking on an unclickable place like i was doing.
The thing is, i don't know how to do this, and need help on this matter.
I would suggest that you just click the button using JavaScriptExecutor. It will click it no matter where it is on the page. See How to execute a javascript in a Python webdriver and other questions for more info. The general format is
element = driver.find_element_by_id("someId")
driver.execute_script("arguments[0].click();", element)
Also... you don't want to use XPaths like that. Any XPath that starts at the HTML tag or is more than just a few levels deep is going to be very brittle. Do some googling on selenium xpaths and read some guides for more info.
try moveToElement and then perform click
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
new Actions(driver).moveToElement(element, x, y).click().perform();
x is xoffset
y is yoffset
Please see that if you use Javascript for click its not going to be native click.

Categories