Selenium + Python: Store text in a variable and print - python

I'm trying to use send_keys to fill a field and in the same time, store this value in a variable. When I run this code, the text of the variable is not printed.
locators.py
from selenium.webdriver.common.by import By
class CreateNewContractor(object):
FIRST_NAME = (By.ID, "id_0-first_name")
pages.py
from locators import *
class CreateNewContractor1(Page):
def fill_contractor(self):
email = self.find_element(*CreateNewContractor.FIRST_NAME).send_keys("Hello")
email.text
print email
How can I store and print the text filled in the email variable?

The email variable would get the value None - this is what send_keys() method returns.
Instead, you can simply keep the text in a variable:
text = "hello"
self.find_element(*CreateNewContractor.FIRST_NAME).send_keys(text)
print(text)
Or, if you want to actually get the value of the input, use get_attribute() method:
elm = self.find_element(*CreateNewContractor.FIRST_NAME)
elm.send_keys("hello")
print(elm.get_attribute("value"))

Related

Telethon get message buttons with python

Is there a way to get the URL or/and text of a button below the message?
I'm using telethon with python.
You can access the buttons of a message using its message.buttons property.
This property returns a list, each element of list is a row(list) of MessageButton.
For example, if you want to access the URL or text of send music to friends button which is in row 1 and column 0 (0 based index), you can use the following code:
peer_username = "Telegram identifier"
message = client.get_messages(peer_username)[0]
message_button = message.buttons[1][0]
text = message_button.text
url = message_button.url
Sometimes the url property in the MessageButton is empty, and you can use its button property to access the KeyboardButton. For example:
url = message_button.button.url

Send text and click ENTER on expath

I clicked the text box but I am unable to send a text.
divselected = driver.find_elements_by_xpath("//*[contains(text(), 'Add a public comment...')]")[0].click()
divselected.send_keys("Talk-Talk")
Unable to add comments and press enter.
I did some search and I think this should work, just clear and send return key.
divselected = driver.find_elements_by_xpath("//*[contains(text(), 'Add a public comment...')]")[0].click()
divselected.clear()
divselected.send_keys("Talk-Talk")
divselected.send_keys("Keys.RETURN")
You wrong variable initialize for divselected, remove .click().
So, it's should like this:
divselected = driver.find_elements_by_xpath("//*[contains(text(), 'Add a public comment...')]")[0]
divselected.click()
divselected.send_keys('Talk-Talk')
divselected.submit()
Or if .submit() doesn't work, use .send_keys(Keys.ENTER):
#following import
from selenium.webdriver.common.keys import Keys
divselected.send_keys(Keys.ENTER)
But in this case if you want get the first element (refers to your index [0]), actually you don't need .find_elements_*. You can use .find_element_(without s):
divselected = driver.find_element_by_xpath("//*[contains(text(), 'Add a public comment...')]")

Combine multiple Selenium waits using "OR"?

My selenium code checks for a completed subroutine to be done by waiting on the site's title to change which worked perfectly. Code looks like this:
waitUntilDone = WebDriverWait(session, 15).until(EC.title_contains(somestring))
However, this can fail sometimes since the site's landing page changes after manual website visits. The server remembers where you left off. This forces me to check for an alternate condition (website title = "somestring2).
Here is what I came up with so far (also works as far as I can tell):
try:
waitUntilDone = WebDriverWait(session, 15).until(EC.title_contains(somestring)) # the old condition
except:
try:
waitUntilDone = WebDriverWait(session, 15).until(EC.title_contains(somestring2)) # the new other condition which is also valid
except:
print "oh crap" # we should never reach this point
Either one of these conditions is always true. I don't know which one thou.
Is there any way to include an "OR" inside these waits or make the try/except block look nicer?
Looks like selenium will let you do this by creating your own class. Check out the documentation here: http://selenium-python.readthedocs.io/waits.html
Here's a quick example for your case. Note the key is to have a method named __call__ in your class that defines the check you want. Selenium will call that function every 500 milliseconds until it returns True or some not null value.
class title_is_either(object):
def __init__(self, locator, string1, string2):
self.locator = locator
self.string1 = string1
self.string2 = string2
def __call__(self, driver):
element = driver.find_element(*self.locator) # Finding the referenced element
title = element.text
if self.string1 in title or self.string2 in title
return element
else:
return False
# Wait until an element with id='ID-of-title' contains text from one of your two strings
somestring = "Title 1"
somestring2 = "Title 2"
wait = WebDriverWait(driver, 10)
element = wait.until(title_is_either((By.ID, 'ID-of-title'), somestring, somestring2))

Calling variables from inside functions in Python

