Using selenium to fill in a form with random number - python-3.x

I am having trouble filling the form which using java creates a pair of random numbers and upon entering the right answer one can proceed:
<div class="form-group has-feedback">
<label for="captcha" class="..." id="captchaOperation">6 + 20 =</label>
I want to extract the two numbers, add them up (it is mainly the sum operation, but generic solutions are also appreciated).
I have used different combinations with send_keys, e.g.:
mathcaptcha = action.send_keys("""document.querySelectorAll("span#captchaOperation").firstChild.nodeValue;""")
print(mathcaptcha)
which all return:
<selenium.webdriver.common.action_chains.ActionChains object at 0x11238cd68>
Then I used the execute_script with few different scripts, e.g.:
mathcaptcha = driver.execute_script("""document.getElementById("captchaOperation");""")
print(mathcaptcha)
and got None printed out.
How could I get the 6 + 20 out of the code or 26 as final result?

To make execute_script return a value to you, use return :
mathcaptha = driver.execute_script("return document.getElementById('captchaOperation').textContent;")
print(mathcaptha)

You can try the following code:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
mathcaptha = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "captchaOperation"))).text.replace(" =", "")
print(eval(mathcaptha))

As per the HTML you have shared to extract 6 + 20 you can use either of the following solution:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
#other lines of code
captcha_text = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//label[#id='captchaOperation' and #for='captcha']"))).get_attribute("innerHTML")
print((captcha_text.replace("=", "")), eval(captcha_text.replace("=", "")))

Related

Working with Python and Selenium Chrome Driver

I was hoping for maybe some clarification or suggestions on how to get selenium working with a href I have tried selecting it by pretty much every element possible.
My end goal would be to loop through each "Case Number" and click on it and once finished add each one to a list, then if it is not in the list click on it until finished.
<td class="x-grid3-col x-grid3-cell x-grid3-td-CASES_CASE_NUMBER " style="width:172px;" tabindex="0"><div class="x-grid3-cell-inner x-grid3-col-CASES_CASE_NUMBER" id="5005a00001rezYE_CASES_CASE_NUMBER">0000000</div></td>
<div class="x-grid3-cell-inner x-grid3-col-CASES_CASE_NUMBER" id="5005a00001rezYE_CASES_CASE_NUMBER">0000000</div>
0000000
clicky = driver.find_element_by_css_selector("//div[#id='5005a00001rezYE_CASES_CASE_NUMBER']").click()
I have also tried with this element(which would make it easier for what I am trying to do)
<span>Edit</span>
<span>Edit</span>
clicky = driver.find_element_by_xpath("span[contains(text(),'Edit')]").click()
clicky = driver.find_element_by_css_selector("span[Edit]").click()
I'm not sure this locator is correct and unique, but you can try this:
clicky = driver.find_element_by_xpath("//span[contains(text(),'Edit')]").click()
Possibly you will have to add some delay / wait before accessing this element.
The simplest way is to add a delay
time.sleep(5)
clicky = driver.find_element_by_xpath("//span[contains(text(),'Edit')]").click()
While recommended approach is to add an explicit wait, like this:
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//span[contains(text(),'Edit')]"))).click()
For this you will need to add these imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Unable to get web element since XPATH is dynamically changing

<div dojoattachpoint="titleNode" class="dijitTitlePaneTextNode" tabindex="0">Transfer ( XXXXX.YYYYYY#ABCD.COM 10-Aug-2021 02:24:39 PM GMT+05:30 ) Top Bottom</div>
The above snippet I got from inspect element on Google Chrome. I am want to get this "Transfer ( XXXXX.YYYYYY#ABCD.COM 10-Aug-2021 02:24:39 PM GMT+05:30 ) " value to be printed in output.
The problem is that XPATH get changed dynamically every time.
I have already tried the below, but it did not work.
get_div = driver.find_element_by_class_name("dijitTitlePaneTextNode")
get_div = driver.find_element_by_xpath('//a[contains(text(), "Transfer ( ")]')
get_div = driver.find_elements_by_xpath('//div[#class = "dijitTitlePaneTextNode"]')
Try this CSS selector and see if that helps:
div[dojoattachpoint='titleNode']
in code:
get_div = driver.find_element_by_css_selector("div[dojoattachpoint='titleNode']")
print(get_div.text)
if it needs explicit wait:
wait = WebDriverWait(driver, 10)
a = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[dojoattachpoint='titleNode']"))).text
print(a)
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Update 1 :
The below xpath should represent the first element,
(//div[#dojoattachpoint='titleNode'])[1]
and the below should represent the 2nd one..
(//div[#dojoattachpoint='titleNode'])[2]
so using xpath indexing you can get the unique match.

How do I wait until text of element changes to something else than a string?

I'm using selenium with Python 3 to retrieve the contents from an element on a webpage. There is an element with dynamic text.
<div id="accResp">Please wait...</div>
The "Please wait..." section changes to different strings like "Password Incorrect", "Loading".
How do I wait until the string changes to anything except "Please wait..."?
Based on your functionality you will see text in your web page so you can handle text using below xpath's:
wait = WebDriverWait(driver, 10)
password Incorrect
passwordIncorrect = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(),'Password Incorrect')]")))
Loading
loading = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(),'Loading')]")))
Please wait...
waitText= wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(),'Please wait...')]")))
Note : please add below imports to your solution
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

How to input Values in Google Maps using Python/Selenium

