I have multiple sign up pages that I am currently testing. Each of the form have seprate fields. However, some share common fields(as you can see from signup page.py).

This is what I have so far(I am using Page Object method), I would like to know how I can improve my code to make it more robust.

Here is the signUp page.py:

class signupPage(Page):

def __init__(self, driver):
super(signupPage, self).__init__(driver)

def SignupPage1139_CompanyOne(self):
self.driver.get("https://abc.com/s_csignup.jsp?token=XVtQHUUGYFFaRhNaXxJaQVBRZEl2EnBo")
self.driver.find_element_by_id("cname").clear()
self.driver.find_element_by_id("cname").send_keys("QA EXTERNAL")
self.driver.find_element_by_id("cf_2727675").clear()
self.driver.find_element_by_id("cf_2727675").send_keys("Test")
self.driver.find_element_by_id("cf_2697953").clear()
self.driver.find_element_by_id("cf_2697953").send_keys("Test")
self.driver.find_element_by_id("sbbut").click()
self.assertEqual("Could not create organization, an organization with the entered criteria already exists.", self.close_alert_and_get_its_text())

def SignupPage1139_CompanyTwo(self):
self.driver.get("https://abc.com/s_csignup.jsp?token=XVtQHUUGYFFaRhNaXxJaQVBRZElzGnJt")
self.driver.find_element_by_id("cname").clear()
self.driver.find_element_by_id("cname").send_keys("QA EXTERNAL")
self.driver.find_element_by_id("city").clear()
self.driver.find_element_by_id("city").send_keys("Toronto")
Select(self.driver.find_element_by_id("state")).select_by_visible_text("Ontario")
self.driver.find_element_by_id("sbbut").click()
self.assertEqual("Cannot update using new scripts as there is already a matching company", self.close_alert_and_get_its_text())

def SignupPage1139_CompanyThree(self):
self.driver.get("https://abc.com/s_csignup.jsp?token=XVtQHUUGYFFcRhZdXxJaQVBRZEl9HnRr")
self.driver.find_element_by_id("cname").clear()
self.driver.find_element_by_id("cname").send_keys("DO NOT DELETE - Pandora External")
self.driver.find_element_by_id("cf_2698238").clear()
self.driver.find_element_by_id("cf_2698238").send_keys("000000124")
self.driver.find_element_by_id("sbbut").click()


Here is my test.py:

class MatchingContactCompany(BaseTestCase, unittest.TestCase):

def setUp(self):
super(MatchingContactCompany, self).setUp()

def test_MatchingCompany(self):
# form 1
signup.obj = signupPage(self.driver)
signup.obj.SignupPage1139_CompanyOne()
# form 2
signup.obj.SignupPage1139_CompanyTwo()
# form 3 create the account and verify if the account was created
signup.obj.SignupPage1139_CompanyThree()

def tearDown(self):
super(MatchingContactCompany, self).tearDown()

if __name__ == "__main__":
unittest.main()


This is not how the Page Object pattern should be implemented:

• page object needs to have abstractions over the visual elements on a page
• you should not be asserting things in the page object methods

There are, of course, many different Python+Selenium Page Object pattern implementations and I am not completely sure, which one is the One, here are some(1) of(2) them(3).

We can, at least, start with defining locators and then reusing them inside the methods, something along these lines:

class SignupPage(Page):
cname_input = (By.ID, "cname")

submit_button = (By.ID, "sbbut")

def __init__(self, driver):
super(SignupPage, self).__init__(driver)

def submit(self):
self.driver.find_element(*self.submit_button).click()

def sign_up(self):
self.driver.get("https://abc.com/s_csignup.jsp?token=XVtQHUUGYFFaRhNaXxJaQVBRZEl2EnBo")

cname = self.driver.find_element(*self.cname_input)
cname.send_keys("QA EXTERNAL")

self.submit()


Or, even better, we can create a class for every Page Element, like suggested in the documentation.

Note that the assertion itself should be moved to the test case method, and, hence, your Page class should not be derived from the unittest.TestCase (or have the assertEqual method).

Also, here are some notes about the code style of the code in the question:

• if your BaseTestCase class inherits unittest.TestCase (it should), there is no need for multiple inheritance. And, you would not need to override the setUp and tearDown methods:

class BaseTestCase(unittest.TestCase):
# ...

class MatchingContactCompany(BaseTestCase):
def test_matching_company(self):
# ...

• according to PEP8, a class name should start with a capital letter and be in camel case - call it SignupPage instead of signupPage

• the test_* methods should be named according to the PEP8 method name convention - it should be test_matching_company instead of test_MatchingCompany
• same note about your page object methods - use a lower case and separate words with underscore