PO库设计与实现
元素定位方式封装
写一个locators.yml文件
LoginPage:
email_input: ['id','email']
pwd_input: ['id','password']
login_btn: ['css selector','.MuiButton-containedPrimary']
MainPage:
task_input: ['id','task']
读取配置文件
#读取配置文件
self.locators=read_yml('conf/locators.yml')['LoginPage']
但是这样,不管是哪个页面进来只能读取到LoginPage页面的元素
class BasePage:
def init(self):
self._driver=WebdriverCreater().get_browser()
#读取配置文件
current_class=self.class.name
self.locators=read_yml('conf/locators.yml')[current_class]
实现登录方法
class LoginPage(BasePage):
def __init__(self):
super().__init__()
self.email_input=self.locators['email_input']
self.pwd_input=self.locators['pwd_input']
self.login_btn=self.locators['login_btn']
def login(self,email,pwd):
self.input_text(self.email_input,email)
self.input_text(self.pwd_input,pwd)
self.click(self.login_btn)
假如MainPage里面也需要元素操作,那么也要进行初始化,其他页面也要这么操作,那我们有更好的方法来减少重复性的操作吗?
我们现在是不断的给这个属性赋值,那有没有方法可以进行批量操作呢?
python是动态类型的语言,那python就有方法动态给属性赋值
配置信息读取出来,是一个个字典,那我们就可以通过遍历进行不断的赋值
#动态赋值元素属性--key ,value
self.setattr(self.email_input,self.locators['email_input'])
在basepage的init方法里面操作
def __init__(self):
self._driver=WebdriverCreater().get_browser()
#读取配置文件
current_class=self.__class__.__name__
self.locators=read_yml('conf/locators.yml')[current_class]
#动态赋值元素属性
for key in self.locators:
self.__setattr__(key,self.locators[key])# 参数:1属性,2属性值
至此为止,basepage框架基本搭好了
实现业务类--链式调用
现在需要实现具体的业务类
if name == 'main':
LoginPage().login('xx','xxx')
MainPage().to_schedule()
正常情况是这么实现,每一个页面都要实例化,然后再调用具体的方法
那我们可以这样实现吗?
LoginPage().login('xx','xxx').to_schedule()
这样实现的好处是进行链式调用,简化我们的代码
利用login方法的返回值,让login方法返回一个对象,然后通过返回的对象调用实例的方法来实现
def login(self,email,pwd):
self.input_text(self.email_input,email)
self.input_text(self.pwd_input,pwd)
self.click(self.login_btn)
return MainPage()
class MainPage(BasePage):
def to_schedule(self):
#点击日程
self.click(self.schedule_btn)
return SchedulePage()
接下来实现创建日程的方法
创建日程
class SchedulePage(BasePage):
def new_schedule(self):
pass
#点击日程
#点击新建按钮
#输入主题
#点击指派
#清除已选
#选择目标用户
接下来获取页面元素定位表达式,保存到配置文件中
class SchedulePage(BasePage):
def new_schedule(self,sumary,target):
#点击新建按钮
self.click(self.new_btn)
#输入主题
self.input_text(self.sumary_input,sumary)
#点击指派
self.click(self.select_btn)
清除已选,需要操作多个元素,通过for循环进行点击操作,for循环放到业务逻辑里面不合理,操作多个元素也是一个通用方法,其他页面也有可能用到,在common中封装一个通用方法
#点击多个元素
def click_multi(self):
eles=self._driver.find_elements()
for ele in eles:
ele.click()
选择目标元素,通过什么来选择目标元素呢?观察发现可以通过文本来选择,那我们又封装一个方法来实现
#根据文本选择目标元素
def select_target_by_text(self,locator,text):
eles=self._driver.find_elements(*locator)
for ele in eles:
if ele.text==text:
ele.click()
break
class SchedulePage(BasePage):
def new_schedule(self,sumary,target):
#点击新建按钮
self.click(self.new_btn)
#输入主题
self.input_text(self.sumary_input,sumary)
#点击指派
self.click(self.select_btn)
#清除已选
self.click_multi(self.selected_users)
#选择目标用户
self.select_target_by_text(self.target_users,target)
class SchedulePage(BasePage):
def new_schedule(self,sumary,target):
#点击新建按钮
self.click(self.new_btn)
#输入主题
self.input_text(self.sumary_input,sumary)
#点击指派
self.click(self.select_btn)
#清除已选
self.click_multi(self.selected_users)
#选择目标用户
self.select_target_by_text(self.target_users,target)
#点击确认
self.click(self.confirm_btn)
#点击保存
self.click(self.save_btn)
if __name__ == '__main__':
LoginPage().login('gavin@test.com','123456').to_schedule().new_schedule('早会','猪八戒')
css包含模式: