Same Element becomes unclickable during iteration - python

I'm using Selenium Python to do the same action for different users and the flow is as follows,
1- the webpage show list of user ids
2- I search for 1 user-id (Iteration)
3- I click on the check box next to the user-id
4- I click on done
My issue is with the check box, it is clickable in the first row of iteration but then it becomes unclickable with the next row.
Checkbox Element:
<input type="checkbox" class="ant-checkbox-input" value="" xpath="1">
I have also tried ActionChains but I got the error: stale element reference: element is not attached to the page document
Thank you

the input checkbox might be in disable state or some javascript load is yet to happen before checkbox become availabe.
try this code:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.XPATH,"//tbody/tr[1]/td[1]/span[1]/label[1]/span[1]/input[1]"))).click()
another problem might be xpath changes depending on user you logged in.
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.XPATH,'//input [#type="checkbox"]'))).click()
above code will work only if you have 1 checkbox.
This code will try to click all the check boxes present on page, if this works we could narrow down XPath.
els=driver.find_elements_by_xpath('//input [#type="checkbox"]')
for el in els:
try:
el.click()
except:
pass

Related

Python Selenium ID Tags change each time i refresh the page

I am currently trying to automate a data entry process. Every time I refresh the page the ID tags change and make it impossible. I read that I can use CSS selectors or a possible xpath using tags that don't change. It seems that only the ID tags are the problem.
Below is the HTML code for the button. Every time i try and use the CSS selector i got a no such element exception. I think I am doing it wrong. Please help.
<button type="button" class="dark button secondary" data-automation-id=
"btn-footer-save" data-dojo-attach-event="onclick:saveAndStayPressed"
data-qbo-bind="visible:shouldShowSaveAndStayButton" style>Save</button>
Try this:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = new WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Save')]"))).click()
The element gets wrapped in a WebDriverWait until it is interactable, in this case clickable

cannot find button element, selenium, python

Already try by xpath, class_name, name, tag_name, everything! but cannot find this element, the html code llok like this.
<button class ="btn btn-submit" type="submit" class="btn btn-submit" name="submitBtn">Crear cuenta</button>
I don't know why can't find the element, here an example of my code triying to find the element
self.driver.find_element_by_xpath("//*[#id='app']/div/footer/button").click()
As the web site you passed has a load screen the element you want to grab is not available to interaction.
For that you can use the selenium web driver Expected Conditions.
Here an use example on how to use.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
...
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "dtListaEntidade")))
# do your stuff with elements
Im my example the element I want to grab is the dtListaEntidade.
I'm telling the webdriver to wait the present of that element for
10 ms
check if the element is available
do 1. again
This waits up to 10 seconds before throwing a TimeoutException unless it finds the element to return within 10 seconds.
WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully.
Here is the documentation from selenium docs waits

selecting a drop down item from a <div> menu selenium python

