Selenium的PageObject设计模式(1)

一、PageObject框架与线性脚本框架的基本思想区别

  1. PageObject:以页面作为类,页面中的所有控件作为属性,控件的操作作为方法
  2. 线性脚本框架:以模块化的思想拆分用例封装

二、PageObject框架搭建

  1. 项目包的目录结构(目录结构的清晰有利于框架的搭建)

        

  

  2.BasePage(公共方法的封装,包含:浏览器操作,元素操作,frame处理、windows句柄处理、alert处理、鼠标常用操作、键盘常用操作等封装)

  1 class BasePage(object):
  2     def __init__(self, driver):
  3         self.driver = driver
  4     # 浏览器操作封装->二次封装
  5     def open_url(self, url):
  6         self.driver.get(url)
  7         logger.info('打开url地址%s' % url)
  8 
  9     def set_browser_max(self):
 10         self.driver.maximize_window()
 11         logger.info('设置浏览器最大化')
 12 
 13     def refresh(self):
 14         self.driver.refresh()
 15         logger.info('浏览器刷新')
 16 
 17     def get_title(self):
 18         value = self.driver.title
 19         logger.info('获取标题:%s' % value)
 20         return value
 21 
 22     # 元素操作封装
 23     # 查找元素
 24     def find_element(self, element_info):
 25         locator_type_name = element_info['locator_type']
 26         locator_value_info = element_info['locator_value']
 27         locator_timeout = element_info['timeout']
 28         if locator_type_name == 'id':
 29             locator_type = By.ID
 30         elif locator_type_name == 'class':
 31             locator_type = By.CLASS_NAME
 32         elif locator_type_name == 'xpath':
 33             locator_type = By.XPATH
 41         element = WebDriverWait(self.driver, int(locator_timeout)) 
 42             .until(lambda x: x.find_element(locator_type, locator_value_info))
 43         # element_info怎么来的
 44         logger.info('[%s]元素识别成功' % element_info['element_name'])
 45         return element
 46 
 47     # 点击操作
 48     def click(self, element_info):
 49         element = self.find_element(element_info)
 50         element.click()
 51         logger.info('对[%s]元素进行点击操作' % element_info['element_name'])
 52 
 53     # 输入操作
 54     def input(self, element_info, content):
 55         element = self.find_element(element_info)
 56         element.send_keys(content)
 57         logger.info('[%s]元素输入内容:%s' % (element_info['element_name'], content))
 58 
 59     # 获取文本
 60     def get(self, element_info):
 61         element = self.find_element(element_info)
 62         value = element.text
 63         logger.info('获取[%s]元素内容为:%s' % (element_info['element_name'], value))
 64         return value
 71 
 72     # frame处理
 73     # 进入frame框
 74     def goto_frame(self, element_info):
 75         self.driver.switch_to.frame(element_info)
 76         # self.driver.switch_to.default_content()
 77         logger.info('定位至[%s]frame框' % element_info['element_name'])
 78 
 79     # 退出frame框
 80     def outo_frame(self):
 81         self.driver.switch_to.default_content()
 82         logger.info('退出frame框')
 83 
 84     # alert处理
 85     # alert处理,返回alert/confirm/prompt中的文字内容
 86     def alert_text(self):
 87         value = self.driver.switch_to_alert().text()
 88         logger.info('获取alert元素内容为:%s' % value)
 89         return value 105 
106 # 鼠标事件
107     # 鼠标右击元素
108     def contextclick(self, element_info):
109         element = self.find_element(element_info)
110         ActionChains.context_click(element).perform()
111         logger.info('鼠标右击[%s]元素' % element_info['element_name'])130 
131 # 键盘事件
132 # key_down 模拟键盘摁下某个按键 key_up 松开某个按键,与sendkey连用完成一些操作,每次down必须up一次否则将出现异常
133     # 全选数据
134     def SelectAll(self):
135         ActionChains.key_down(Keys.CONTROL).send_keys('A').key_up(Keys.CONTROL).perform()
136         logger.info('全选当前数据')

  3.ini文件做配置项管理

 1 current_path = os.path.dirname(__file__)
 2 cfgpath = os.path.join(current_path,'..//config/config_base.ini')
 3 
 4 class ConfigUtils:
 5     def __init__(self,config_path=cfgpath):
 6         self.__conf = configparser.ConfigParser()
 7         self.__conf.read(config_path, encoding='utf-8')
 8     def read_ini(self,sec,option):
 9         return self.__conf.get(sec,option)
