微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python_Selenium 下basepage对元素的读取、获取元素属性、鼠标及键盘操作的封装及调用

目的:简化代码,提供框架该有的东西
一个函数 -提供了一个功能 - 公共的功能
有了basepage,在PageObjects当中直接调用元素操作。

以下以login_page 为例,实现从配置文件中读取基础信息,公共方法login.py的封装,从Excel中读取元素信息,login_page.py 调用basepage中公共操作方法操作。

一、basepage类代码如下:

#coding=gbk
import os
import time
from selenium import webdriver
from selenium.webdriver.common.by import By #导入by方法
from selenium.webdriver.support.wait import webdriverwait
from selenium.webdriver.common.action_chains import ActionChains ##对鼠标事件操作
from selenium.webdriver.common.keys import Keys # 对键盘事件操作
from common.log_utils import logger


class BasePage(object):
def __init__(self,driver):
self.driver=driver

# ------ -------------------------------------浏览器操作封装----------------------------------------------#
#打开网页
def open_url(self,url):
self.driver.get(url)
logger.info('打开URL地址%s;'%url)

def set_browser_max(self):
self.driver.maximize_window()
logger.info("设置浏览器的最大化")

def set_brower_min(self):
self.driver.minimize_window()
logger.info("设置浏览器的最小化")

def brower_refresh(self):
self.driver.refresh()
logger.info("浏览器的刷新操作")

def get_title(self):
value=self.driver.title
logger.info("获取网页的标题为:%s"%value)
return value
def quit_brower(self):
self.driver.quit()
logger.info("关闭浏览器")

# ------ ------------------------------------- 元素识别的封装----------------------------------------------#
def find_element(self,element_info):
locator_type_name=element_info['locator_type']
locator_value_info=element_info['locator_value']
locator_timeout=element_info['timeout']
if locator_type_name =='id':
locator_type=By.ID
elif locator_type_name=='class':
locator_type=By.CLASS_NAME
elif locator_type_name=='xpath':
locator_type=By.XPATH
#识别元素
element=webdriverwait(self.driver,locator_timeout)\
.until(lambda x:x.find_element(locator_type,locator_value_info))
logger.info('[%s]元素识别成功'%element_info['element_name'])
return element

# ------ -------------------------------------获取属性封装-------------------------------------#
#获取元素属性封装
def get_element_attribute(self,element_info,attribute_name):
element=self.find_element(element_info)
value=element.get_attribute(attribute_name)
logger.info('[%s]元素的%s的值为:%s'%(element_info['element_name'],attribute_name,value))
return value

#获取元素text属性封装
def get_text(self,element_info):
text=self.find_element(element_info).text
logger.info('[%s]元素的text值为:%s'%(element_info['element_name'],text))
return text

#------ ------------------------------------- 鼠标事件封装----------------------------------------------#
#元素鼠标操作封装:点击
def click(self,element_info):
element=self.find_element(element_info)
logger.info('[%s]元素进行点击操作'%element_info['element_name'])
element.click()

#元素鼠标操作:右击
def context_click(self,element_info):
mouse = ActionChains(self.driver)
element = self.find_element(element_info)
logger.info('[%s]元素进行右击操作' % element_info['element_name'])
mouse.context_click(element).perform()

#元素鼠标操作:移动到该元素上-
def moveto_element(self,element_info):
mouse = ActionChains(self.driver)
element = self.find_element(element_info)
logger.info('将鼠标移动到[%s]元素上' % element_info['element_name'])
mouse.move_to_element(element).perform()

def scrollIntoView(self,element_info):
element=self.find_element(element_info)
logger.info('将滚动条滚动至[%s]元素可见'%element_info['element_name'])
self.driver.execute_script('arguments[0].scrollIntoView();', element)
time.sleep(1)

# ------ ------------------------------------- 键盘事件封装-------------------------------------------#
# #键盘事件操作封装:输入内容
def input(self,element_info,content):
element=self.find_element(element_info)
element.send_keys(content)
logger.info('[%s]元素输入内容%s'%(element_info['element_name'],content))

#删除内容
def back_space(self,element_info):
element=self.find_element(element_info)
logger.info('[%s]元素操作back_space' % (element_info['element_name']))
element.send_keys(Keys.BACK_SPACE)

