The part contains sample of web UI automation sources and tests
Web tests based on UI interactions using Selenium WebDriver and rest API endpoint from common framework Part:
We support 3 layers structure for code base:
- Builder layer - implementation of Page Object pattern
- Steps layer - steps functions that used from tests
- Tests layer - tests functions
Implementation of Page object pattern based on Page classes (For each web page we have separate class). This layer describes web interface and Actions that we can do using web interface.
That layer placed in pages
directory, e.g. for Home Page - home_page.py.
The Page object implementation should include following rules:
- The page class must inherit from WebPage class and implement
super
call for__init__
method - All page elements should be defined in
__init__
method as WebElement related objects - All elements variable names starts with element type shortcut: button -
seld.btn_name
, text_box -self.txb_name
etc - Class methods should implement only actions on the page using elements from
__init__
section byself.
call and methods fromWebElement
/WebPage
classes
sample of Page class:
from common._webdriver_qa_api.web.web_pages import WebPage
from selenium.webdriver.common.by import By
from common._webdriver_qa_api.web.web_elements import WebElement
class HomePage(WebPage):
def __init__(self):
super().__init__(By.ID, "myTab", "Account Home Page")
self.lnk_api_keys = WebElement(By.XPATH, "//li/a[@href='/api_keys']")
self.lbl_api_key = WebElement(By.XPATH, "//table//pre")
def click_api_keys_menu(self):
self.lnk_api_keys.click()
Steps layer - it's a function set which combine Action methods from Builder layer and expands them with test checks. This solution help us to have clear structure of tests and avoid code duplication (save time on test supporting)
That layer placed in steps
directory and divided to 3 main parts:
- navigation - function that used for navigation between web pages
- page steps - steps related with Pages, based on classes that inherit from Page Object classes
- global steps - functions that combine many actions for frequent uses (like login)
The navigation
keywords should include following rules:
- Navigation function combine actions from: another steps, PO classes, checks
- Should return an object of PageStep class
- Have a log_title message with action message
- Function should be added to
__all__
module list
sample of navigation method:
from common._webdriver_qa_api.web.web_driver import navigate_to
from common.facade import logger, raw_config
from sample import web
__all__ = ['navigate_to_sign_in_page']
def navigate_to_sign_in_page():
logger.log_title(f"Navigate to Sign in page")
navigate_to(raw_config.project_settings.web_app_url)
main_steps = web.pages.MainPageSteps()
main_steps.click_sign_in()
return web.pages.SignInSteps()
The page steps
keywords should include following rules:
- The step class must inherit from PO class for same page (e.g. if you have HomePage on PO layer, steps class will be -
class HomePageSteps(HomePage)
) - Step class haven't
__init__
section or have a super call of__init__
from PO class - Class methods should implement steps related with inherited page using: actions from Page class, checks, additional object from Builder layer (e.g. popup's)
- Python module should be added to
__all__
variable in__init__.py
file of pages or subdirectory (e.g. __init__.py`)
sample of page steps implementation:
from common.facade import logger
from sample.web.pages.home_page import HomePage
class HomePageSteps(HomePage):
def get_api_key(self):
logger.log_title("Get REST API key")
self.click_api_keys_menu()
return self.lbl_api_key.text
The global steps
keywords should include following rules:
- Function combine actions from: another steps, page steps classes, checks
- Have a log_title call with action message
- Function should be added to
__all__
module list
sample of steps method:
# TBU
Test layer include python modules with tests and pytest fixtures.
That layer placed in tests
directory that can include subdirectories and modules by test types or target,
e.g. for Sign In page - tests for sign in page
there are a few rules that we hold:
- Test module name should starts from
test_
- Test Class name should starts from
Test
- Test function should starts from
test
- Create test Classes to organize logical test suites and implement flexible mechanism of fixtures
- Place fixtures in
conftest.py
on test layer when this fixture can be reused from different packages, modules - Place fixture in local python test module/conftest file when fixture used by single test/module
- Tests function use actions from: keyword layer calls (page steps, global steps, navigation steps)
Code sample:
import pytest
from common.facade import logger
from sample import web
@pytest.mark.usefixtures('open_main_page')
class TestSignIn:
""" Weather - sign in to account tests """
def test_sign_in_page_displayed(self):
""" Recover account button transaction """
logger.log_step("Open sign in page", precondition=True)
sign_in_page = web.navigation_steps.navigate_to_sign_in_page()
logger.log_step("Verify default elements on the page")
sign_in_page.verify_default_elements()