lsekfe 发表于 2020-11-2 09:22:18

Python Selenium自动化进阶线性脚本到PO模式拆分

写在前面:在研究po模式拆分时,在网上找了大量的资料,基本都是提供思路及结果,对于如果一步一步如果从线性脚本到函数再到po模式转化的文章少之又少,类似于小白的同学到这一个过程无疑是痛苦的,这种经历只有体会过的同学才会懂。
  这篇文章是我在参考大量视频、网上资料、自己实践总结出来的,希望读完后大家有所收获。
       1.什么是PO模式
  PO是一种设计模式,核心思想是每个页面定义一个单独的类,类中包含元素所需要的对象及方法
  2.PO模式优点
  ·使代码结构清晰:po模式使页面元素操作和业务流程相分离
  ·方便复用:相同功能可多次调用
  ·页面元素发生变化时,直接修改封装好的页面元素就可以
  3.实例演示PO模式拆分
  本例采用三层模式,对象库层+逻辑层+业务数据层
  对象库层:base层,封装常用的方法如click,doubleclick,元素定位,功能封装等
  逻辑层:页面功能逻辑实现
  业务数据层:通过传入参数,调用逻辑层功能
  4.代码实现逻辑
  首先,整个功能线性脚本编写实现
  其次,线性脚本到函数封装
  最后,函数拆分都不同层次页面
  目的:一个线性脚本test_2_modify_plan.py文件拆分成上图中的3个文件内
  4.1 线性脚本
  源码1.0版本:这部分仅仅实现登录->新建->填写数据->提交这一过程。

 from selenium import webdriver#导入webdriver

  from time import sleep #导入sleep

  from selenium.webdriver.common.action_chains import ActionChains#导入ActionChains

  from page_object.LoginPage import * #导入page_object文件夹下的LoginPage函数,登录功能

  from selenium.webdriver.support.select import Select#导入Select 方法

  from model import function,myunit #从model文件夹导入 function,myunit函数

  #打开chrome浏览器

  chrome_options = webdriver.ChromeOptions()

  chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])

  driver = webdriver.Chrome(options=chrome_options)

  driver.get("http://127.0.0.1:8080/portal-web/framework/login?")

  driver.maximize_window()

  输入用户名、密码ver.find_element_by_name("username").send_keys('b')

  driver.find_element_by_id('password').send_keys('11qq!!')

  driver.find_element_by_id('dlu').click()

  sleep(3)

  ul1#进入三级目录=driver.find_element_by_xpath("//*")

  ActionChains(driver).double_click(ul1).perform()

  ul2=driver.find_element_by_xpath("//*")

  ActionChains(driver).double_click(ul2).perform()

  ul3=driver.find_element_by_xpath("//*")

  ActionChains(driver).double_click(ul3).perform()

  sleep(3)

  #主页面点击新建

  driver.switch_to.frame('data_iframe')

  driver.find_element_by_xpath('//*[@id="grid"]/div/a').click()

  sleep(3)

  # 第二个iframe填写内容新建

  #下拉菜单非select类型,直接定位选择内容

  iframe1 = driver.find_element_by_xpath('//*[@title="新建页面"]')

  driver.switch_to.frame(iframe1)

  iframe2=driver.find_element_by_xpath("//iframe")

  driver.switch_to.frame(iframe2)

  driver.find_element_by_xpath('//*[@id="myform"]/table/tbody/tr/td/span/span/span').click()

  sleep(2)

  driver.find_element_by_xpath("//*").click()

  sleep(2)

  driver.find_element_by_xpath('//*[@id="myform"]/table/tbody/tr/td/span/span').click()

  sleep(1)

  driver.find_element_by_xpath("//*").click()

  sleep(1)

  #完成时间控件选择

  js = "$('.kendoDate').removeAttr('readonly')"# jQuery,移除属性

  driver.execute_script(js)

  input_datetime = driver.find_element_by_xpath('//*[@id="myform"]/table/tbody/tr/td/span/span')

  sleep(2)

  driver.find_element_by_xpath('//*[@id="myform"]/table/tbody/tr/td/span/span/input').send_keys("2020-06-22")

  #认证日期

  driver.find_element_by_xpath('//*[@id="mybody"]/tr/td/span/span/input').send_keys('2020-06-22')

  driver.find_element_by_xpath('//*[@id="mybody"]/tr/td/span/span/input').send_keys('2020-06-22')

  #文本框输入

  driver.find_element_by_xpath('//*[@data-isq="工作项目"]').send_keys("您好")

  sleep(1)

  driver.find_element_by_xpath('//*[@data-isq="详细计划"]').send_keys("您好")

  sleep(1)

  #

  drer.find_element_by_xpath('//*[@data-isq="供应商名称"]').send_keys("您好")

  sleep(1)

  driver.find_element_by_xpath('//*[@data-isq="制造地址/邮编"]').send_keys("您好")

  sleep(1)

  driver.find_element_by_xpath('//*[@data-isq="电话/传真"]').send_keys("您好")

  sleep(1)

  driver.find_element_by_xpath('//*[@data-isq="认证产品"]').send_keys("您好")

  sleep(1)

  #树形结构

  #批准人

  driver.find_element_by_xpath('//*[@data-isq="计划审核人"]').click()

  people=driver.find_element_by_xpath('//*[@title="人员选择"]')

  driver.switch_to.frame(people)

  sleep(2)

  driver.find_element_by_id('searchbox').send_keys('b')

  sleep(2)

  driver.find_element_by_xpath('//*[@id="myeorgrid"]/div/table/tbody/tr/td').click()

  sleep(2)

  driver.find_element_by_xpath('//*[@id="okButton"]').click()

  sleep(2)

  #计划批准人

  driver.switch_to.parent_frame()

  driver.find_element_by_xpath('//*[@data-isq="计划批准人"]').click()

  people=driver.find_element_by_xpath('//*[@title="人员选择"]')

  driver.switch_to.frame(people)

  sleep(2)

  driver.find_element_by_id('searchbox').send_keys('b')

  sleep(2)

  driver.find_element_by_xpath('//*[@id="myeorgrid"]/div/table/tbody/tr/td').click()

  sleep(2)

  driver.find_element_by_xpath('//*[@id="okButton"]').click()

  sleep(2)

  #担当人

  driver.switch_to.parent_frame()

  driver.find_element_by_xpath('//*[@data-isq="担当人"]').click()

  people=driver.find_element_by_xpath('//*[@title="人员选择"]')

  driver.switch_to.frame(people)

  sleep(2)

  driver.find_element_by_id('searchbox').send_keys('b')

  sleep(2)

  driver.find_element_by_xpath('//*[@id="myeorgrid"]/div/table/tbody/tr/td').click()

  sleep(2)

  driver.find_element_by_xpath('//*[@id="okButton"]').click()

  sleep(2)

  #跳回frame1

  driver.switch_to.parent_frame()

  driver.switch_to.parent_frame()

  driver.find_element_by_id("buttons2").click()

  driver.find_element_by_xpath('//*[@id="header"]/div/div/span/a').click()

  driver.switch_to.default_content()

  #切换其他窗体

  driver.quit() 4.2 函数封装
  1) 重构-元素定位优化
  将1.0代码内容进行重构,基本思路按功能实现先对元素定位进行函数封装,再进行调用
  ·封装定位方法
  ·功能区调用封装好的方法
  ·建议每次改写一个小功能,改写完成后进行调试,切近全部一次性改写,工作量太大。
  ·在原有py文件旁在新建一个py文件,每次拷贝一小段功能进行改写
  代码2.0版本
  将代码用函数封装起来:

from selenium import webdriver

  from time import sleep

  from selenium.webdriver.common.action_chains import ActionChains

  from page_object.LoginPage import *

  from selenium.webdriver.support.select import Select

  from model import function,myunit

  # chrome_options = webdriver.ChromeOptions()

  # chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])

  #driver = webdriver.Chrome()

  driver=webdriver.Firefox()

  driver.get("http://127.0.0.1:8080/portal-web/framework/login?")

  driver.maximize_window()

  #函数封装

  def ty_name(driver,na):

      return driver.find_element_by_name(na)

  def ty_id(driver,i):

      return driver.find_element_by_id(i)

  def ty_xpath(driver,xxpath):

      return driver.find_element_by_xpath(xxpath)

  #

  def double_click(driver,element):

      return ActionChains(driver).double_click(element).perform

  def ty_switch_to_frame(driver,frame):

      return driver.switch_to.frame(frame)

  def ty_switch_to_default_frame(driver):

      return driver.switch_to.default_content()

  def ty_switch_to_parent_frame(driver):

      return driver.switch_to.parent_frame()

  def js(driver,ele):

      driver.execute_script("$("+"'"+ele+"'"+").removeAttr('readonly')")

  js(driver,'.kendoDate')

  #登录功能

  ty_name(driver,"username").send_keys('b')

  ty_id(driver,'password').send_keys('11qq!!')

  ty_id(driver,'dlu').click()

  sleep(3)

  #目录导航

  ul1=driver.find_element_by_xpath("//*")

  ActionChains(driver).double_click(ul1).perform()

  ul2=driver.find_element_by_xpath("//*")

  ActionChains(driver).double_click(ul2).perform()

  ul3=driver.find_element_by_xpath("//*")

  ActionChains(driver).double_click(ul3).perform()

  sleep(1)

  #主页面点击新建

  #主页frame,点击新建按钮

  ty_switch_to_frame(driver,'data_iframe')

  ty_xpath(driver,'//*[@id="grid"]/div/a').click()

  sleep(3)

  # 第二个iframe填写内容新建

  #下拉菜单非select类型,直接定位选择内容

  iframe1 = ty_xpath(driver,'//*[@title="新建页面"]')

  ty_switch_to_frame(driver,iframe1)

  sleep(1)

  iframe2 = ty_xpath(driver,"//iframe")

  ty_switch_to_frame(driver,iframe2)

  sleep(1)

  #选择年份

  ty_xpath(driver,'//*[@id="myform"]/table/tbody/tr/td/span/span/span').click()

  sleep(1)

  ty_xpath(driver,"//*").click()

  #工作类别

  sleep(1)

  ty_xpath(driver,'//*[@id="myform"]/table/tbody/tr/td/span/span').click()

  sleep(1)

  ty_xpath(driver,"//*").click()

  sleep(1)

  #完成时间控件选择

  input_datetime=ty_xpath(driver,'//*[@id="myform"]/table/tbody/tr/td/span/span')

  sleep(2)

  ty_xpath(driver,'//*[@id="myform"]/table/tbody/tr/td/span/span/input').send_keys("2020-06-22")

  #认证日期

  ty_xpath(driver,'//*[@id="mybody"]/tr/td/span/span/input').send_keys('2020-06-22')

  ty_xpath(driver,'//*[@id="mybody"]/tr/td/span/span/input').send_keys('2020-06-22')

  #文本框输入

  ty_xpath(driver,'//*[@data-isq="工作项目"]').send_keys("您好")

  sleep(1)

  ty_xpath(driver,'//*[@data-isq="详细计划"]').send_keys("您好")

  sleep(1)

  #

  ty_xpath(driver,'//*[@data-isq="供应商名称"]').send_keys("您好")

  sleep(1)

  ty_xpath(driver,'//*[@data-isq="制造地址/邮编"]').send_keys("您好")

  sleep(1)

  ty_xpath(driver,'//*[@data-isq="电话/传真"]').send_keys("您好")

  sleep(1)

  ty_xpath(driver,'//*[@data-isq="认证产品"]').send_keys("您好")

  sleep(1)

  #树形结构

  #批准人

  ty_xpath(driver,'//*[@data-isq="计划审核人"]').click()

  people=ty_xpath(driver,'//*[@title="人员选择"]')

  ty_switch_to_frame(driver,people)

  sleep(1)

  ty_id(driver,'searchbox').send_keys('b')

  sleep(1)

  ty_xpath(driver,'//*[@id="myeorgrid"]/div/table/tbody/tr/td').click()

  sleep(1)

  ty_xpath(driver,'//*[@id="okButton"]').click()

  sleep(1)

  #计划批准人

  driver.switch_to.parent_frame()

  sleep(1)

  ty_xpath(driver,'//*[@data-isq="计划批准人"]').click()

  people=ty_xpath(driver,'//*[@title="人员选择"]')

  sleep(1)

  ty_switch_to_frame(driver,people)

  sleep(1)

  ty_id(driver,'searchbox').send_keys('b')

  sleep(1)

  ty_xpath(driver,'//*[@id="myeorgrid"]/div/table/tbody/tr/td').click()

  sleep(1)

  ty_xpath(driver,'//*[@id="okButton"]').click()

  sleep(1)

  #担当人

  ty_switch_to_parent_frame(driver)

  ty_xpath(driver,'//*[@data-isq="担当人"]').click()

  people=ty_xpath(driver,'//*[@title="人员选择"]')

  ty_switch_to_frame(driver,people)

  sleep(1)

  ty_id(driver,'searchbox').send_keys('b')

  sleep(1)

  ty_xpath(driver,'//*[@id="myeorgrid"]/div/table/tbody/tr/td').click()

  sleep(1)

  ty_xpath(driver,'//*[@id="okButton"]').click()

  sleep(1)

  #跳回frame1

  ty_switch_to_parent_frame(driver)

  ty_switch_to_parent_frame(driver)

  ty_id(driver,"buttons2").click()

  ty_xpath(driver,'//*[@id="header"]/div/div/span/a').click()

  ty_switch_to_default_frame(driver)

  #切换其他窗体

  driver.quit()

Miss_love 发表于 2020-12-25 13:38:21

支持分享
页: [1]
查看完整版本: Python Selenium自动化进阶线性脚本到PO模式拆分