10 
11     @property
12     def get_zentao_url(self):
13         value = self.read_ini('zentao', 'zentao_url')
14         return value
15     @property
16     def get_username(self):
17         value = self.read_ini('user', 'username')
18         return value
19     @property
20     def get_password(self):
21         value = self.read_ini('user', 'password')
22         return value
23 
24 conf = ConfigUtils()

   4. driver驱动的封装 

 1 class Set_Driver(object):
 2 
 3     def set_Chrome_driver():
 4         chrome_options=Options()
 5         # 谷歌文档提到需要加上这个规避bug
 6         chrome_options.add_argument('--disable-gpu')
 7         # 设置默认编码为utf-8
 8         chrome_options.add_argument('lang=zh_CN.UTF-8')
 9         # 取消chrome受自动化软件控制提示
10         chrome_options.add_experimental_option('useAutomationExtension',False)
11         #取消chrome受自动化软件控制提示
12         chrome_options.add_experimental_option("excludeSwitches",['enable-automation'])
13         conf = ConfigUtils()
14         driver = webdriver.Chrome(options=chrome_options)
15         driver.implicitly_wait(10)
16         driver.maximize_window()
17         url= conf.get_zentao_url
18         driver.get(url)
19         return driver
20 
21     def set_Firefox_driver(self):
22         conf = ConfigUtils()
23         driver = webdriver.Firefox()
24         driver.implicitly_wait(10)
25         driver.maximize_window()
26         url= conf.get_zentao_url
27         driver.get(url)
28         return driver 

  5.日志封装

 1 class LogUtils:
 2     def __init__(self,logfile_path = log_path ):
 3         self.logfile_path = logfile_path
 4         self.logger = logging.getLogger('Logger')
 5         self.logger.setLevel(level=logging.INFO)
 6         file_log = logging.FileHandler(self.logfile_path)
 7         formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 8         file_log.setFormatter(formatter)
 9         self.logger.addHandler(file_log)
10 
11     def info(self,message):
12         self.logger.info( message )
13 
14     def error(self,message):
15         self.logger.error(message)
16 
17 logger = LogUtils()

  6.具体页面元素举例(登录模块)

 1 class LoginPage(BasePage):
 2     def __init__(self,driver):
 3         super().__init__(driver)
 4 
 5          方式二:
 6          self.username_inputbox={'element_name':'用户名输入框',
 7                                  'locator_type':'xpath',
 8                                  'locator_value':'//input[@name="account"]',
 9                                  'timeout':3}
10          self.password_inputbox={'element_name':'密码输入框',
11                                  'locator_type':'xpath',
12                                  'locator_value':'//input[@name="password"]',
13                                  'timeout':3}
14          self.login_button={'element_name':'登录按钮',
15                                  'locator_type':'xpath',
16                                  'locator_value':'//button[@id="submit"]',
17                                  'timeout':10}
18 
19     # 方法-》控件的操作
20     # 输入用户名
21     def input_username(self, username):
22         # self.username_inputbox.send_keys(username)
23         # logger.info('用户名输入框输入:'+ str(username))
24         self.input(self.username_inputbox,username)
25     # 输入密码
26     def input_password(self, password):
27         # self.password_inputbox.send_keys(password)
28         # logger.info('密码输入框输入:'+str(password))
29         self.input(self.password_inputbox,password)
30     # 点击登录按钮
31     def click_login(self):
32         # self.login_button.click()
33         # logger.info("点击登录按钮成功")
34         self.click(self.login_button)
35 
36 if __name__ == "__main__":
37     # 用例1:登录成功用例
38     conf = ConfigUtils()
39     driver = Set_Driver.set_Chrome_driver()
40     login.test_login(conf.get_zentao_url,conf.get_username,conf.get_password,driver)
41 
42     time.sleep(3)
 


 

原文地址:https://www.cnblogs.com/wangyawen/p/12823248.html