mirror of
https://github.com/gunesmes/page-object-python-selenium.git
synced 2021-05-12 23:22:11 +03:00
orginize structure
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.idea/*
|
||||
*__pycache__*
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
0
__init__.py
Normal file
0
__init__.py
Normal file
17
locators.py
17
locators.py
@@ -1,17 +0,0 @@
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
# for maintainability we can seperate web objects by page name
|
||||
|
||||
class MainPageLocatars(object):
|
||||
LOGO = (By.ID, 'nav-logo')
|
||||
ACCOUNT = (By.ID, 'nav-link-yourAccount')
|
||||
SIGNUP = (By.CSS_SELECTOR, '#nav-flyout-ya-newCust > a')
|
||||
LOGIN = (By.CSS_SELECTOR, '#nav-flyout-ya-signin > a')
|
||||
SEARCH = (By.ID, 'twotabsearchtextbox')
|
||||
SEARCH_LIST = (By.ID, 's-results-list-atf')
|
||||
|
||||
class LoginPageLocatars(object):
|
||||
EMAIL = (By.ID, 'ap_email')
|
||||
PASSWORD = (By.ID, 'ap_password')
|
||||
SUBMIT = (By.ID, 'signInSubmit-input')
|
||||
ERROR_MESSAGE = (By.ID, 'message_error')
|
||||
66
pages.py
66
pages.py
@@ -1,66 +0,0 @@
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from base import Page
|
||||
from locators import *
|
||||
import users
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
|
||||
# Page opjects are written in this module.
|
||||
# Depends on the page functionality we can have more functions for new classes
|
||||
|
||||
class MainPage(Page):
|
||||
def __init__(self, driver):
|
||||
self.locator = MainPageLocatars
|
||||
super().__init__(driver) # Python3 version
|
||||
|
||||
def check_page_loaded(self):
|
||||
return True if self.find_element(*self.locator.LOGO) else False
|
||||
|
||||
def search_item(self, item):
|
||||
self.find_element(*self.locator.SEARCH).send_keys(item)
|
||||
self.find_element(*self.locator.SEARCH).send_keys(Keys.ENTER)
|
||||
return self.find_element(*self.locator.SEARCH_LIST).text
|
||||
|
||||
def click_sign_up_button(self):
|
||||
self.hover(*self.locator.ACCOUNT)
|
||||
self.find_element(*self.locator.SIGNUP).click()
|
||||
return SignUpPage(self.driver)
|
||||
|
||||
def click_sign_in_button(self):
|
||||
self.hover(*self.locator.ACCOUNT)
|
||||
self.find_element(*self.locator.LOGIN).click()
|
||||
return LoginPage(self.driver)
|
||||
|
||||
class LoginPage(Page):
|
||||
def __init__(self, driver):
|
||||
self.locator = LoginPageLocatars
|
||||
super(LoginPage, self).__init__(driver) # Python2 version
|
||||
|
||||
def enter_email(self, user):
|
||||
self.find_element(*self.locator.EMAIL).send_keys(users.get_user(user)["email"])
|
||||
|
||||
def enter_password(self, user):
|
||||
self.find_element(*self.locator.PASSWORD).send_keys(users.get_user(user)["password"])
|
||||
|
||||
def click_login_button(self):
|
||||
self.find_element(*self.locator.SUBMIT).click()
|
||||
|
||||
def login(self, user):
|
||||
self.enter_email(user)
|
||||
self.enter_password(user)
|
||||
self.click_login_button()
|
||||
|
||||
def login_with_valid_user(self, user):
|
||||
self.login(user)
|
||||
return HomePage(self.driver)
|
||||
|
||||
def login_with_in_valid_user(self, user):
|
||||
self.login(user)
|
||||
return self.find_element(*self.locator.ERROR_MESSAGE).text
|
||||
|
||||
class HomePage(Page):
|
||||
pass
|
||||
|
||||
class SignUpPage(Page):
|
||||
pass
|
||||
0
pages/__init__.py
Normal file
0
pages/__init__.py
Normal file
@@ -1,28 +1,26 @@
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.common.action_chains import ActionChains
|
||||
|
||||
# this Base class is serving basic attributes for every single page inherited from Page class
|
||||
|
||||
# this Base class is serving basic attributes for every single page inherited from Page class
|
||||
class Page(object):
|
||||
def __init__(self, driver, base_url='http://www.app.com/'):
|
||||
def __init__(self, driver, base_url='http://www.amazon.com/'):
|
||||
self.base_url = base_url
|
||||
self.driver = driver
|
||||
self.timeout = 30
|
||||
|
||||
|
||||
def find_element(self, *locator):
|
||||
return self.driver.find_element(*locator)
|
||||
|
||||
def open(self,url):
|
||||
|
||||
def open(self, url):
|
||||
url = self.base_url + url
|
||||
self.driver.get(url)
|
||||
|
||||
|
||||
def get_title(self):
|
||||
return self.driver.title
|
||||
|
||||
|
||||
def get_url(self):
|
||||
return self.driver.current_url
|
||||
|
||||
|
||||
def hover(self, *locator):
|
||||
element = self.find_element(*locator)
|
||||
hover = ActionChains(self.driver).move_to_element(element)
|
||||
5
pages/home_page.py
Normal file
5
pages/home_page.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from pages.base import Page
|
||||
|
||||
|
||||
class HomePage(Page):
|
||||
pass
|
||||
33
pages/login_page.py
Normal file
33
pages/login_page.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from utils.locators import *
|
||||
from pages.base import Page
|
||||
from utils import users
|
||||
|
||||
|
||||
class LoginPage(Page):
|
||||
def __init__(self, driver):
|
||||
self.locator = LoginPageLocators
|
||||
super(LoginPage, self).__init__(driver) # Python2 version
|
||||
|
||||
def enter_email(self, email):
|
||||
self.find_element(*self.locator.EMAIL).send_keys(email)
|
||||
|
||||
def enter_password(self, password):
|
||||
self.find_element(*self.locator.PASSWORD).send_keys(password)
|
||||
|
||||
def click_login_button(self):
|
||||
self.find_element(*self.locator.SUBMIT).click()
|
||||
|
||||
def login(self, user):
|
||||
user = users.get_user(user)
|
||||
print(user)
|
||||
self.enter_email(user["email"])
|
||||
self.enter_password(user["password"])
|
||||
self.click_login_button()
|
||||
|
||||
def login_with_valid_user(self, user):
|
||||
self.login(user)
|
||||
return HomePage(self.driver)
|
||||
|
||||
def login_with_in_valid_user(self, user):
|
||||
self.login(user)
|
||||
return self.find_element(*self.locator.ERROR_MESSAGE).text
|
||||
28
pages/main_page.py
Normal file
28
pages/main_page.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from pages.base import Page
|
||||
from utils.locators import *
|
||||
|
||||
|
||||
# Page objects are written in this module.
|
||||
# Depends on the page functionality we can have more functions for new classes
|
||||
|
||||
class MainPage(Page):
|
||||
def __init__(self, driver):
|
||||
self.locator = MainPageLocators
|
||||
super().__init__(driver) # Python3 version
|
||||
|
||||
def check_page_loaded(self):
|
||||
return True if self.find_element(*self.locator.LOGO) else False
|
||||
|
||||
def search_item(self, item):
|
||||
self.find_element(*self.locator.SEARCH).send_keys(item)
|
||||
self.find_element(*self.locator.SEARCH).send_keys(Keys.ENTER)
|
||||
return self.find_element(*self.locator.SEARCH_LIST).text
|
||||
|
||||
def click_sign_up_button(self):
|
||||
self.find_element(*self.locator.SIGNUP).click()
|
||||
return SignUpPage(self.driver)
|
||||
|
||||
def click_sign_in_button(self):
|
||||
self.find_element(*self.locator.LOGIN).click()
|
||||
return LoginPage(self.driver)
|
||||
5
pages/signup_page.py
Normal file
5
pages/signup_page.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from pages.base import Page
|
||||
|
||||
|
||||
class SignUpPage(Page):
|
||||
pass
|
||||
62
testPages.py
62
testPages.py
@@ -1,62 +0,0 @@
|
||||
import unittest
|
||||
from selenium import webdriver
|
||||
from pages import *
|
||||
from testCases import test_cases
|
||||
from locators import *
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
# I am using python unittest for asserting cases.
|
||||
# In this module, there should be test cases.
|
||||
# If you want to run it, you should type: python <module-name.py>
|
||||
|
||||
class TestPages(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.driver = webdriver.Chrome()
|
||||
#self.driver = webdriver.Firefox()
|
||||
self.driver.get("http://www.amazon.com")
|
||||
|
||||
def test_page_load(self):
|
||||
print "\n" + str(test_cases(0))
|
||||
page = MainPage(self.driver)
|
||||
self.assertTrue(page.check_page_loaded())
|
||||
|
||||
def test_search_item(self):
|
||||
print "\n" + str(test_cases(1))
|
||||
page = MainPage(self.driver)
|
||||
search_result = page.search_item("Nexus 5")
|
||||
self.assertIn("Nexus 5", search_result)
|
||||
|
||||
def test_sign_up_button(self):
|
||||
print "\n" + str(test_cases(2))
|
||||
page = MainPage(self.driver)
|
||||
signUpPage = page.click_sign_up_button()
|
||||
self.assertIn("ap/register", signUpPage.get_url())
|
||||
|
||||
def test_sign_in_button(self):
|
||||
print "\n" + str(test_cases(3))
|
||||
page = MainPage(self.driver)
|
||||
loginPage = page.click_sign_in_button()
|
||||
self.assertIn("ap/signin", loginPage.get_url())
|
||||
|
||||
def test_sign_in_with_valid_user(self):
|
||||
print "\n" + str(test_cases(4))
|
||||
mainPage = MainPage(self.driver)
|
||||
loginPage = mainPage.click_sign_in_button()
|
||||
result = loginPage.login_with_valid_user("valid_user")
|
||||
self.assertIn("yourstore/home", result.get_url())
|
||||
|
||||
def test_sign_in_with_in_valid_user(self):
|
||||
print "\n" + str(test_cases(5))
|
||||
mainPage = MainPage(self.driver)
|
||||
loginPage = mainPage.click_sign_in_button()
|
||||
result = loginPage.login_with_in_valid_user("invalid_user")
|
||||
self.assertIn("There was a problem with your request", result)
|
||||
|
||||
def tearDown(self):
|
||||
self.driver.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestPages)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
70
tests/testPages.py
Normal file
70
tests/testPages.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import unittest
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from pages.main_page import *
|
||||
from utils.testCases import test_cases
|
||||
|
||||
|
||||
# I am using python unittest for asserting cases.
|
||||
# In this module, there should be test cases.
|
||||
# If you want to run it, you should type: python <module-name.py>
|
||||
|
||||
class TestPages(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
options = Options()
|
||||
# options.add_argument("--headless") # Runs Chrome in headless mode.
|
||||
options.add_argument('--no-sandbox') # # Bypass OS security model
|
||||
options.add_argument('disable-infobars')
|
||||
options.add_argument("--disable-extensions")
|
||||
options.add_argument("--start-fullscreen")
|
||||
options.add_argument('--disable-gpu')
|
||||
|
||||
self.driver = webdriver.Chrome(options=options)
|
||||
# self.driver = webdriver.Firefox()
|
||||
self.driver.get("http://www.amazon.com")
|
||||
|
||||
def test_page_load(self):
|
||||
print("\n" + str(test_cases(0)))
|
||||
page = MainPage(self.driver)
|
||||
self.assertTrue(page.check_page_loaded())
|
||||
|
||||
def test_search_item(self):
|
||||
print("\n" + str(test_cases(1)))
|
||||
page = MainPage(self.driver)
|
||||
search_result = page.search_item("iPhone 8")
|
||||
self.assertIn("iPhone 8", search_result)
|
||||
|
||||
def test_sign_up_button(self):
|
||||
print("\n" + str(test_cases(2)))
|
||||
page = MainPage(self.driver)
|
||||
sign_up_page = page.click_sign_up_button()
|
||||
self.assertIn("ap/register", sign_up_page.get_url())
|
||||
|
||||
def test_sign_in_button(self):
|
||||
print("\n" + str(test_cases(3)))
|
||||
page = MainPage(self.driver)
|
||||
login_page = page.click_sign_in_button()
|
||||
self.assertIn("ap/signin", login_page.get_url())
|
||||
|
||||
def test_sign_in_with_valid_user(self):
|
||||
print("\n" + str(test_cases(4)))
|
||||
main_page = MainPage(self.driver)
|
||||
login_page = main_page.click_sign_in_button()
|
||||
result = login_page.login_with_valid_user("valid_usrer")
|
||||
self.assertIn("yourstore/home", result.get_url())
|
||||
|
||||
def test_sign_in_with_in_valid_user(self):
|
||||
print("\n" + str(test_cases(5)))
|
||||
main_page = MainPage(self.driver)
|
||||
login_page = main_page.click_sign_in_button()
|
||||
result = login_page.login_with_in_valid_user("invalid_user")
|
||||
self.assertIn("There was a problem with your request", result)
|
||||
|
||||
def tearDown(self):
|
||||
self.driver.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestPages)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
18
users.py
18
users.py
@@ -1,18 +0,0 @@
|
||||
from operator import itemgetter
|
||||
|
||||
# we can store test data in this module like users
|
||||
|
||||
users = [
|
||||
{"name": "invalid_user", "email": "invalidUser@test.com", "password": "qwert1235"},
|
||||
{"name": "valid_user", "email": "validUser@yahoo.com", "password": "ValidPassword"},
|
||||
{"name": "Staff2", "email": "staff@test.com", "password": "qwert1235"},
|
||||
{"name": "Admin0", "email": "admin@test.com", "password": "qwert1234"},
|
||||
{"name": "Admin1", "email": "admin@test.com", "password": "qwert1234"},
|
||||
{"name": "Admin2", "email": "admin@test.com", "password": "qwert1234"},
|
||||
]
|
||||
|
||||
def get_user(name):
|
||||
try:
|
||||
return (user for user in users if user["name"] == name).next()
|
||||
except:
|
||||
print "\n User %s is not defined, enter a valid user.\n" %name
|
||||
0
utils/__init__.py
Normal file
0
utils/__init__.py
Normal file
19
utils/locators.py
Normal file
19
utils/locators.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
|
||||
# for maintainability we can seperate web objects by page name
|
||||
|
||||
class MainPageLocators(object):
|
||||
LOGO = (By.ID, 'nav-logo')
|
||||
ACCOUNT = (By.ID, 'nav-link-accountList')
|
||||
SIGNUP = (By.CSS_SELECTOR, '#nav-signin-tooltip > div > a')
|
||||
LOGIN = (By.CSS_SELECTOR, '#nav-signin-tooltip > a')
|
||||
SEARCH = (By.ID, 'twotabsearchtextbox')
|
||||
SEARCH_LIST = (By.CLASS_NAME, 's-result-list')
|
||||
|
||||
|
||||
class LoginPageLocators(object):
|
||||
EMAIL = (By.ID, 'ap_email')
|
||||
PASSWORD = (By.ID, 'ap_password')
|
||||
SUBMIT = (By.ID, 'signInSubmit-input')
|
||||
ERROR_MESSAGE = (By.ID, 'message_error')
|
||||
@@ -1,21 +1,22 @@
|
||||
# -*- coding: utf8 -*-
|
||||
# we should add test cases here because we can miss some cases while writing automation code or
|
||||
# some manuel testers (test analystes) can handle this more efficiently
|
||||
# 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
|
||||
# We can also record the result of test cases to test management tool
|
||||
# -*- coding: utf8 -*- we should add test cases here because we can miss some cases while writing automation code or
|
||||
# some manuel testers (test analystes) can handle this more efficiently 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 We can also record the result of test
|
||||
# cases to test management tool
|
||||
|
||||
# for maintainability, we can seperate web test cases by page name but I just listed every case in same array
|
||||
|
||||
|
||||
def test_cases(number):
|
||||
return testCases[number]
|
||||
|
||||
|
||||
|
||||
testCases = [
|
||||
#[severity, description]
|
||||
# [severity, description]
|
||||
['Blocker', 'when user goes to main page, page should be loaded'],
|
||||
['Blocker', 'In Main page, when user search "Nexus 5" button, he should see result for Nexus 5'],
|
||||
['Blocker', 'In Main page, when user click "Sing up" button, he should see Sign up Page'],
|
||||
['Blocker', 'In Main page, when user click "Sing in" button, he should see Sign in Page'],
|
||||
['Blocker', 'In Login Page, when user login with a valid user, he should see Home Page'],
|
||||
['Blocker', 'In Login Page, when user login with a in-valid user, he should see Error Message'],
|
||||
]
|
||||
]
|
||||
18
utils/users.py
Normal file
18
utils/users.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from operator import itemgetter
|
||||
|
||||
# we can store test data in this module like users
|
||||
users = [
|
||||
{"name": "invalid_user", "email": "invalidUser@test.com", "password": "qwert1235"},
|
||||
{"name": "valid_user", "email": "validUser@yahoo.com", "password": "ValidPassword"},
|
||||
{"name": "Staff2", "email": "staff@test.com", "password": "qwert1235"},
|
||||
{"name": "Admin0", "email": "admin@test.com", "password": "qwert1234"},
|
||||
{"name": "Admin1", "email": "admin@test.com", "password": "qwert1234"},
|
||||
{"name": "Admin2", "email": "admin@test.com", "password": "qwert1234"},
|
||||
]
|
||||
|
||||
|
||||
def get_user(name):
|
||||
try:
|
||||
return next(user for user in users if user["name"] == name)
|
||||
except:
|
||||
print("\n User %s is not defined, enter a valid user.\n" % name)
|
||||
Reference in New Issue
Block a user