I'm trying to create a class that can create wedriver instances and add proxies to them, this is only a dumbed down version of what i've already written, but I'm also trying to make a method that will wait for an element to be visible before clicking it, the attribute is isn't getting passed to the driver object.
Edit: The code as it was, was hard to understand out of context so I added the whole class as I'm working on it. I've also changed the click_elem method to a static method but now it just times out even though the element is visible.
class Driver:
proxies = []
#staticmethod
def test_proxy(proxy):
try:
urllib.urlopen(
"https://www.google.com",
proxies={'http': proxy})
return True
except IOError:
print "Connection error! (Check proxy)"
return False
else:
return False
def get_proxied_driver(self):
for proxy in self.proxies:
try:
myproxy = self.proxies.pop()
if self.test_proxy(myproxy):
proxy = Proxy({
'proxyType': ProxyType.MANUAL,
'httpProxy': myproxy,
'ftpProxy': myproxy,
'sslProxy': myproxy,
'noProxy': '' # set this value as desired
})
driver = webdriver.Firefox(proxy=proxy)###### chrome, phantom js & IE etc ##
is_working = raw_input('Is your proxy working? [y/n]: ') # use selenium assert
if is_working == 'y' or is_working == 'Y':
return driver
if is_working == 'n' or is_working == 'N':
driver.quit()
continue
if not is_working == 'y' or is_working == 'Y' or is_working == 'n' or is_working == 'N':
print 'Invallid'
except:
continue
# needs working_proxies.txt in the same dir
def get_proxies(self):
with open('working_proxies.txt', 'rb') as working_proxies:
for proxy in working_proxies:
proxy.rstrip()
self.proxies.append(proxy.decode('ascii'))
def get_proxies_n_driver(self): # same as get_driver but it adds proxies from -
self.get_proxies() # working_proxies.txt to proxies list
driver = self.get_proxied_driver()
return driver
#staticmethod
def click_elem(driver, elem_type, elem):
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((elem_type, elem)))
if elem_type == By.CLASS_NAME:
find = find_element_by_class_name
elem = driver.find(elem).click()
driver = Driver()
#driver.test_proxy('213.136.79.124:80')
new_driver = driver.get_proxies_n_driver()
new_driver.get("https://twitter.com/signup")
driver.click_elem(new_driver, By.CLASS_NAME, "submit_button")
I've also got another Script that tests the proxies and then adds them to working_proxies.txt
Related
I have a script to auto check crypto prices every 5 minutes but I can't let chrome driver opened due to number of reasons, however when I quit it and start it again exception occur
while True:
before_time = time.time()
self.start() # this initialize chromedriver
self.driver.get(self.url)
self.check()
self.quit()
after_time = time.time()
self._counter += 1
self._time.append(round(after_time - before_time, 3))
print(self._timer)
self.delay.custom(self._timer)
This works perfect on first iteration while in the next iterations exception occur
class Selenium:
def __init__(self, webdriver="uc", _user_data_dir=None, _incognito=False, _proxy_server=None,
load_full=False, _timeout=30, _zoom=125):
assert not _incognito or _user_data_dir is None, "You can't use profile in incognito mode!"
self.driver = None
self.wait = None
self.webdriver = webdriver
self.timeout = _timeout
self.proxy = _proxy_server
self.data_dir = _user_data_dir
self.incognito = _incognito
self.load_type = load_full
self.zoom = _zoom / 100
def start(self):
options = Options()
options.add_argument("--start-maximized")
options.add_argument(f"--force-device-scale-factor={self.zoom}")
options.add_argument(f"--high-dpi-support={self.zoom}")
if not self.load_type:
options.page_load_strategy = "none"
if self.proxy is not None:
options.add_argument(f"--proxy-server=socks5://{self.proxy}:1080")
if self.data_dir is not None:
options.add_argument(f"--user-data-dir={self.data_dir}")
if self.incognito:
options.add_argument(f"--incognito")
if self.webdriver == "uc":
self.driver = uc.Chrome(options=options, use_subprocess=True, suppress_welcome=True)
elif self.webdriver.lower() == "chrome":
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
self.driver = webdriver.Chrome(service=service(__chrome=True), options=options)
elif self.webdriver.lower() == "firefox":
self.driver = webdriver.Chrome(service=service(__gecko=True), options=options)
else:
raise NotImplementedError(f"{self.webdriver} is not implemented yet!")
self.wait = WebDriverWait(self.driver, self.timeout)
def slow_type(self, element, content):
for x in content:
element.send_keys(x)
self.delay.custom(self.speed)
def get(self, url):
self.driver.get(url)
def quit(self):
self.driver.quit()
def refresh(self):
self.driver.refresh()
Appium automation runs and ends correctly inside one class, but fails when another class is created.
I tried to to delete all attributes in init, except first one and it helps.
Main Class(works well)
import unittest
from appium import webdriver
from ScreenObjects.SendMessage import SendMsg
class AppTestAppium(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = ''
desired_caps['deviceName'] = '81e9b20e'
desired_caps['appPackage'] = 'org.telegram.messenger'
desired_caps['appActivity'] = 'org.telegram.ui.LaunchActivity'
desired_caps['noReset'] = 'True'
self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)
def tearDown(self):
"Tear down the test"
self.driver.quit()
def test_send_messge_to_olga(self):
"Test is sending message"
contactItem = self.driver.find_element_by_xpath("//android.view.ViewGroup[contains(#index,'2')]")
contactItem.click()
elementTypeField = self.driver.find_element_by_xpath("//android.widget.EditText[contains(#index,'1')]")
elementTypeField.clear()
elementTypeField.send_keys("Hello. If you are reading this, my first appium automation has passed")
sendButton = self.driver.find_element_by_xpath("//android.widget.ImageView[#content-desc ='Send']")
sendButton.click()
if __name__ == '__main__':
unittest.main()
Main class(fails)
import unittest
from appium import webdriver
from ScreenObjects.SendMessage import SendMsg
class AppTestAppium(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = ''
desired_caps['deviceName'] = '81e9b20e'
desired_caps['appPackage'] = 'org.telegram.messenger'
desired_caps['appActivity'] = 'org.telegram.ui.LaunchActivity'
desired_caps['noReset'] = 'True'
self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)
def tearDown(self):
"Tear down the test"
self.driver.quit()
def test_send_messge_to_olga(self):
"Test is sending message"
send_message = SendMsg(self.driver)
send_message.chooseContact()
send_message.typeMsg()
send_message.clickSend()
if __name__ == '__main__':
unittest.main()
with one more Class (fails)
class SendMsg(object):
def __init__(self, driver):
self.contactItem = driver.find_element_by_xpath("//android.view.ViewGroup[contains(#index,'2')]")
self.elementTypeField = driver.find_element_by_xpath("//android.widget.EditText[contains(#index,'1')]")
self.sendButton = driver.find_element_by_xpath("//android.widget.ImageView[#content-desc ='Send']")
def chooseContact(self):
self.contactItem.click()
def typeMsg(self):
self.elementTypeField.clear()
self.elementTypeField.send_keys("Hello")
def clickSend(self):
self.sendButton.click()
I expect TEST PASSED, but the actual output is 'An element could not be located on the page using the given search parameters.'
I'm trying to write a test in Selenium using python,
I managed to run the test and it passed, But now I want add arg parser so I can give the test a different URL as an argument.
The thing is that my test is inside a class,
So when I'm passing the argument I get an error:
app_url= (args['base_url'])
NameError: global name 'args' is not defined
How can I get args to be defined inside the Selenium class?
This is my code:
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
from selenium import webdriver
import unittest, time, re
import os
import string
import random
import argparse
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(8))
agmuser = id_generator()
class Selenium(unittest.TestCase):
def setUp(self):
chromedriver = "c:\chromedriver.exe"
os.environ["webdriver.chrome.driver"] = chromedriver
self.driver = webdriver.Chrome(chromedriver)
app_url = (args['base_url'])
#app_url= "http://myd-vm16635.fufu.net:8080/"
print "this is the APP URL:" + ' ' + app_url
self.base_url = app_url
self.verificationErrors = []
self.accept_next_alert = True
def test_selenium(self):
#id_generator.user = id_generator()
driver = self.driver
driver.get(self.base_url + "portal/")
driver.find_element_by_css_selector("span").click()
driver.find_element_by_id("j_loginName").clear()
driver.find_element_by_id("j_loginName").send_keys(agmuser)
driver.find_element_by_id("btnSubmit").click()
driver.find_element_by_link_text("Login as" + ' ' + agmuser).click()
driver.find_element_by_css_selector("#mock-portal-Horizon > span").click()
# driver.find_element_by_id("gwt-debug-new-features-cancel-button").click()
# driver.find_element_by_xpath("//table[#id='gwt-debug-module-dropdown']/tbody/tr[2]/td[2]").click()
# driver.find_element_by_id("gwt-debug-menu-item-release-management").click()
def is_element_present(self, how, what):
try: self.driver.find_element(by=how, value=what)
except NoSuchElementException as e: return False
return True
def is_alert_present(self):
try: self.driver.switch_to_alert()
except NoAlertPresentException as e: return False
return True
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
#####################******SCRIPT PARAMS****;**###################################
# these values can be changed type 'python selenium_job.py --help' for assistance
##################################################################################
parser = argparse.ArgumentParser(description='DevOps team - Sanity test')
parser.add_argument('-b', '--base_url', help='base_url', default="http://myd-vm16635.fufu.net:8080/")
args = vars(parser.parse_args())
unittest.main()
Put the parser = argparse.ArgumentParser(...) and parser.add_argument() outside if __name__ == "__main__": so that it always gets created but not evaluated. Keep args = vars(parser.parse_args()) inside __main__.
That way you can import it from the file like from selenium_tests import parser and then in your other script, do parser.parse_args().
And a cleaner way to do it is to create a function which returns the parser, like:
def get_parsed_args():
parser = argparse.ArgumentParser(...)
parser.add_argument(...)
# etc.
args = parser.parse_args()
return args
# or just...
return parser.parse_args()
#and then call that in the main program:
if __name__ == '__main__':
args = get_parsed_args()
# etc.
And in other scripts which you want to import it into, do
from selenium_tests import get_parsed_args
if __name__ == '__main__':
args = get_parsed_args()
# etc.
I am trying to check if an element exists on an HTML page with Selenium/Python.
This is my function:
class runSelenium(object):
def __init__(self):
# define a class attribute
self.driver = webdriver.Firefox()
def isElementPresent(self, locator):
try:
self.driver.find_element_by_xpath(locator)
except NoSuchElementException:
print ('No such thing')
return False
return True
def selenium(self):
self.driver.get("https://somepage.com")
isElement = self.isElementPresent("//li[#class='item'][6]")
isElement1 = str(isElement)
if __name__ == '__main__':
run = runSelenium()
run.selenium()
I am trying to pick the result with a Boolean value but with no luck:
isElement = self.isElementPresent("//li[#class='item'][6]")
What am I missing here?
You need to un-indent the last code block:
class runSelenium(object):
def __init__(self):
# define a class attribute
self.driver = webdriver.Firefox()
def isElementPresent(self, locator):
try:
self.driver.find_element_by_xpath(locator)
except NoSuchElementException:
print ('No such thing')
return False
return True
def selenium(self):
self.driver.get("https://somepage.com")
isElement = self.isElementPresent("//li[#class='item'][6]")
isElement1 = str(isElement)
if __name__ == '__main__':
run = runSelenium()
run.selenium()
So I restarted the IDE (Visual Studio 2013) and it works now fine.. The code is correct 100%
I have the following code that occasionally crashes due to a permissions bug. I am trying to wrap it up in a try / except statement that will keep trying to launch the driver until successful...
def init_driver():
ffprofile = webdriver.FirefoxProfile("my_profile")
ffprofile.add_extension(extension="myaddon.xpi")
return driver
driver = init_driver()
I have seen examples letting me print a message if an error occurs but how do I get it to keep retrying? Does anybody have an example they can point me at?
Here's a loop that iterates over attempts:
while True:
try:
driver = init_driver()
break
except Foo:
continue
Note that this is not a bare except clause. Bare excepts are dangerous because they can capture things like NameError that are so rarely meant to be caught. You should put the specific exception you expect to catch here.
Here's one way to do it if you don't want to use a loop. Just recall the function on the exception
import sys
def init_driver(tries=0):
try:
ffprofile = webdriver.FirefoxProfile("my_profile");
ffprofile.add_extension(extension="myaddon.xpi")
return driver
except Exception: #This should be the exception you expect and not a catch all
if tries < sys.getrecursionlimit(): #By default 1,000 can be bumped up by setrecursionlimit
return init_driver(tries+1)
#just for kicks
#else:
#sys.setrecursionlimit(sys.getrecursionlimit() + 1)
#print("Yes we'll win this game the old-fashioned way, the tried and true way:")
#print("We'll cheat!")
#refactor / prettify if's to call init_driver if you want to cheat.
else:
print("OH NO RECURSION LIMIT HIT!!!!!! (ノಠ益ಠ)ノ彡┻━┻")
driver = init_driver()
Other answers are fine but they will keep retrying until it hits the recursion depth limit. Consider adding a retry limit:
def init_driver(retry_limit=10, nretry=0):
if nretry >= retry_limit:
return # retry limit reached, maybe raise an exception?
try:
ffprofile = webdriver.FirefoxProfile("my_profile");
ffprofile.add_extension(extension="myaddon.xpi")
except SomeException:
return init_driver(nretry=nretry+1)
return ffprofile
driver = init_driver()
Do like this:
def init_driver():
driver = None
ffprofile = webdriver.FirefoxProfile("my_profile");
ffprofile.add_extension(extension="myaddon.xpi")
# do something with a valid profile and set driver to something other than None
return driver
driver = None
while driver is None:
driver = init_driver()
Here is a recursive solution (with keeping track of the retries):
def init_driver(retries=0):
try:
ffprofile = webdriver.FirefoxProfile("my_profile");
ffprofile.add_extension(extension="myaddon.xpi")
except:
print('attempt nr. ' + str(retries))
return init_driver(retries+1)
return driver
Just a small change required. Where Foo is the specific exception you get with the permissions bug.
def init_driver():
try:
ffprofile = webdriver.FirefoxProfile("my_profile");
ffprofile.add_extension(extension="myaddon.xpi")
return driver
except Foo:
return init_driver()
driver = init_driver()