selenium+Page Objects(第二话)

前面介绍了什么是po模式,并且简单分析了一下使用po模式编写脚本的思路,接下来开始正式编写

1.先编写一个页面基类BasePage.py,里面封装每个页面常用的一些方法

# coding: utf-8
# author: hmk
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException


class BasePage(object):  # 如果没有明确要继承的类,默认继承object,当然这里留空也行
    """基类封装其他页面都会用到的方法"""

    base_url = 'http://localhost/UnifiedReporting/bid/caption?'

    def __init__(self, driver):
        self.driver = driver   # 构造器中定义一个driver驱动,后续所有操作都引用这个driver,保持前后driver一致性

    def open(self, url):
        """定义打开url方法"""
        url = self.base_url + url
        self.driver.get(url)
        self.driver.maximize_window()

    def find_element(self, *locator):
        """定位页面元素位置的方法"""
        try:
            # element = WebDriverWait(self.driver, 30).until(lambda x: x.find_element(*locator))  # 这个方法我没有成功,总是定位不到元素
            element = WebDriverWait(self.driver, 30).until(EC.presence_of_element_located(locator))
            return element   # 返回页面元素的位置对象 # 类型是<class 'selenium.webdriver.remote.webelement.WebElement'>
        except NoSuchElementException:
            print("%s 页面中未能找到 %s 元素" % (self, locator))

    def switch_frame(self, loctor):
        """切换iframe表单"""
        return self.driver.switch_to_frame(loctor)

    def script(self, src):
        """执行js脚本"""
        self.driver.execute_script(src)

    def send_keys(self, locator, value, clear_first=True):
        """封装send_keys()方法"""
        try:
            # locator = getattr(self, "_%s"% locator)
            if clear_first:
                self.find_element(*locator).clear()   # 判断是否需要清除输入框信息
            self.find_element(*locator).send_keys(value)
        except AttributeError:
            print("%s 页面中未找到 %s 元素" % (self, locator))

    def click(self, locator):
        """封装click()方法"""
        self.find_element(*locator).click()

    def get_current_url(self):
        """获取当前页面url"""
        return self.driver.current_url

    def get_url_title(self):
        """获取当前页面title"""
        return self.driver.title

注释写得也比较详细,不过多赘述了,后续需要其他操作的话,也可以继续添加进来

2.编写locators文件,把每个页面中的元素位置都事先定义好

# coding: utf-8
# author: hmk

from selenium.webdriver.common.by import By


class Locators(object):
    """元素定位器"""
    first_page_locators = {
        "agree_button": (By.ID, "btn_argee"),
        "disagree_button": (By.XPATH, "//a[@aria-label='不同意']")
    }
    second_page_locators = {
        "handle": (By.ID, "start_handle"),
        "back": (By.XPATH, "//a[text()='上一步']")
    }
    third_page_locators = {
        "custName": (By.NAME, "custName"),  # 企业名称
        "custAddr": (By.NAME, "custAddr"),  # 企业地址
        "custLegalMan": (By.NAME, "custLegalMan"),   # 法定代表人
        "custCerId": (By.NAME, "custCerId"),   # 法定代表人证件
        "custContactPerson": (By.NAME, "custContactPerson"),  # 经办人姓名
        "custCardId": (By.NAME, "custCardId"),   # 经办人证件
        "nextstep": (By.ID, "basicinfo_next_btn"),   # 下一步
        "backstep": (By.XPATH, "//a[text()='上一步']")   # 上一步
    }
    fourth_page_locators = {
        "upload_button1": (By.XPATH, ".//*[@id='uploadAttachList_body']/tr[1]/td[5]/a"),  # 材料列表第一个材料的上传按钮
        "upload_true": (By.CSS_SELECTOR, "#i_select_files>input"),  # 去掉上传隐藏属性后的真实上传按钮
        "upload_t": (By.XPATH, "//div[@class='layui-layer-content']//a[@aria-label='本地上传']"),  # 必须双斜杠
        "confirm": (By.XPATH, "//div[@class='layui-layer-content']//a[text()='确定']"),   # 上传弹窗的确定按钮
        "nextstep": (By.ID, "upload_next_btn"),  # 下一步按钮
        "backstep": (By.CLASS_NAME, "btn")  # 上一步按钮
    }


if __name__ == "__main__":
    t = Locators()
    print(t.first_page_locators["agree_button"])

这里简单地把所有页面中用到的元素都写在了这里面,每个页面各自以字典形式存放元素,当然也可以拆分为几个文件分别存放,后面元素位置发生变化,可以在这里修改


2018-05-11 11:54:42

原文地址:https://www.cnblogs.com/hanmk/p/9023829.html