I have web page, where the user needs to upload a list of documents and only after which the Submit button is enabled.
I am using python selenium for this automation. My program is able to upload the documents but is unable to click on the Submit button after it is enabled.
I tried this:
element = WebDriverWait(driver, 10000).until(EC.element_to_be_clickable("(//button[#type='submit'][2]"))
element.click()
but it is not working, as the jobs are not submitted in the front end
Change code to be:
element = WebDriverWait(driver, 100).until(
EC.element_to_be_clickable((By.XPATH, "//input[contains(#ng-click,'SubmitJob')]")))
element.click()
So we now are waiting for up to 100 seconds (instead of 3 hours), and we are passing a tuple argument (By.XPATH, "//input[contains(#ng-click,'SubmitJob')]") to EC.element_to_be_clickable, which is what it expects.
Cannot comment on the correctness of the xpath though, but please check it as well.
Edit: changed the xpath based on comment. There are many ways to express that xpath. I would prefer ng-click over class attribute, since classes may change; action, however, will likely stay the same. But if you choose using classes, I still suggest going with something like
//input[contains(#class,'btn') and contains(#class,'form-control')]
because you never know if the order of classes will change.
Related
I came across this problem while automating task with Selenium.
What was the code execution process?
So first of all there're two functions inside seleniumtest.py :
getGateway() and restartRouter().
Let's focus on restartRouter() function as it contains code related to selenium, and getGateway() function was just function that I used in restartRouter() just like this: driver.get(getGateway()).
First of all, what was happening is following:
Start browser and open provided url;
Find elements username and password
Enter username and password;
Find Login element
Click Login;
Find another button
Click on another button
...
What is the problem?
So, the problem start occuring on step 6, just after clicking Login button (See code execution process, step 6).
After it clicks on login button, it loads new page (it doesn't open it in new tab), and after that it didn't want to work.
What have you tried to do to solve the problem
First thing that came up to mine mind was to use driver.wait(5) just after clicking on login, which didn't work.
I've also tried to check if any other element on that page will result in action .click()
After that, I've tried Waits - SELENIUM WAITS ; which also didn't work. I tried two possible options: driver.implicitly_wait(10) and WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,"//*[#id=\"mmManagDiag\"]")). It also gave me errors how my USB Device isn't working while using explicit waits.
None of these worked.
What worked for me?
After working around it came up to my mind to try with time.sleep(3) and suddenly it worked.
My final question
So, I am wondering why Selenium couldn't find any element on that page before I used time.sleep()?
And isn't selenium waits and time.sleep() almost the same thing?
Code
driver = webdriver.Chrome('./chromedriver')
driver.get(getGateway())
#Frm_Username
username = driver.find_element(By.NAME,'Frm_Username')
username.clear()
username.send_keys("user")
#Frm_Password
passwrd = driver.find_element(By.NAME,"Frm_Password")
passwrd.clear()
passwrd.send_keys("user")
#passwrd.send_keys(Keys.RETURN)
driver.find_element(By.XPATH,"//*[#id=\"LoginId\"]").click()
time.sleep(3)
driver.find_element(By.XPATH,"//*[#id=\"mmManagDiag\"]").click()
time.sleep(3)
driver.find_element(By.XPATH,"//*[#id=\"mmManagDevice\"]").click()
time.sleep(3)
driver.find_element(By.XPATH,"//*[#id=\"Btn_restart\"]").click()
time.sleep(3)
driver.find_element(By.XPATH,"//*[#id=\"confirmOK\"]").click()
driver.quit()
Waiting for the elements presence might be not enough to click on it.
Try to wait for element to be clickable.
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "your xpath value"))
).click()
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
I'm trying to make a bot that logs inside my account.
After inserting psw and username I make my bot clicking on "I'm not a robot" recaptcha checkbox.
After flagging the Recaptcha checkbox it could randomly appear a second Recaptcha, this time one with images. Fine, I could solve it by using the audio to text method. The issue is that this Recaptcha appears randomly.
I used an explicit wait but it gets bypassed and doesn't give me any errors.
Here's my code
#solve first recaptcha (I'm not a robot)
driver.switch_to_frame(element) #element = captcha frame already found
recaptcha = driver.find_element_by_xpath('//*[#id="recaptcha-anchor"]/div[1]')
driver.execute_script("arguments[0].click();",recaptcha)
_delay()
driver.switch_to_default_content()
#if an image captcha frame appears click on the audio button
try:
recaptcha_frame = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH,
'/html/body/div/div/div[3]/div[2]/div[1]'))).find_element_by_tag_name('iframe') #locating the recaptcha image frame
driver.switch_to_frame(recaptcha_frame)
audio_button = driver.find_element_by_class_name('rc-button goog-inline-block rc-button-audio')
driver.execute_script("arguments[0].click();",audio_button)
except:
pass
If i would have used driver.quit() instead of pass it would have closed the session. My aim is to click on the audio_button. Any wonder on why this explicit wait doesn't work?
I think you do not need using explicit wait if you already using implicit. This may be the first problem. For the implicit wait the code should look similar to this:
try:
recaptcha = driver.find_elements_by_xpath("Your recaptcha_frame stable xpath")
recaptcha.click()
except NoSuchElementException:
pass
Also, /html/body/div/div/div[3]/div[2]/div[1] is not reliable locator. Change it to the stable one. In your code if this locator is not found, nothing will happen. Use a better exception type to understand the reason.
If you go with explicit wait, try changing presence_of_element_located to visibility_of_element_located
But still, locator is the main problem in your code.
Also, I have doubts you will be able to pass recaptcha.
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.
I'm trying to find Selenium Xpath for element in the input tag. But, I'm not getting the value. I have used following code :
WebDriverWait(driver,
10).until(EC.presence_of_element_located((By.TAG_NAME("input"))))
searchBox = driver.findElement(By.tagName("input"))
But, it is not working!!!
You can use a more specific finder like By.ID this will look for an id on the web page since id is unique this should work better.
The id of the search box is input_0 you can look it up via the inspect element from your browser, or via the development tools usually hidden under the F12 key
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID("input_0"))))
searchBox = driver.find_element_by_id('input_0')
Have a read over here here for more information about locators.
Let me know if it helped and if you learned something today :)
Here is the Answer to your Question:
I don't see any issue with your line of code or locator. But you may consider trying the line of code below along with a few points:
The URL https://paytm.com/shop takes a bit of time to load properly, so we need to wait for the HTML DOM to be completely loaded. Using ExplicitWait is the right choice.
You can consider increasing the time limit from 10 to 20 seconds.
Instead of TAG_NAME locator consider using XPATH locator.
Your line of code will look like:
search_box = WebDriverWait(browser, 20).until(
EC.presence_of_element_located((By.XPATH, "//input[#id='input_0']"))
)
search_box.click()
Let me know if this Answers your Question.