how to retrieve selenium webdriver sessionid using unittest framework? - python

I'm trying to retrieve the session id of a selenium webdriver session during the execution of a test as such:
import unittest
class MyTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
def testSomething(self):
"""selenium tests go here"""
self.driver.get('http://www.example.com')
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)
testResult = unittest.TextTestRunner(verbosity=2).run(suite)
session_id = ???
I know I could do self.driver.session_id side the setUp method. The problem is I need to get the session id outside of the class instance. Any ideas?

Probably, you can create property/function inside the class instance which could return you sessionID.

Related

PytestCollectionWarning: cannot collect test class 'Test_001_Login' because it has a __init__ constructor

Hi I'm trying to learn Python/Selenium using a Page Object Model.
I have been following this tutorial and as far as I can tell I haven't missed anything. However I can't run my tests because of the init constructor. In the video, he has the same init constructor and the tests run for him.
Inside my project folder I have a subfolder pageObjects and testCases.
In pageObjects I have LoginPage.py where i set up my locators and actions i want to perform on the locators
class LoginPage:
textbox_username_id = "Email"
textbox_password_id = "Password"
button_login_xpath = "//input[#class='button-1 login-button']"
link_logout_linktext = "Logout"
def __init__(self,driver):
self.driver = driver
def setUserName(self,username):
self.driver.find_element_by_id(self.textbox_username_id).clear()
self.driver.find_element_by_id(self.textbox_username_id).send_keys(username)
def setPassword(self,password):
self.driver.find_element_by_id(self.textbox_password_id).clear()
self.driver.find_element_by_id(self.textbox_password_id).send_keys(password)
def clickLogin(self):
self.driver.find_element_by_xpath(self.button_login_xpath).click()
def clickLogout(self):
self.driver.find_element_by_link_text(self.link_logout_linktext).click()
In testCases I have test_login.py and conftest.py
I'll show conftest.py first
from selenium import webdriver
import pytest
#pytest.fixture()
def setup():
driver = webdriver.Chrome()
return driver
and test_login.py
import pytest
from selenium import webdriver
from pageObjects.LoginPage import LoginPage
from testCases import conftest
class Test_001_Login:
baseURL = "https://admin=demo.nopcommerce.com/"
username = "admin#yourstore.com"
password = "admin"
def __init__(self):
self.lp = LoginPage(self.driver)
self.driver = conftest.setup
def test_homePageTitle(self, setup):
self.driver = setup
self.driver.get(self.baseURL)
act_title = self.driver.title
self.driver.close()
if act_title == "Your store. Login":
assert True
else:
assert False
def test_login(self, setup):
self.driver = setup
self.driver.get(self.baseURL)
self.lp.setUserName(self.username)
self.lp.setPassword(self.password)
self.lp.clickLogin()
act_title = self.driver.title
if act_title == "Dashboard / nopCommerce administration":
assert True
else:
assert False
There are 2 issues.
conftest.py is supposed to be a special type of class/fixture. I should be able to call it to create an instance of webdriver.Chrome(). However it does not work. In test_login.py when i call 'setup' I get an error 'unresolved reference 'setup''. So I've had to manually import it as a work around. Isn't the whole point of the conftest.py file so that my test_* files have access to the webdriver in conftest.py wihtout having to import it?
When i try to run the test_login.py file, I get a warning and 0 items are collected - testCases\test_login.py:6
C:\Users\Mirza\PycharmProjects\nopcommerceApp\testCases\test_login.py:6: PytestCollectionWarning: cannot collect test class 'Test_001_Login' because it has a init constructor (from: testCases/test_login.py)
class Test_001_Login:
I have absolutely no idea what to do here. Why can't my class Test_001_Login have an init constructor? I need it to create an instance of the LoginPage class and to create an instance of the webdriver from conftest.py.
Any help would be greatly appreciated.

Changing test name in python unittest using selenium

