Check AngularJS checkbox with Selenium - python

HTML Source here
It seems trivial, but after hours of attempts I cannot manage to check this checkbox using Selenium. I am able to select the element no problem, and have even been able to 'highlight' (see code snippet below) it by sending Keys.RETURN to the element, but on attempting to click it, nothing happens. Perhaps someone has an idea?
What I have tried already:
Using with WebDriverWait
Using multiple and different combinations of .click()/.send_keys(Keys.RETURN)
Just about every combination of XPATH/css selector/id/name/classname/text that Selenium would accept for the element, and all of its children and most of its parents (including spans/labels, and the text inside the label itself).
Directly clicking the element/label coordinates using actions (nothing happens, even when I can 100% confirm it is clicking the right spot by using context_click()).
Using execute_script to change the "checked" attribute to True (the checkbox appears checked, but it is clear it is only client side as a box that is supposed to render when it is actually clicked doesn't).
Using execute_script to change the class to 'ng-valid ng-not-empty ng-dirty ng-valid-parse ng-touched'
Here is the code that I feel got me the closest (it is 'highlighting' the box as seen here)
browser.find_element(By.ID, "sp_formfield_none_of_the_above").send_keys(Keys.RETURN)

Managed to solve it after another while of testing. Hopefully this helps someone in the future. I had to use JS to execute .click() on the checkbox element. In retrospect, I should have tried this solution sooner. See code snippet:
cb_none = browser.find_element(By.ID, 'sp_formfield_none_of_the_above')
browser.execute_script("arguments[0].click();", cb_none)

Related

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

Selenium not detecting an element

So I'm coding this bot to join my school classes for me using selenium and I'm facing this issue where it goes to my conferences page and it waits for a join button to appear and press on it. At first, it wouldn't be able to find it so I scratched the idea of time and I made sure that when it opens the page the join button will be there so I did that and even put this line of code just to make sure
join=WebDriverWait(driver,30).until(EC.presence_of_element_located((By.XPATH,"//span[contains(text(),'Join')]")))
yet it still can't find the join button either press it even though it's visible by the eye I will link the page source under in a link if you can just tell me how to find it also I cant use the href method since it isn't stored like that it's just stored like this
https://i.stack.imgur.com/ldxY7.png
so I'm really confused it's almost like this is an invisible element its funny because even when I do get an error I use control F on inspect element to check if I used correct XPATH and I always find it so I don't see why selenium cant please help I think I just missed something I just don't know what.
Page Source
Check the presence of the element by looping and checking the presence_of_element_element_located multiple times with 2/3 seconds delay added between every consecutive check.
An analogy from python selenium-
for i in range(5):
l= driver.find_element_by_css_selector("#js-gdpr")
time.sleep(5)
OR
Iterate over all the elements under the parent div and verify it using unique text/color and access it.
I think you are trying to do Google meet automation. In that website the "join now" button is declared as a dynamic path so, you can use the library pyautogui
impor pyautogui as pg
for i in range(5):
pg.press('tab')
time.sleep(2)
pg.press('enter')
This code will help you to find the join now button and to click it.

Selenium Python: Census ACS Data- unable to select Download button in window

I am attempting to scrape the Census website for ACS data. I have scripted the whole processes using Selenium except the very last click. I am using Python. I need to click a download button that is in a window that pops when the data is zipped and ready, but I can't seem to identify this button. It also seems that the button might change names based on when it was last run, for example, yui-gen2, yui-gen3, etc so I am thinking I might need to account for this someone. Although I normally only see yui-gen2.
Also, the tag seems to be in a "span" which might be adding to my difficulty honing in on the button I need to click.
Please help if you can shed any light on this for me.
code snippet:
#Refine search results to get tables
driver.find_element_by_id("prodautocomplete").send_keys("S0101")
time.sleep(2)
driver.find_element_by_id("prodsubmit").click()
driver.implicitly_wait(100)
time.sleep(2)
driver.find_element_by_id("check_all_btn_above").click()
driver.implicitly_wait(100)
time.sleep(2)
driver.find_element_by_id("dnld_btn_above").click()
driver.implicitly_wait(100)
driver.find_element_by_id("yui-gen0-button").click()
time.sleep(10)
driver.implicitly_wait(100)
driver.find_element_by_id("yui-gen2-button").click()
enter image description here
enter image description here
Instead of using the element id, which as you pointed out varies, you can use XPath as Nogoseke mentioned or CSS Selector. Be careful to not make the XPath/selector too specific or reliant on changing values, in this case the element id. Rather than using the id in XPath, try expressing the XPath in terms of the DOM structure (tags):
//*/div/div/div/span/span/span/button[contains(text(),'Download')]
TIL you can validate your XPath by using the search function, rather than by running it in Selenium. I right-clicked the webpage, "inspect element", ctrl+f, and typed in the above XPath to validate that it is the Download button.
For posterity, if the above XPath is too specific, i.e. it is reliant on too many levels of the DOM structure, you can do something shorter, like
//*button[contains(text(),'Download')]
although, this may not be specific enough and may require an additional field, since there may be multiple buttons on the page with the 'Download' text.
Given the HTML you provided, you should be able to use
driver.find_element_by_id("yui-gen2-button")
I know you said you tried it but you didn't say if it works at all or what error message you are getting. If that never works, you likely have an IFRAME that you need to switch to.
If it works sometimes but not consistently due to changing ID, you can use something like
driver.find_element_by_xpath("//button[.='Download']")
On the code inspection view on Chrome you can right click on the item you want to find and copy the xpath. You can they find your element by xpath on Selenium.

Rewrite click() method in Selenium 2 (python)

I'm using Seleniun 2 webdriver (python) to run auto tests on IE browser.
One of major bugs in IE webdriver is that click() method does not work in 100% of cases. It happens sometimes when IE browser cannot set/looses focus on element. So, there's a workaround i googled to solve the problem- first the parent element must be clicked/selected. After that click() on the current element always works.
I would like to add my own method, named for ex. ieclick() that would do something like:
element = driver.find_element_by_id('id')
parentElement = element.find_element_by_xpath('..')
parentElement.click()
element.click()
Instead of writing all this code i would like to make:
driver.find_element_by_id('id').ieclick()
But i don't know how to implement this. I'm lost in Selenium modules code. I know that selenium class has click() method but i can't understand how can i rewrite it/add my own and make it useble for all this find_element_by_id, find_element_by_xpath etc.
Can someone help me to understand this implementation or maybe paste a link to some sort of explanation/example/lesson ?
The only reason that an element would not receive a click is because :
The element is disabled.
The element is invisible (therefore, cannot interact with it)
The element is not listening for any clicks (not binded)
My guess is that your "inconsistency issue" is coming form the third reason.
Consider the following:
<a href="dosomething">
<span id="spanclick">Click me</span>
</a>
Doing driver.find_element_by_id("spanclick").click() would not work, because it's the <a> element that is receiving the click, not the <span>.
It's your responsibility as the test writer to determine which element is receiving the click. My suggestion would be use debugging anytime you are in doubt. I've actually had a scenario where an <li> was receiving the actions of the mouse, not the <a>. By using Watch Expressions you are able to find what element is receiving the actions.
Seems i was exaggerating the difficulty.
selenium\webdriver\remote\webelement.py
Added code right after native click() method:
def ieclick(self):
"""2013-12-27. Surely clicks the element in IE."""
parent = self.find_element(by=By.XPATH, value='..')
parent._execute(Command.CLICK_ELEMENT)
try:
self._execute(Command.CLICK_ELEMENT)
except:
pass

Categories