So I'm a little stuck! I'm trying to select an item from the 'All reviews' drop down however it doesn't interact like a where each item I could select the element of and then click it.
Instead the acts like an element where upon its label changing different results are displayed. Does anyone know how I could select an element from this menu?
For example, making the menu select the "Google" tab from the drop down.
for reference:
https://www.google.com/maps/place/Hilton+London+Bankside/#51.5056536,-0.1033145,17z/data=!3m1!4b1!4m10!3m9!1s0x487604af6af74cc7:0x6c4cb3cbe03e95bf!5m2!4m1!1i2!8m2!3d51.5056536!4d-0.1011258!9m1!1b1
Induce WebDriverWait() and element_to_be_clickable() and click on the All reviews div element to open up the dropdown menu and then select the items based on text.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver=webdriver.Chrome()
driver.get("https://www.google.com/maps/place/Hilton+London+Bankside/#51.5056536,-0.1033145,17z/data=!3m1!4b1!4m10!3m9!1s0x487604af6af74cc7:0x6c4cb3cbe03e95bf!5m2!4m1!1i2!8m2!3d51.5056536!4d-0.1011258!9m1!1b1")
#Dropdown text provide here
selectItem='Agoda'
#First click on the All reviews element to open up the dorpdown element
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div[aria-label='All reviews']"))).click()
#Select item from menu dropdown by text
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//div[#role='menuitem']//div[text()='"+ selectItem +"']"))).click()
Browser snapshot: after execution
At this particular webpage elements are appearing,many of them don't just exist in the DOM content, you should use WebDriverWait method to wait until the specific element gets located.
For example, let's select "Google" as you asked:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("the google link here, it's too big to paste it")
#Waiting until dropdown is visible , there are two dropdowns, taking the first one
menu = WebDriverWait(driver,5).until(EC.visibility_of_element_located((By.XPATH, "
(//div[#class='cYrDcjyGO77__container'])[1]")))
menu.click()
#Waiting untill menu items is visible then selecting the second element - Google
item = WebDriverWait(driver,5).until(EC.visibility_of_element_located((By.XPATH, "
(//div[#role='menuitem'])[2]")))
item.click()
What you can do is to find your dropdown and then list thru all the options and select your one.
Here is how I'm doing it
el = driver.find_element_by_id("dropdown_id")
for option in el.find_elements_by_tag_name('option'):
if "GB" in option.text:
option.click() # select() in earlier versions of webdriver
break
I'm selecting the dropdown that have Value of the state "GB".

can't click button or submit form using Selenium

I'm trying to use Selenium w/ Python to click on answers to problems posted at a tutoring site, so I can take tests over the command line.
I enter the following:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver.get('https://www.varsitytutors.com/sat_critical_reading_diagnostic_1-problem-10821')
(an annoying popup comes up at this point -- we can ignore that for now)
Answers on the page are embedded in forms like this:
<div class="question_row">
<form class="button_to" method="post" action="/problem_question_answers/save_answer?answer_id=539461&problem_id=5065&qotd=false&question_id=10821">
<input id="answer_539461" class="test_button" type="submit" value="select" /><input type="hidden" name="authenticity_token" value="LE4B973DghoAF6Ja2qJUPIajNXhPRjy6fCDeELqemIl5vEuvxhHUbkbWeDeLHvBMtEUVIr7okC8Njp4eMIuU3Q==" /></form>
<div class="answer">
<p>English dramatists refused to employ slang in their work.</p>
</div>
<div style="clear:both"></div>
</div>
My goal is to click an answer such as this one in order to get to the next question using Selenium.
I thought it might be as easy as doing this:
answer_buttons=driver.find_elements_by_class_name('test_button')
answer_buttons[1].click()
But I get error messages saying that the element is out of the frame of the driver.
I've also tried submitting the form, which doesn't produce an error message:
answer_forms=driver.find_elements_by_class_name('button_to')
answer_forms[1].submit()
But it redirects to a different url that doesn't load:
http://www.varsitytutors.com/sat_critical_reading_diagnostic_1-problems-results-d9399f1a-4e00-42a0-8867-91b1c8c9057d
Is there any way to do this programmatically, or is the website's code going to prevent this?
Edit:
With some help I was able to click the button once initially. But an identical submit button (by xpath) for the next question remains unclickable. This is the code I'm presently using:
driver.get('https://www.varsitytutors.com/practice-tests')
# click subject
subject=driver.find_element_by_xpath('/html/body/div[3]/div[9]/div/div[2]/div[1]/div[1]')
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[9]/div/div[2]/div[1]/div[1]')))
subject.click()
# select specialty
specialty=driver.find_element_by_xpath('/html/body/div[3]/div[9]/div/div[2]/div[2]/div[1]/div[2]/a[4]')
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[9]/div/div[2]/div[2]/div[1]/div[2]/a[4]')))
specialty.click()
# select test
taketest=WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[8]/div[3]/div[1]/div[1]/a[1]')))
driver.execute_script("arguments[0].click();", taketest)
# click away popup
button=WebDriverWait(driver,5).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks')]")))
button.location_once_scrolled_into_view
button.click()
# select first choice
choice=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[7]/div[1]/div[3]/div[1]/form/input[1]')))
driver.execute_script("arguments[0].click();", choice)
I repeat this code again over the next few lines. It has no effect, however; the drive stays on question two and the next few clicks don't work...
choice=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[7]/div[1]/div[3]/div[1]/form/input[1]')))
driver.execute_script("arguments[0].click();", choice)
choice=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[7]/div[1]/div[3]/div[1]/form/input[1]')))
driver.execute_script("arguments[0].click();", choice)
Try the following code.This will handle pop-up and click on the select button.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
driver=webdriver.Chrome()
driver.get('https://www.varsitytutors.com/sat_critical_reading_diagnostic_1-problem-10821')
driver.maximize_window()
button=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks, Start The Test')]")))
button.location_once_scrolled_into_view
button.click()
eleQuestions=WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'input.test_button')))
driver.execute_script("arguments[0].click();", eleQuestions[2])
button=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks')]")))
button.location_once_scrolled_into_view
button.click()
Please note: you can change the indexes from 2 to 6.
Snapshot:
If you would like to select any particular Question as you mentioned then try below code.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
driver=webdriver.Chrome()
driver.get('https://www.varsitytutors.com/sat_critical_reading_diagnostic_1-problem-10821')
driver.maximize_window()
button=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks, Start The Test')]")))
button.location_once_scrolled_into_view
button.click()
eleQuestions=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//div[./p[text()='English dramatists refused to employ slang in their work.']]/parent::div//input[1]")))
driver.execute_script("arguments[0].click();", eleQuestions)
button=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks')]")))
button.location_once_scrolled_into_view
button.click()

python selenium unable to click on a tag

I'm trying to click on this button shown below named “Segment Metrix 2.0 Consumer Target Profile report“
and I found corresponding HTML as shown below.
I tried to write code as below:
elem = driver.find_elements_by_xpath("//*[contains(text(), 'Segment Metrix 2.0 Consumer Target Profile report ')]")
print (elem)
it gives me:
[<selenium.webdriver.remote.webelement.WebElement (session="daf65f4e5ed0485027d04eed8db8aca7", element="0.8079987809618281-1")>]
But I can't click on it by adding elem[0].click(), it throws me an "element not visible" error. What should I do?
The problem is that the element has to be visible. It means that even if it's in html, it's not enough, it has to been visible from the browser. Try to click on the dropdown first in order to see its elements and only than click on one of the elements. Also, after clicking on the dropdown, don't forget to wait until your element will be seen, either explicitly or implicitly.
Do you sure you need to click on it? If it is just an object with an url, exact the url and use driver.get(url)
Try to wait until element become visible:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as wait
wait(driver, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, "Segment Metrix 2.0 Consumer Target Profile report"))).click()
You can wait for the element to be visible
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
elem = driver.find_elements_by_xpath("//*[contains(text(), 'Segment Metrix 2.0 Consumer Target Profile report ')]")
WebDriverWait(driver, 10).until(EC.visibility_of(elem[0]))
elem[0].click()

Categories