Basepage is a python package that enables you to write selenium tests using python easily and fast.
It provides two parts:
- A wrapper around webdriver (selenium) and its functions and properties
- Convenience methods for dealing with elements
We recommend you use it in conjunction with the page-object model (examples are in java, but the pattern works for python as well).
There are a couple of ways you can use Basepage.
frombasepageimportBasepageclassMyBasepage(Basepage):
def__init__(self, driver):
super(BasePage, self).__init__(driver)This way, Basepage becomes part of self, and in your page-objects you can use it like so:
frommybaseimportMyBasepageclassLoginpage(MyBasepage):
_username_locator= ('ID', 'username')
_password_locator= ('ID', 'password')
_login_button_locator= ('CSS_SELECTOR', '.login_button')
deflogin(username, password):
self.enter_text(self._username_locator, username)
self.enter_text(self._password_locator, password)
self.click(self._login_button_locator)classMyBasepage(object):
def__init__(self, driver):
frombasepageimportBasepageself._base=Basepage(driver)
@propertydefbase(self):
returnself._baseThis way, Basepage is a property on MyBasepage, and in your page-objects you can use it like so:
frommybaseimportMyBasepageclassLoginpage(MyBasepage):
_username_locator= ('ID', 'username')
_password_locator= ('ID', 'password')
_login_button_locator= ('CSS_SELECTOR', '.login_button')
deflogin(username, password):
self.base.enter_text(self._username_locator, username)
self.base.enter_text(self._password_locator, password)
self.base.click(self._login_button_locator)To be able to use Basepage you need to provide an adapter for selectors, you have to name it get_compliant_locatorand it has to return a tuple containing a selenium By selector and a string. The rest of the implementation details is up to you.
Example:
frombasepageimportBasepageclassMyBasepage(Basepage):
def__init__(self, driver):
super(BasePage, self).__init__(driver)
@staticmethoddefget_compliant_locator(by, locator, params=None):
""" Returns a tuple of by and locator prepared with optional parameters :param by: Type of locator (ie. CSS, ClassName, etc) :param locator: element locator :param params: (optional) locator parameters :return: tuple of by and locator with optional parameters """fromselenium.webdriver.common.byimportByifparamsisnotNoneandnotisinstance(params, dict):
raiseTypeError("<params> need to be of type <dict>, was <{}>".format(params.__class__.__name__))
returngetattr(By, by), locator.format(**(paramsor {}))We recommend using the pytest test framework with the pytest-selenium plugin to even further cut down on implementation time.
Given you're using pytest and pytest-selenium, this is what a test could look like:
importpytestfromlogin_pageimportLoginpagedeftest_login(driver):
page=Loginpage(driver)
page.login("Tom Smith", "123456")
assertsomethingThe driver parameter is actually a fixture provided by the pytest-selenium to the pytest framework and represents an instance of webdriver.