#清空内容-
def clear_input(self,element_info):
element=self.find_element(element_info)
logger.info('[%s]元素输入框操作清空' % (element_info['element_name']))
element.clear()

#按回车
def enter(self,element_info):
element=self.find_element(element_info)
logger.info('[%s]元素进行回车键操作' % (element_info['element_name']))
element.send_keys(Keys.ENTER)

#全选 Ctrl+a--测试OK
def ctrl_a(self,element_info):
element=self.find_element(element_info)
logger.info('[%s]元素输入框内容进行全选操作' % (element_info['element_name']))
element.send_keys(Keys.CONTROL, 'a')

#粘贴 Ctrl +x--测试OK
def ctrl_x(self,element_info):
element=self.find_element(element_info)
logger.info('[%s]元素输入框内容进行剪切操作' % (element_info['element_name']))
element.send_keys(Keys.CONTROL, 'x')

#粘贴 Ctrl +v--测试OK
def ctrl_v(self,element_info):
element=self.find_element(element_info)
logger.info('[%s]元素输入框内容进行粘贴操作' % (element_info['element_name']))
element.send_keys(Keys.CONTROL, 'v')

# ------ ------------------------------------- 弹窗封装----------------------------------------------#
#弹窗处理封装-测试OK
def get_alert_content(self,driver):
time.sleep(3)
alert = driver.switch_to.alert # 切换到js弹窗
value = alert.text
logger.info('当前弹窗的内容为:%s' % value)
time.sleep(1)
alert.accept()
logger.info('点击弹窗的确定按钮成功')
return value

# ------ -------------------------------------frame封装-----------------------------------------------#
#frame封装frame == > id/name frame元素对象
#思路一
def switch_to_frame(self,element_info):
element = self.find_element(element_info)
self.driver.switch_to.frame(element)
logger.info('[%s]frame元素切换成功' %(element_info["element_name"]))

#思路二
def switch_to_frame_id_or_name(self,id_or_name):
self.driver.switch_to.frame(id_or_name)
def switch_to_frame_by_element(self,element_info):
element = self.find_element(element_info)
self.driver.switch_to.frame(element)
logger.info('[%s]frame元素切换成功' % (element_info["element_name"]))

# ------ -------------------------------------切换句柄封装-------------------------------------------#
##方式一
def switch_window_by_title(self,title):
for handle in self.driver.window_handles:
self.driver.switch_to.window(handle)
if self.driver.title.__contains__(title):
break
logger.info('切换到网页标题为[%s]的句柄成功!'%title)

#方式二
def switch_window_by_url(self,url):
for handle in self.driver.window_handles:
self.driver.switch_to.window(handle)
if self.driver.current_url.__contains__(url):
break
logger.info('切换到URL为[%s]的句柄成功!' % url)

二、调用如下(以登录为例):

(1)login_page.py 主代码如下:
#coding=gbk
import os
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from common.log_utils import logger
from common.base_page import BasePage
from common.config_utils import config
from common import login
from common.set_driver import set_driver
from common.element_data_utils import ElementdataUtils
from common.element_yamldate_utils import ElementdataYamlUtils

class LoginPage(BasePage):
def __init__(self,driver):
super().__init__(driver)
####-----------------第一种方式,直接写字典形式---------------------####
# self.username_inputBox = {'element_name':'用户名输入框',
# 'locator_type':'xpath',
# 'locator_value':'//input[@name="account"]',
# 'timeout': 5 }
# self.password_inputBox = {'element_name': '密码输入框',
# 'locator_type': 'xpath',
# 'locator_value': '//input[@name="password"]',
# 'timeout': 4}
# self.login_button = {'element_name': '登录按钮',
# 'locator_type': 'xpath',
# 'locator_value': '//button[@id="submit"]',
# 'timeout': 2}
####-----------------第二种方式,使用excecl读取---------------------####
elements=ElementdataUtils('login_page').get_element_info()
#####公共####
self.username_inputBox =elements['username_inputBox']
self.password_inputBox=elements['password_inputBox']
self.login_button=elements['login_button']
self.change_language=elements['change_language']

def input_username(self,username): #方法 == 》控件的操作
self.input( self.username_inputBox , username )


def input_password(self,password):
self.input( self.password_inputBox , password )

def click_login(self):
self.click( self.login_button )

def moveto_change_language(self):
self.moveto_element(self.change_language)


