Skip to content

Commit 52ecf29

Browse files
committed
6 test cases are added
0 parents  commit 52ecf29

File tree

7 files changed

+221
-0
lines changed

7 files changed

+221
-0
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# selenium-page-object
2+
3+
Page-object model is a pattern that you can apply it to develop efficient automation framework. With page-model, it is possible to minimise maintenance cost. Basically page-object means that your every page is inherited from a base class which includes basic functionalities for every pages. If you have some new functionality that every pages have, you can simple add it to the base class.
4+
5+
####If you want to run it, you should type:
6+
```sh
7+
python <module-name.py>
8+
```
9+
10+
11+
####If you want to run it just a class, you should type:
12+
```sh
13+
python <module-name.py> <class-name>
14+
```

base.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.common.by import By
3+
from selenium.webdriver.common.action_chains import ActionChains
4+
5+
# this Base class is serving basic attributes for every single page inherited from Page class
6+
7+
class Page(object):
8+
def __init__(self, driver, base_url='http://www.app.com/'):
9+
self.base_url = base_url
10+
self.driver = driver
11+
self.timeout = 30
12+
13+
def find_element(self, *locator):
14+
return self.driver.find_element(*locator)
15+
16+
def open(self,url):
17+
url = self.base_url + url
18+
self.driver.get(url)
19+
20+
def get_title(self):
21+
return self.driver.title
22+
23+
def get_url(self):
24+
return self.driver.current_url
25+
26+
def hover(self, *locator):
27+
element = self.find_element(*locator)
28+
hover = ActionChains(self.driver).move_to_element(element)
29+
hover.perform()

locators.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from selenium.webdriver.common.by import By
2+
3+
# for maintainability we can seperate web objects by page name
4+
5+
class MainPageLocatars(object):
6+
LOGO = (By.ID, 'nav-logo')
7+
ACCOUNT = (By.ID, 'nav-link-yourAccount')
8+
SIGNUP = (By.CSS_SELECTOR, '#nav-flyout-ya-newCust > a')
9+
LOGIN = (By.CSS_SELECTOR, '#nav-flyout-ya-signin > a')
10+
SEARCH = (By.ID, 'twotabsearchtextbox')
11+
SEARCH_LIST = (By.ID, 's-results-list-atf')
12+
13+
class LoginPageLocatars(object):
14+
EMAIL = (By.ID, 'ap_email')
15+
PASSWORD = (By.ID, 'ap_password')
16+
SUBMIT = (By.ID, 'signInSubmit-input')
17+
ERROR_MESSAGE = (By.ID, 'message_error')

pages.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.common.by import By
3+
from selenium.webdriver.common.keys import Keys
4+
from base import Page
5+
from locators import *
6+
import users, functions
7+
from selenium.webdriver.support.ui import WebDriverWait
8+
9+
10+
# Page opjects are written in this module.
11+
# Depends on the page functionality we can have more functions for new classes
12+
13+
class MainPage(Page):
14+
def check_page_loaded(self):
15+
return True if self.find_element(*MainPageLocatars.LOGO) else False
16+
17+
def search_item(self, item):
18+
self.find_element(*MainPageLocatars.SEARCH).send_keys(item)
19+
self.find_element(*MainPageLocatars.SEARCH).send_keys(Keys.ENTER)
20+
return self.find_element(*MainPageLocatars.SEARCH_LIST).text
21+
22+
def click_sign_up_button(self):
23+
self.hover(*MainPageLocatars.ACCOUNT)
24+
self.driver.find_element(*MainPageLocatars.SIGNUP).click()
25+
return SignUpPage(self.driver)
26+
27+
def click_sign_in_button(self):
28+
self.hover(*MainPageLocatars.ACCOUNT)
29+
self.driver.find_element(*MainPageLocatars.LOGIN).click()
30+
return LoginPage(self.driver)
31+
32+
class LoginPage(Page):
33+
def enter_email(self, user):
34+
self.driver.find_element(*LoginPageLocatars.EMAIL).send_keys(users.get_user(user)["email"])
35+
36+
def enter_password(self, user):
37+
self.driver.find_element(*LoginPageLocatars.PASSWORD).send_keys(users.get_user(user)["password"])
38+
39+
def click_login_button(self):
40+
self.driver.find_element(*LoginPageLocatars.SUBMIT).click()
41+
42+
def login(self, user):
43+
self.enter_email(user)
44+
self.enter_password(user)
45+
self.click_login_button()
46+
47+
def login_with_valid_user(self, user):
48+
self.login(user)
49+
return HomePage(self.driver)
50+
51+
def login_with_in_valid_user(self, user):
52+
self.login(user)
53+
return self.find_element(*LoginPageLocatars.ERROR_MESSAGE).text
54+
55+
class HomePage(Page):
56+
pass
57+
58+
class SignUpPage(Page):
59+
pass

