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()
Related
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.'
Could you please explain, why the DRIVER is equaled to None in the decorator auto_login. But DRIVER from setUp method goes first in output when I print it from setUp and auto_login methods.
And how can I set up driver globally from setUp method.
DRIVER = None
class BaseTest(unittest.TestCase):
def setUp(self):
global DRIVER
DRIVER = webdriver.Firefox()
print("DRIVER setUp: ", DRIVER)
def tearDown():
.....
And decorator
def auto_login(email, password):
def create_dec(func):
def wrapper(*args, **kwargs):
print("DRIVER IN DEC: ", DRIVER)
login(DRIVER, email, password)
func(*args, **kwargs)
return wrapper
return create_dec
It is how I use decorator for test
class Test(BaseTest):
EMAIL = "xxx#gmail.com"
PASSWORD = "xxxxx"
#auto_login(email=EMAIL, password=PASSWORD)
def test_1(self):
......
Output:
DRIVER setUp: <selenium.webdriver.firefox.webdriver.WebDriver (session="e1f7fa5fa4137305c4587535b20b849c")>
DRIVER IN DEC: None
It seems like you don't have DRIVER defined in scope.
def auto_login(email, password):
def create_dec(func):
def wrapper(*args, **kwargs):
global DRIVER # <--- What happens if you add this line?
print("DRIVER IN DEC: ", DRIVER)
login(DRIVER, email, password)
func(*args, **kwargs)
return wrapper
return create_dec
Try this
DRIVER = None
class BaseTest(unittest.TestCase):
def setUp(self):
global DRIVER
DRIVER = webdriver.Firefox()
self.DRIVER=DRIVER
print("DRIVER setUp: ", DRIVER)
return DRIVER
def tearDown():
.....
And in your Test Class
class Test(BaseTest):
DRIVER=BaseTest.DRIVER
EMAIL = "xxx#gmail.com"
PASSWORD = "xxxxx"
#auto_login(email=EMAIL, password=PASSWORD)
def test_1(self):
......
I'm having some real issues trying to work out how to get this to work, and I'm sure there are some experts on here who can work it out for me, please :)
So I have a number of test cases in python that all follow on from each other, but are individual scripts, I want to combine these and run them in order, in a single webdriver instance, as they all follow on, but I can't seem to work out how to do it..
I have created a test suite -
import unittest
from Searchfieldreturnscorrectvalue import SearchFieldReturnsCorrectValue
from Navigatetostreetlightprecontentpage import Navigatetostreetlightprecontentpage
class TestSuite(unittest.TestSuite):
def suite():
suite = unittest.TestSuite()
suite.addTest(Searchfieldreturnscorrectvalue('test_searchfieldreturnscorrectvalue'))
suite.addTest(Navigatetostreetlightprecontentpage('test_navigatetostreetlightprecontentpage'))
return suite
if __name__ == "__main__":
unittest.main()
This runs the tests, but the second one fails as it tried to run it in a second firefox instance..
Searchfieldreturnscorrectvalue.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
class SearchFieldReturnsCorrectValue(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "https://www.XXXXX.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_search_field_returns_correct_value(self):
driver = self.driver
driver.get(self.base_url + "/")
driver.find_element_by_id("edit-search-block-form--2").click()
driver.find_element_by_id("edit-query").clear()
driver.find_element_by_id("edit-query").send_keys("street light")
driver.find_element_by_id("edit-query").send_keys(Keys.ENTER)
for i in range(60):
try:
if self.is_element_present(By.LINK_TEXT, "Street lighting"): break
except: pass
time.sleep(1)
else: self.fail("time out")
try: self.assertEqual("Street lighting", driver.find_element_by_link_text("Street lighting").text)
except AssertionError as e: self.verificationErrors.append(str(e))
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.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
Navigatetostreetlightprecontentpage.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
class Navigatetostreetlightprecontentpage(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.verificationErrors = []
self.accept_next_alert = True
def test_navigatetostreetlightprecontentpage(self):
driver = self.driver
driver.find_element_by_link_text("Street lighting").click()
try: self.assertEqual("Street lighting", driver.find_element_by_css_selector("h1.page-title__main__title").text)
except AssertionError as e: self.verificationErrors.append(str(e))
try: self.assertEqual("Report a faulty street light | Cheshire East", driver.title)
except AssertionError as e: self.verificationErrors.append(str(e))
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.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
I don't know if a test suite is the correct way to do it, or to just get all the tests into one file, but I still would want the "Classes/Tests" to individually report pass/fail, at the moment I can't get that to work, I think it is something to do with the setUp(self) needing to be moved to a setUpModule and shared? But I can't work it out, if someone could please point me in the right direction, I would be very grateful.
Thanks
Update
Example of what I have tired as per comment bellow, still not working..
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
class SeleniumTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.driver = webdriver.Firefox()
cls.driver.maximize_window()
#classmethod
def tearDownClass(cls):
cls.driver.close()
cls.driver.quit()
class SearchFieldReturnsCorrectValue(SeleniumTest):
def setUp(cls):
cls.base_url = "https://www.XXXXX.com"
cls.verificationErrors = []
cls.accept_next_alert = True
def test_search_field_returns_correct_value(cls):
driver = cls.driver
driver.get(cls.base_url + "/")
driver.find_element_by_id("edit-search-block-form--2").click()
driver.find_element_by_id("edit-query").clear()
driver.find_element_by_id("edit-query").send_keys("street light")
driver.find_element_by_id("edit-query").send_keys(Keys.ENTER)
for i in range(60):
try:
if cls.is_element_present(By.LINK_TEXT, "Street lighting"): break
except: pass
time.sleep(1)
else: cls.fail("time out")
try: cls.assertEqual("Street lighting", driver.find_element_by_link_text("Street lighting").text)
except AssertionError as e: cls.verificationErrors.append(str(e))
driver.find_element_by_link_text("Street lighting").click()
def is_element_present(cls, how, what):
try: cls.driver.find_element(by=how, value=what)
except NoSuchElementException as e: return False
return True
def is_alert_present(cls):
try: cls.driver.switch_to_alert()
except NoAlertPresentException as e: return False
return True
def close_alert_and_get_its_text(cls):
try:
alert = cls.driver.switch_to_alert()
alert_text = alert.text
if cls.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: cls.accept_next_alert = True
def tearDown(cls):
cls.assertEqual([], cls.verificationErrors)
class Navigatetostreetlightprecontentpage(SeleniumTest):
def setUp(cls):
cls.verificationErrors = []
cls.accept_next_alert = True
def test_navigatetostreetlightprecontentpage(cls):
driver = cls.driver
try: cls.assertEqual("Street lighting", driver.find_element_by_css_selector("h1.page-title__main__title").text)
except AssertionError as e: cls.verificationErrors.append(str(e))
try: cls.assertEqual("Report a faulty street light | Cheshire East", driver.title)
except AssertionError as e: cls.verificationErrors.append(str(e))
def is_element_present(cls, how, what):
try: cls.driver.find_element(by=how, value=what)
except NoSuchElementException as e: return False
return True
def is_alert_present(cls):
try: cls.driver.switch_to_alert()
except NoAlertPresentException as e: return False
return True
def close_alert_and_get_its_text(cls):
try:
alert = cls.driver.switch_to_alert()
alert_text = alert.text
if cls.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: cls.accept_next_alert = True
def tearDown(cls):
cls.assertEqual([], cls.verificationErrors)
if __name__ == "__main__":
unittest.main()
This seems to be running both classes now, but the second class is never able to locate any elements, but the same line in the first class works perfectly.
I am not sure I understood well, but to use a single driver instance, you can use the setupClass class method where you create the driver:
class MyTestClass(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.driver = webdriver.Firefox()
#classmethod
def tearDownClass(cls):
cls.driver.close()
cls.driver.quit()
def setUp(self):
....
It will still recreate the driver for every new test class, but it does not recreate one for every test (as setUp does).
Personnally I make all my test classes inherit from a SeleniumTest class like this:
class SeleniumTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.driver = webdriver.Firefox()
#classmethod
def tearDownClass(cls):
cls.driver.close()
cls.driver.quit()
class MyTestClass(SeleniumTest):
def setUp(self):
....
import unittest
from selenium import webdriver
from time import sleep
class SeleniumTest(unittest.TestCase):
global driver
#classmethod
def setUpClass(cls):
#getting a common webdriver instance for all your tests for this module
cls.driver = webdriver.Chrome("/Users/sibasish/PycharmProjects/CommonDriverInstance/chromedriver")
cls.driver.get("https://www.google.com")
#classmethod
def tearDownClass(cls):
cls.driver.close()
cls.driver.quit()
class MyTestClass(SeleniumTest):
def setUp(self):
pass
def test_sample1(self):
print("hello1")
self.driver.get("https://www.google.com/")
sleep(4)
def test_sample2(self):
print("hello2")
self.driver.get("https://www.facebook.com/")
sleep(4)
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'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