if __name__=="__main__":
from common.base_page import BasePage
driver=set_driver()
login_page = LoginPage(driver)
login.test_login(config.get_url,config.get_user_name,config.get_password,driver) ##因为封装了登录方法,直接调用即可

(2)公共方法登录login.py封装
from selenium import  webdriver
from element_infos.login_page import LoginPage
from common.config_utils import config
from common.set_driver import set_driver

def test_login(url, username, password, driver):
driver.get(url)
login = LoginPage(driver)
login.input_username(username)
login.input_password(password)
login.click_login()

(3)公共方法:config_utils.py 配置信息封装
import  os
import configparser

current_path = os.path.dirname(__file__)
cfgpath = os.path.join(current_path, "../conf/local_config.ini")
print(cfgpath)


class ConfigUtils:
def __init__(self,config_path=cfgpath):
self.__conf=configparser.ConfigParser() ##做成私有实例属性,仅在类的内部使用,外部不可访问,也提高使用的简洁度
self.__conf.read(config_path, encoding="utf-8")

def read_ini(self,sec,option):
value=self.__conf.get(sec,option)
return value

@property #添加这个可将该类的这个方法变成一个属性,直接调用类的属性就可以
def get_url(self):
value=self.read_ini('default','url')
return value


@property #添加这个可将该类的这个方法变成一个属性,直接调用类的属性就可以
def get_user_name(self):
value=self.read_ini('user','user_name')
return value

@property
def get_password(self):
value = self.read_ini('user', 'password')
return value

@property
def get_error_user_name(self):
value=self.read_ini('user','error_user_name')
return value

@property
def get_error_password(self):
value = self.read_ini('user', 'error_password')
return value


config=ConfigUtils() #直接定义一个方法,在外部直接调用方法就可以,不需要再每次都创建一个对象


if __name__=='__main__':
current_path = os.path.dirname(__file__)
cfgpath = os.path.join(current_path, "../conf/local_config.ini")
config_u=ConfigUtils()
print(config_u.get_url)
print(config_u.get_user_name)
print(config_u.get_password)

local_config.ini配置如下:
[default]
url=http://127.0.0.1/zentao/user-login-L3plbnRhby9teS5odG1s.html

[user]
user_name = admin
password = XXXXXXX

(4)公共方法:element_data_utils.py  配置信息封装
import  os
import xlrd

current_path=os.path.dirname(__file__)
excel_path=os.path.join(current_path,'../element_info_datas/element_infos.xlsx')

class ElementdataUtils:
def __init__(self,page_name,element_path=excel_path):
self.element_path=element_path
self.workbook = xlrd.open_workbook(excel_path)
self.sheet = self.workbook.sheet_by_name(page_name)
self.row_count=self.sheet.nrows

def get_element_info(self):
element_infos = {}
for i in range(1, self.sheet.nrows):
element_info = {}
element_info['element_name'] = self.sheet.cell_value(i, 1)
element_info['locator_type'] = self.sheet.cell_value(i, 3) ##所属页面不要取值
element_info['locator_value'] = self.sheet.cell_value(i, 4)
element_info['timeout'] = self.sheet.cell_value(i, 5)
element_infos[self.sheet.cell_value(i, 0)] = element_info
return element_infos


if __name__ == '__main__':
print(ElementdataUtils('login_page').get_element_info())
print(ElementdataUtils('main_page').get_element_info()

元素Excel信息配置:

(4)公共方法:set_driver.py  浏览器简单封装
from selenium import webdriver
from common.config_utils import config
from selenium.webdriver.chrome.options import Options


def set_driver():
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('disable-infobars')
driver = webdriver.Chrome(options=chrome_options)
driver.maximize_window()
return driver

if __name__ == '__main__':
set_driver()

结论:

一、在login_page.py 中,引入basepage,定义元素字典信息(字典信息在Excel中存放),定义当前login页面的元素操作(loginpage对元素操作此处调用basepage中公共的元素操作方法--->basepage内部再去调用basepage中的元素识别和元素操作),各个模块方法组合调用,PO模式实现登录

二、将常用的方法做成公共方法,方便调用,比如对元素信息的读取,登录方法login.py,配置文件的读取等。

三、测试数据和代码分离,方便维护,比如excecl存放元素信息,采用xlrd模块读取数据为字典形式。



版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