I cannot use send keys correctly to input values.
I would like to be able to insert text into the text box.
Tried 2 different methods
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument("--test-type")
driver = webdriver.Chrome('/Users/.../Documents/chromedriver')
driver.get('http://codepad.org/')
text_area = driver.find_element_by_id('textarea')
text_area.send_keys("This text is send using Python code.")
from selenium import webdriver
driver = webdriver.Chrome('/Users/.../Documents/chromedriver')
driver.get( 'https://www.google.com/maps/dir///#36.0667234,-115.1059052,15z')
driver.find_element_by_xpath("//*[#placeholder='Choose starting point, or click on the map...']").click()
driver.find_element_by_xpath("//*[#placeholder='Choose starting point, or click on the map...']").clear()
driver.find_element_by_xpath("//*[#placeholder='Choose starting point, or click on the map...']").send_keys("New York")
Put a value into the fields i am trying to put the values in
Here is the code that you can use, which will wait for the element to present and then set the value in the input box.
WebDriverWait(driver,30).until(EC.visibility_of_element_located((By.XPATH, "(//input[#class='tactile-searchbox-input'])[1]"))).send_keys("new york")
BTW you need below imports in order to work with explicit wait used in the above code.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

How to wait for non empty input field in Selenium Python

I'm trying to automatically run the currency converter in https://www.mastercard.us/en-us/consumers/get-support/convert-currency.html using Selenium in Python. Here is what I got so far:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
link1 = 'https://www.mastercard.us/en-us/consumers/get-support/convert-currency.html'
driver1 = webdriver.PhantomJS()
driver1.get(link1)
script = """ var select = arguments[0];
for(var i = 0; i < select.options.length; i++) {
if(select.options[i].value == arguments[1]) {
select.options[i].selected = true;
}
}
"""
driver1.find_element_by_id('getDate').send_keys('05-Sep-2017')
select = driver1.find_element_by_id('firstID')
driver1.execute_script(script, select, 'USD');
driver1.find_element_by_name('txtTAmt').send_keys('1.00')
driver1.find_element_by_name('txtBankFee').send_keys('0.00')
select = driver1.find_element_by_id('newID')
driver1.execute_script(script, select, 'EUR');
driver1.find_element_by_id('btnSubmit').click()
wait = WebDriverWait(driver1, 100)
element = wait.until(EC.presence_of_element_located((By.XPATH,
'//*[#name="txtCardAmt" and text() != ""]')))
print(element.text)
The problem is that the field "txtCardAmt" never gets populated and I'm getting a timeout exception. My question is, how can I wait for the server to finish the computation?
PS: I know there is easier ways to select options using the Select class, however in this website they do not work for some reason.
Your problem is that you wait until the text of the element with name txtCardAmt is not empty. The problem is that this is always true.
If you take a look to the interested html:
<input type="text" name="txtCardAmt" ng-model="mcz.txtCardAmt"
class="mczreadonly ng-pristine ng-valid mczblue" placeholder="0"
readonly="readonly" disabled="">
you can see that the there isn't text.
The info that you are you looking for (not visible in the html) is in the attribute value:
That is 7.38 in my example.
So:
elem = driver1.find_element_by_name('txtCardAmt')
value = elem.get_attribute("value")
print(value)
Your code regarding the selection of the date and the currencies doesn't work. In my example I used the xpath in order to do that. I'm sure there are better way to do this tasks. I used the xpath returned by the tools of the inspector of my browser.
The entire example:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
link1 = 'https://www.mastercard.us/en-us/consumers/get-support/convert-currency.html'
driver1 = webdriver.PhantomJS(executable_path=r'/pathTo/phantomjs')
driver1.get(link1)
driver1.find_element_by_id('getDate').click()
wait = WebDriverWait(driver1, 20)
wait.until(EC.presence_of_element_located((By.XPATH,"/html/body/div[1]/div/div/div/div[2]/div[3]/div/div/div[2]/div/div/div/a[1]/span")))
driver1.find_element_by_xpath("/html/body/div[1]/div/div/div/div[2]/div[3]/div/div/div[2]/div/div/div/a[1]/span").click()
driver1.find_element_by_xpath("//*[#id='transactiondatepicker']/div/table/tbody/tr[2]/td[3]/a").click()
#select = driver1.find_element_by_id('firstID')
#driver1.execute_script(script, select, 'USD');
driver1.find_element_by_xpath("//*[#id='mczRowC']/div[2]/button").click()
wait.until(EC.presence_of_element_located((By.XPATH,"//*[#id='mczRowC']/div[2]/div/ul/li[146]/a")))
driver1.find_element_by_xpath("//*[#id='mczRowC']/div[2]/div/ul/li[146]/a").click()
driver1.find_element_by_name('txtTAmt').send_keys('1.00')
driver1.find_element_by_name('txtBankFee').send_keys('2.00')
#select = driver1.find_element_by_id('newID')
#driver1.execute_script(script, select, 'EUR');
driver1.find_element_by_xpath("//*[#id='mczRowD']/div[2]/button").click()
wait.until(EC.presence_of_element_located((By.XPATH,"//*[#id='mczRowD']/div[2]/div/ul/li[49]/a")))
driver1.find_element_by_xpath("//*[#id='mczRowD']/div[2]/div/ul/li[49]/a").click()
driver1.find_element_by_id('btnSubmit').click()
time.sleep(3)
elem = driver1.find_element_by_name('txtCardAmt')
value = elem.get_attribute("value")
print(value)

Resources