Page Object Model (Selenium + Python)(三)

本文介绍了一个基于Python的PageObject框架实现细节,包括基础页面、登录页面等模块的设计与代码示例,适用于自动化测试项目的开发。

     基于对前边几篇文章的参考,自己根据系统需求写了一个pageobject的框架。主要树形结构如下图:

                    

 

以下是个别代码块:

1.base page模块

该parent页面主要每个页面都可能用到的方法,以便后面页面的继承(有的方法没写完整,用的时候可以自行添加)

 

# _*_ coding=utf-8 _*_

from abc import abstractmethod
from pageobject.log.logger import Logging
import time
from selenium.webdriver.common.action_chains import ActionChains


class 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 WebDriverWait
from base_page import BasePage
from pageobject.parameter.locator_element import login_locators
from base_element import BaseTextElement


class 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 WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains


class 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"""
        pass


class 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.以下就不再赘述相关的代码块了,有什么不明白的地方可以讨论下,如需下载整体代码(github),地址:http://download.youkuaiyun.com/detail/lb245557472/9819007
参考:https://pragprog.com/magazines/2010-08/page-objects-in-python

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值