I have a question. Is it possible to change the name test in output, using python unittests?
For example, my test:
from selenium import webdriver
import unittest
from data.readData import Data
from actions.actions import Actions
from pages.notificationsPage import NotificationsPage
class NotificationsTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome(executable_path=Data.driver)
cls.driver.implicitly_wait(10)
cls.driver.maximize_window()
def test_order_confirmation(self):
Actions.login(self, Data.email, Data.password)
driver = self.driver
driver.get(Data.website + "Admin/Configuration/Message")
notify = NotificationsPage(driver)
notify.order_confirmation()
#classmethod
def tearDownClass(cls):
cls.driver.close()
cls.driver.quit()
if __name__ == '__main__':
unittest.main()
And my output:
I want to change the marked one test name to own string here, in this output, and also in result file in res.xml (I think it is the same value).
Is it possible?
Yes, Just simply change the name of your tests method. Just Change:
def test_order_confirmation(self):
to
def whatever_you_want_to_call_your_test(self):

How do i make the pytest driver instance available in my testcase

I am trying to build an selenium based automation framework, using, Python, Pytest.
My intention is to create a driver instance at the class level by initializing it in conftest.py and making it available in all testcases, so that user doesn't need to create the driver instance in each testcase.
Driver instance in conftest.py:
#pytest.fixture(scope="class")
def get_driver(request):
from selenium import webdriver
driver = webdriver.Chrome()
request.cls.driver = driver
yield
driver.quit()
BaseTestCase class looks like this:
#pytest.mark.usefixtures("get_driver")
class BaseTestCase(unittest.TestCase):
def __init__(self, *args, **kwargs):
super(BaseTestCase, self).__init__(*args, **kwargs)
#classmethod
def setUpClass(cls):
if hasattr(super(BaseTestCase, cls), "setUpClass"):
super(BaseTestCase, cls).setUpClass()
My testcase is as follows:
from ..pages.google import Google
class Test_Google_Page(BaseTestCase):
#classmethod
def setUpClass(self):
self.page = Google(self.driver, "https://www.google.com/")
My page Google extends to BasePage that looks like this:
class BasePage(object):
def __init__(self, driver, url=None, root_element = 'body'):
super(BasePage, self).__init__()
self.driver = driver
self._root_element = root_element
self.driver.set_script_timeout(script_timeout)
When i execute my testcase, I get the following error:
#classmethod
def setUpClass(self):
> driver = self.driver
E AttributeError: type object 'Test_Google_Page' has no attribute 'driver'
How can I make the driver instance available in my testcases by simply calling self.driver?
The class scoped fixtures are executed after the setUpClass classmethods, so when Test_Google_Page.setUpClass is executed, get_driver did not run yet. Check out the execution ordering:
import unittest
import pytest
#pytest.fixture(scope='class')
def fixture_class_scoped(request):
print(f'{request.cls.__name__}::fixture_class_scoped()')
#pytest.mark.usefixtures('fixture_class_scoped')
class TestCls(unittest.TestCase):
#classmethod
def setUpClass(cls):
print(f'{cls.__name__}::setUpClass()')
def setUp(self):
print(f'{self.__class__.__name__}::setUp()')
#pytest.fixture()
def fixture_instance_scoped(self):
print(f'{self.__class__.__name__}::fixture_instance_scoped()')
#pytest.mark.usefixtures('fixture_instance_scoped')
def test_bar(self):
print(f'{self.__class__.__name__}::test_bar()')
assert True
When running the test with e.g. pytest -sv, the output yields:
TestCls::setUpClass()
TestCls::fixture_class_scoped()
TestCls::fixture_instance_scoped()
TestCls::setUp()
TestCls::test_bar()
So the solution is to move the code from setUpClass to e.g. setUp:
class Test_Google_Page(BaseTestCase):
def setUp(self):
self.page = Google(self.driver, "https://www.google.com/")
I am afraid I may not use setUp because in my most of my class file I have multiple test cases and I just want to do one time setup in setUpClass instead of launching in each time before calling any test method.
I would then move the code from setUpClass to another class-scoped fixture:
import pytest
#pytest.mark.usefixtures('get_driver')
#pytest.fixture(scope='class')
def init_google_page(request):
request.cls.page = Google(request.cls.driver,
"https://www.google.com/")
#pytest.mark.usefixtures('init_google_page')
class Test_Google_Page(BaseTestCase):
...
The former setUpClass is now the init_google_page fixture which will be called after get_driver (because of pytest.mark.usefixtures('get_driver')).

