I'm trying to implement PageObject pattern for my first Login test. While running it I'm receiving the following error:
>> py.test -v test_login.py
============================= test session starts ==============================
platform linux2 -- Python 2.7.3 -- pytest-2.3.4
plugins: xdist
collected 0 items / 1 errors
==================================== ERRORS ====================================
____________________ ERROR collecting test_login_logout.py _____________________
test_login_logout.py:10: in <module>
> from ui.pages import LoginPage
../pages/__init__.py:1: in <module>
> from loginPage import LoginPage
../pages/loginPage.py:3: in <module>
> from base import BasePage
E ImportError: No module named base
Here is the pythonpath:
Pythonpath: PYTHONPATH="${PYTHONPATH}:/usr/lib/python2.7/"
export PYTHONPATH
As far as it's one of my first tests a lot of code was copy-pasted, maybe there's something wrong with it but I'd can't get it. Will be very pleased with any suggestions on this point.
Also below is the structure and content of my so-called PageObject implementation:
ui/__ init __ .py:
__author__ = 'testuser'
ui/base/__ init __ .py:
from wrapper import SeleniumWrapper
from basePage import BasePage
selenium_driver = SeleniumWrapper()
ui/base/basePage.py:
class BasePage(object):
def __init__(self, driver):
self.driver = driver
def get_current_url(self):
return str(self.driver.current_url)
ui/base/configs.py:
import os
try:
os.environ["HOST"]
HOST = os.environ["HOST"]
except KeyError:
os.environ["HOST"] = 'http://www.website.com'
HOST = str(os.environ["HOST"])
PORT = ''
BASE_URL_US = '%s:%s/en/' % (HOST, PORT)
EMAIL = '[email protected]'
PASSWORD = 'secret'
ui/base/wrapper.py:
from selenium import webdriver
import configs
class SeleniumWrapper:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(SeleniumWrapper, cls).__new__(cls, *args, **kwargs)
return cls._instance
def connect(self, host=configs.BASE_URL_US):
self.driver = webdriver.Firefox()
self.base_url = host
return self.driver
ui/pages/__ init __ .py:
from loginPage import LoginPage
ui/pages/loginPage.py:
from base import BasePage
class LoginPage(object):
login_page_link = '.log-in>a'
email_field_locator = 'email'
password_field_locator = 'password'
login_button_locator = 'submit'
def __init__(self, driver, base_url):
self.driver = driver
self.driver.get(base_url)
def login_action(self, email, password):
login_page = self.driver.find_element_by_css_selector(self.login_page_link)
email_element = self.driver.find_element_by_id(self.email_field_locator)
password_element = self.driver.find_element_by_id(self.password_field_locator)
login_button = self.driver.find_element_by_id(self.login_button_locator)
login_page.click()
email_element.send_keys(email)
password_element.send_keys(password)
login_button.click()
ui/tests/__ init __ .py:
__author__ = 'testuser'
ui/tests/test_login.py:
import sys
import os
import pytest
if __name__ == '__main__':
sys.path.append(os.path.dirname(__file__) + '/../')
from ui.base import selenium_driver
from ui.pages import LoginPage
from ui.base import configs
@pytest.mark.ui
class TestLoginLogout(object):
@classmethod
def setup_class(cls):
cls.verificationErrors = []
cls.driver = selenium_driver.connect()
cls.driver.implicitly_wait(10)
cls.base_url = selenium_driver.base_url
cls.email = configs.EMAIL
cls.password = configs.PASSWORD
@classmethod
def teardown_class(cls):
cls.driver.quit()
assert cls.verificationErrors == []
def test_login_positive(self):
welcome_page = LoginPage(self.driver, self.base_url)
login_page = welcome_page.login_action(self.email, self.password)
# assert 'property' in login_page.get_current_url()
if __name__ == '__main__':
pytest.main([__file__, "-s"])
Your base
module is located in the ui
module. Hence line:
from base import BasePage
should be:
from ui.base import BasePage