testCases.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# -*- coding: utf8 -*-
2+
# we should add test cases here because we can miss some cases while writing automation code or
3+
# some manuel testers (test analystes) can handle this more efficiently
4+
# we can obtain test cases from test management tools, I used this for my previous project: http://www.inflectra.com/SpiraTest/Integrations/Unit-Test-Frameworks.aspx
5+
# We can also record the result of test cases to test management tool
6+
7+
# for maintainability, we can seperate web test cases by page name but I just listed every case in same array
8+
9+
def test_cases(number):
10+
return testCases[number]
11+
12+
13+
testCases = [
14+
#[severity, description]
15+
['Blocker', 'when user goes to main page, page should be loaded'],
16+
['Blocker', 'In Main page, when user search "Nexus 5" button, he should see result for Nexus 5'],
17+
['Blocker', 'In Main page, when user click "Sing up" button, he should see Sign up Page'],
18+
['Blocker', 'In Main page, when user click "Sing in" button, he should see Sign in Page'],
19+
['Blocker', 'In Login Page, when user login with a valid user, he should see Home Page'],
20+
['Blocker', 'In Login Page, when user login with a in-valid user, he should see Error Message'],
21+
]

testPages.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import unittest
2+
from selenium import webdriver
3+
from pages import *
4+
from testCases import test_cases
5+
from locators import *
6+
from selenium.webdriver.common.by import By
7+
8+
# I am using python unittest for asserting cases.
9+
# In this module, there should be test cases.
10+
# If you want to run it, you should type: python <module-name.py>
11+
12+
class TestPages(unittest.TestCase):
13+
14+
def setUp(self):
15+
self.driver = webdriver.Chrome()
16+
#self.driver = webdriver.Firefox()
17+
self.driver.get("http://www.amazon.com")
18+
19+
def test_page_load(self):
20+
print "\n" + str(test_cases(0))
21+
page = MainPage(self.driver)
22+
self.assertTrue(page.check_page_loaded())
23+
24+
def test_search_item(self):
25+
print "\n" + str(test_cases(1))
26+
page = MainPage(self.driver)
27+
search_result = page.search_item("Nexus 5")
28+
self.assertIn("Nexus 5", search_result)
29+
30+
def test_sign_up_button(self):
31+
print "\n" + str(test_cases(2))
32+
page = MainPage(self.driver)
33+
signUpPage = page.click_sign_up_button()
34+
self.assertIn("ap/register", signUpPage.get_url())
35+
36+
def test_sign_in_button(self):
37+
print "\n" + str(test_cases(3))
38+
page = MainPage(self.driver)
39+
loginPage = page.click_sign_in_button()
40+
self.assertIn("ap/signin", loginPage.get_url())
41+
42+
def test_sign_in_with_valid_user(self):
43+
print "\n" + str(test_cases(4))
44+
mainPage = MainPage(self.driver)
45+
loginPage = mainPage.click_sign_in_button()
46+
result = loginPage.login_with_valid_user("valid_user")
47+
self.assertIn("yourstore/home", result.get_url())
48+
49+
def test_sign_in_with_in_valid_user(self):
50+
print "\n" + str(test_cases(5))
51+
mainPage = MainPage(self.driver)
52+
loginPage = mainPage.click_sign_in_button()
53+
result = loginPage.login_with_in_valid_user("invalid_user")
54+
self.assertIn("There was a problem with your request", result)
55+
56+
def tearDown(self):
57+
self.driver.close()
58+
59+
if __name__ == "__main__":
60+
suite = unittest.TestLoader().loadTestsFromTestCase(TestPages)
61+
unittest.TextTestRunner(verbosity=2).run(suite)
62+

users.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from operator import itemgetter
2+
3+
# we can store test data in this module like users
4+
5+
users = [
6+
{"name": "invalid_user", "email": "invalidUser@test.com", "password": "qwert1235"},
7+
{"name": "valid_user", "email": "validUser@yahoo.com", "password": "ValidPassword"},
8+
{"name": "Staff2", "email": "staff@test.com", "password": "qwert1235"},
9+
{"name": "Admin0", "email": "admin@test.com", "password": "qwert1234"},
10+
{"name": "Admin1", "email": "admin@test.com", "password": "qwert1234"},
11+
{"name": "Admin2", "email": "admin@test.com", "password": "qwert1234"},
12+
]
13+
14+
def get_user(name):
15+
users_ = sorted(users, key=itemgetter("name"))
16+
for user in users_:
17+
if user["name"] == name:
18+
break
19+
return user

0 commit comments

Comments
 (0)