Attribute error in python unittest

On executing this unittest getting
AttributeError: 'BaseUnit' object has no attribute 'driver'
import unittest
import redis
from selenium import webdriver
redis = redis.Redis(host='abc', port='123')
keys = redis.keys('*')
raw_baseunit = redis.get('test:baseunit')`enter code here`
class BaseUnit(unittest.TestCase):
def setup(self):
self.driver = webdriver.PhantomJS()
def test(self):
self.driver.get("myurl")
self.driver.find_element_by_id('username').send_keys("ngeo_pur1")
self.driver.find_element_by_id('password').send_keys("anything")
self.driver.find_element_by_xpath('html/body/div[1]/div[3]/div/section/div/form/ul/li[5]/div[2]/div/input').click()
self.driver.get("url")
self.driver.find_element_by_partial_link_text("18757424").click()
self.driver.find_element_by_xpath(".//*[#id='tabs']/nav/ul/li[2]/a/i").click()
Actual = self.driver.find_element_by_xpath(".//*[#id='subcat_baseModelSection.baseModelChoice']/div/div[1]").text
keys = redis.keys('*')
raw_baseunit = redis.get('test:baseUnit')
print "Actual Base Unit=",Actual
print "Expected Base Unit=",raw_baseunit
self.assetEquals(raw_baseunit,Actual)
def teardown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
Tried changing the class name 'BaseUnit' as well
Try modifying the setup class's name to this. I just read the doc and the setup class is written with the U in uppercase
def setUp(self):
self.driver = webdriver.PhantomJS()
The methods you want to override in unittest.TestCase are setUp and tearDown (note the capital "U" and "D"), not setup and teardown.
Your all-lowercase setup method doesn't get called before the test methods run (if it gets called at all), so the self.driver attribute doesn't exist when then test method tries to use it.

Python TypeError when attempting to pass parameters to unittest subclass

I'm attempting to pass parameters to unittest subclass methods. Please forgive my ignorance - I've only started coding in Python a few days ago. I could obviously just hardcode the parameters in the subclass itself but that would eliminate its reuse with other username/password combos. When I run run_tests.py below, I get the error "TypeError: runTest() takes exactly 3 arguments (4 given)".
Here is run_tests.py:
from selenium import webdriver
import unittest
from testcases import login
def my_suite():
suite = unittest.TestSuite()
suite.addTest (login.Login().runTest("username1", "password1", "page title"))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(my_suite())
Here is testcases/basetestcase.py:
from selenium import webdriver
import unittest
class BaseTestCase (unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "http://website"
def tearDown(self):
self.driver.quit()
Here is testcases/login.py
import common_page_elements
from basetestcase import BaseTestCase
class Login (BaseTestCase):
def runTest(username, password, verification):
""" Test logging in. """
driver = self.driver
driver.get(self.base_url)
driver.find_element_by_id(common_page_elements.textfield_username).clear()
driver.find_element_by_id(common_page_elements.textfield_username).send_keys(username)
driver.find_element_by_id(common_page_elements.textfield_password).clear()
driver.find_element_by_id(common_page_elements.textfield_password).send_keys(password)
driver.find_element_by_name(common_page_elements.button_submit).click()
self.assertTrue(verification in self.driver.title)
Since runTest has become a class method, you'll have to include the self argument:
class Login (BaseTestCase):
def runTest(self, username, password, verification):
^^^^

Categories

Resources