基於對前邊幾篇文章的參考,自己根據系統需求寫了一個pageobject的架構。主要樹形結構如下圖:
以下是個別代碼塊:
1.base page模組
該parent頁面主要每個頁面都可能用到的方法,以便後面頁面的繼承(有的方法沒寫完整,用的時候可以自行添加)
# _*_ coding=utf-8 _*_from abc import abstractmethodfrom pageobject.log.logger import Loggingimport timefrom selenium.webdriver.common.action_chains import ActionChainsclass BasePage(object): base_url = "XXXXX" def __init__(self, driver): if self.base_url[-1] != '/': self.base_url += '/' # self._validate_page(driver) self.driver = driver self.log_obj = Logging() @abstractmethod def _validate_page(self, driver): return def open(self, url): url = self.base_url + url self.driver.get(url) def get_xpath(self, xpath): "return the DOM element of the xpath or the None object if the element is not found" def click_element(self, locator, is_button=True): "click the button supplied" if is_button: self.driver.find_element(*locator).click() else: f = self.driver.find_element(*locator) ActionChains(self.driver).click(f).perform() def write(self, msg, level='error'): self.log_obj.write(msg, level) def set_text(self, locator, values): try: text_field = self.driver.find_element(*locator) text_field.clear() text_field.send_keys(values) except Exception as msg: self.write(msg) def wait(self, wait_seconds=5): "performs wait for time provided" time.sleep(wait_seconds)class InvalidPageException(Exception): pass
2.login page
該登入頁面繼承於base page,主要寫登入頁面的屬性及控制項(具體根據自己系統登入頁面上的屬性、button等)
# _*_ coding=utf-8 _*_from selenium.webdriver.support.ui import WebDriverWaitfrom base_page import BasePagefrom pageobject.parameter.locator_element import login_locatorsfrom base_element import BaseTextElementclass UsernameElement(BaseTextElement): def __init__(self): self.locator = login_locators["login.username"]class PasswordElement(BaseTextElement): def __init__(self): self.locator = login_locators["login.password"]class LoginPage(BasePage): username = UsernameElement() password = PasswordElement() def __init__(self, driver): BasePage.__init__(self, driver) self.open(login_locators.get("login.url")) def submit(self): "submit the login form" self.click_element(login_locators.get("login.submit")) @property def register(self): "jump to register page" self.click_element(login_locators["login.register"]) from register_page import RegisterPage return RegisterPage(self.driver)
3.base element
該頁面主要寫table,下拉式清單,輸入框等控制項的基類,以便頁面的控制項的繼承(上面登入頁面的輸入框就繼承於下面代碼的BaseTextElement類)
# _*_ coding=utf-8 _*_from selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.common.action_chains import ActionChainsclass BaseTextElement(object): """Base page class that is initialized on every page object class.""" def __set__(self, obj, value): """Sets the text to the value supplied""" dr = obj.driver WebDriverWait(dr, 100).until( lambda driver: driver.find_element(*self.locator)) dr.find_element(*self.locator).clear() dr.find_element(*self.locator).send_keys(value) def __delete__(self, obj): pass def __get__(self, obj, owner): """Gets the text of the specified object""" passclass BaseDropDownMenu(object): """Base DropDownMenu class that is initialized on every page object class.""" def __set__(self, obj, value): dr = obj.driver # element = dr.find_element(*self.btn_locator) # ActionChains(dr).click(element).perform() dr.find_element(*self.btn_locator).click() ul_element = dr.find_element(*self.ul_locator) if ul_element.tag_name.lower() != "select": # dr.find_element_by_link_text(u"%s" % value).click() dr.find_element_by_xpath(self.ul_locator[1] + "/li[{0}]".format(value)).click() else: try: dr.find_element(*self.ul_locator).click() except Exception: dr.find_element(*self.btn_locator).click() dr.find_element(*self.ul_locator).click() dr.find_element_by_css_selector("option[value=\"%s\"]" % value).click()class BaseTableElement(object): """Base table class that is initialized on every page object class.""" @property def column(self): column = len(self.driver.find_elements(*self.column_locator)) return column @property def row(self): row = len(self.driver.find_elements(*self.row_locator)) return row def get_element(self, *row_column): try: element = self.driver.find_element_by_xpath(self.tbody_locator + "/tr[{0}]/td[{1}]".format(*row_column)) return element except Exception as msg: print msg def get_cell_text(self, *value): # locator = "//*[@id=\"wrapper\"]/div/aside[2]/section/div/div/div/div/div/div/div/section/div[2]/table/tbody" if self.row: text = self.get_element(*value).text else: text = "Nothing" return text def get_x_column_all_cell_text(self, column): """get all value about some column and row-column , such as {value:(1,2)}""" text_row = {} if self.row: for i in range(1, self.row+1): temp = self.get_cell_text(i, column) text_row[temp] = i else: text_row = {} return text_row 4.以下就不再贅述相關的代碼塊了,有什麼不明白的地方可以討論下 ,如需下載整體代碼,地址: http://download.csdn.net/detail/lb245557472/9819007
參考: https://pragprog.com/magazines/2010-08/page-objects-in-python