I know I have already asked a question like this before but I have made my code much cleaner and I am still coming up with a problem.
My code goes like this:
class Email_Stuff:
def Get_From_Email():
#code to open up window and get email address
emailaddr = #the input
return emailaddr
def Get_To_Email():
#code to open up window and get to email address
recipaddr = #the input
return recipaddr
def Get_Email_Address():
#code to open up window and get email username
EmailUser = #the input
return EmailUser
def Get_Email_Password():
#code to open up window and get email password
EmailPass = #the input
return EmailPass
def Send_Email():
import smtplib
server = smtplib.SMTP('smtp.gmail.com', 587)
server.login((EmailUser),(EmailPass))
message = "Python Test Email"
server.sendmail(emailaddr,recipaddr,message)
I need to get the variables: emailaddr, recipaddr, EmailUser, and EmailPass into the function Send_Email. I'm not sure how I could do that though because when I run this code, it tells me that "the global name isn't defined".
Any ideas?
Make emailaddr, recipaddr, EmailUser, and EmailPass become instance variables by adding prefix "self.".
class Email_Stuff():
def Get_From_Email(self):
#code to open up window and get email address
self.emailaddr = #the input
def Get_To_Email(self):
#code to open up window and get to email address
self.recipaddr = #the input
def Get_Email_Address(self):
#code to open up window and get email username
self.EmailUser = #the input
def Get_Email_Password(self):
#code to open up window and get email password
self.EmailPass = #the input
def Send_Email(self):
import smtplib
server = smtplib.SMTP('smtp.gmail.com', 587)
server.login((self.EmailUser),(self.EmailPass))
message = "Python Test Email"
server.sendmail(self.emailaddr,self.recipaddr,self.message)
instance = Email_Stuff()
instance.Get_From_Email()
instance.Get_To_Email()
instance.Get_Email_Address()
instance.Get_Email_Password()
instance.Send_Email()
BTW, name of methods should be lowercase.
First, if you want these functions to methods associated with an instance of this class, then each method will need a reference to the instance itself as the first argument, usually designated as self, though you can name it anything you like.
For example:
def Get_Email_Password(self):
#code to open up window and get email password
EmailPass = #the input
return EmailPass
Next, you have two options to get the values ready for sendmail. You can either call each method from within the Send_Email method and store the returned values for each one. That would look like this:
def Send_Email(self):
emailaddr = self.Get_For_Email()
recipaddr = self.Get_Email_Address()
...
Or you can store the values, instead of returning them, as instance variables. So, you would have something like this:
def Get_Email_Password(self):
#code to open up window and get email password
EmailPass = #the input
self.emailaddr = EmailPass
And then, in your Send_Email method, you would reference the instance variables you have saved:
def Send_Email(self):
...
server.sendmail(self.emailaddr, self.recipaddr, self.message)
How you choose to do it is up to you, but I prefer the first way. I also suggest you read up on PEP8

Passing variables to functions in Python

Im writing test scripts in Python for Selenium web testing.
How do I pass parameters through a Python function to call in a later function?
I first have a login test function.
Then I have a new user registration function. Im trying to pass the Username and Password I use in the registration function to the testLogin() function that I call inside the testRegister() function.
This is my python code:
userName = "admin"
password = "admin"
#pass username and password variables to this function
def testLogin(userName,password):
browser = webdriver.Firefox()
browser.get("http://url/login")
element = browser.find_element_by_name("userName")
element.send_keys(userName)
element = browser.find_element_by_name("userPassword")
element.send_keys(password)
element.send_keys(Keys.RETURN)
browser.close()
# test registration
def testRegister():
browser = webdriver.Firefox()
browser.get("http://url/register")
#new username variable
newUserName = "test"
element = browser.find_element_by_name("regUser")
element.send_keys(newUserName)
#new password variable
newUserPassword = "test"
element = browser.find_element_by_name("regPassword")
element.send_keys(newUserPassword)
#
#now test if user is registered, I want to call testLogin with the test user name and pw.
testLogin(newUserName,newUserPassword)
browser.close()
Any values you have around—whether you got them as function arguments, or received them by calling functions, or just defined them on the fly—you can pass as arguments to any other function.
So, if you want to pass some values through testRegister for it to use with testLogin, just do this:
# test registration
def testRegister(userName, password):
browser = webdriver.Firefox()
browser.get("http://url/register")
element = browser.find_element_by_name("regUser")
element.send_keys(userName)
element = browser.find_element_by_name("regPassword")
element.send_keys(password)
Is there something more you wanted?
You can create a new function to run all of your tests.
def run_tests(username, password):
testLogin(username,password)
testRegister(username, password)
You will need to modify testRegister so it accepts username and password parameters.
Then you can start your script with run_tests('admin', 'letmein')

Categories

Resources