优秀的框架都有属于自己的思想,在搭建web自动化测试框架时,我们通常都遵循 PO(Page Object)思想。

简单理解就是我们会把每个页面看成一个对象,一切皆对象,面向对象编码,这样会让我们更好的解耦代码,也更好的进行封装和理解。

使用selenium框架来操作页面时,最常用的都是一些点击,输入内容,页面切换等方法,如果每个页面我们都要写一遍这样的操作代码,重复性高,代码冗余。所以我们一般都会把这些共性的操作提取成一个基础类:BasePage。

以下是对该类的简单封装,还有其他的方法欢迎大家留言补充:

BasePage类:

  1. import com.ggf.selenium.taxcp.utils.BrowserUtil;
  2. import org.openqa.selenium.By;
  3. import org.openqa.selenium.JavascriptExecutor;
  4. import org.openqa.selenium.WebDriver;
  5. import org.openqa.selenium.WebElement;
  6. import org.openqa.selenium.support.ui.ExpectedConditions;
  7. import org.openqa.selenium.support.ui.WebDriverWait;
  8. import java.util.Set;
  9. /**
  10. * @Description: 页面基础类,将公共方法提取出来,如:获取元素内容,点击,等待。。。
  11. * @Author: ggf
  12. * @Date: 2021/05/15
  13. */
  14. public class BasePage {
  15. /**
  16. * 对元素进行点击
  17. * @param by 定位信息
  18. */
  19. public void click(By by) {
  20. waitElementClickable(by).click();
  21. }
  22. /**
  23. * 对元素输入内容
  24. * @param by 定位信息
  25. * @param datas 输入的内容
  26. */
  27. public void sendKeys(By by, String datas) {
  28. waitElementVisible(by).sendKeys(datas);
  29. }
  30. /**
  31. * 清除元素内容
  32. * @param by
  33. */
  34. public void clear(By by) {
  35. waitElementVisible(by).clear();
  36. }
  37. /**
  38. * 判断元素是否存在。
  39. * 使用isDisplayed() 方法,该方法判断某个元素是否在页面中存在,包含了:
  40. * visibility=hidden 或 display=none 时,只要在HTML代码中存在,
  41. * 就会返回true。
  42. * 扩展:
  43. * isEnable()-->用于判断input、select等元素是否可编辑。
  44. * isSelected()-->判断元素是否被选中。
  45. * @param by 定位信息
  46. * @return 存在:true 不存在:false
  47. */
  48. public boolean isElementExist(By by) {
  49. return waitElementVisible(by).isDisplayed();
  50. }
  51. /**
  52. * 获取元素文本内容
  53. * @param by 定位信息
  54. * @return 返回文本内容
  55. */
  56. public String getElementText(By by) {
  57. return waitElementVisible(by).getText();
  58. }
  59. /**
  60. * 获取元素属性值
  61. * @param by 定位信息
  62. * @param attributeName 属性名称
  63. * @return 返回属性值
  64. */
  65. public String getElementAttributeValue(By by, String attributeName) {
  66. return waitElementVisible(by).getAttribute(attributeName);
  67. }
  68. /**
  69. * 等待元素可见,显式等待10秒。
  70. * @param by 定位信息
  71. * @return 返回element对象
  72. */
  73. public WebElement waitElementVisible(By by) {
  74. WebDriverWait webDriverWait = new WebDriverWait(BrowserUtil.getDriver(),10);
  75. return webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(by));
  76. }
  77. /**
  78. * 等待元素可点击,显式等待10秒。
  79. * @param by 定位信息
  80. * @return 返回element对象
  81. */
  82. public WebElement waitElementClickable(By by) {
  83. WebDriverWait webDriverWait = new WebDriverWait(BrowserUtil.getDriver(), 10);
  84. return webDriverWait.until(ExpectedConditions.elementToBeClickable(by));
  85. }
  86. /**
  87. * 等待iframe可见并且根据By切换到iframe框架中
  88. * @param by 元素定位信息
  89. */
  90. public void waitIframeAndSwitch(By by) {
  91. WebDriverWait webDriverWait = new WebDriverWait(BrowserUtil.getDriver(), 10);
  92. webDriverWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(by));
  93. }
  94. /**
  95. * 等待iframe可见并且根据名称切换。
  96. * @param frameName iframe名称
  97. */
  98. public void waitIframeAndSwitch(String frameName) {
  99. WebDriverWait webDriverWait = new WebDriverWait(BrowserUtil.getDriver(), 10);
  100. webDriverWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameName));
  101. }
  102. /**
  103. * 滑动列表找元素并且进行点击
  104. * @param selectedText 选中元素文本
  105. * @param by 正在加载类似元素的定位表达式
  106. * @throws InterruptedException
  107. */
  108. public static void clickElementInList(String selectedText, By by) throws InterruptedException {
  109. // 滑动之前的页面源代码信息
  110. String beforeSource = "";
  111. // 滑动之后的页面源代码信息
  112. String afterSource = "";
  113. // 获取webdriver
  114. WebDriver driver = BrowserUtil.getDriver();
  115. // 循环条件
  116. // 1、找到了元素,跳出循环
  117. // 2、如果没有找到元素???怎么跳出循环
  118. while (true) {
  119. WebElement webElement = driver.findElement(by);
  120. beforeSource = driver.getPageSource();
  121. JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
  122. javascriptExecutor.executeScript("arguments[0].scrollIntoView(0);", webElement);
  123. // 如果当前页面有想要找的元素,怎么判断是否有??--getPageSource
  124. if (driver.getPageSource().contains(selectedText)) {
  125. driver.findElement(By.linkText(selectedText)).click();
  126. break;
  127. }
  128. Thread.sleep(1000);
  129. afterSource = driver.getPageSource();
  130. // 页面元素没有变化---滑动到了最底部
  131. if (afterSource.equals(beforeSource)) {
  132. break;
  133. }
  134. Thread.sleep(1500);
  135. }
  136. }
  137. /**
  138. * 滚动到指定元素上的方法
  139. * @param by 定位信息
  140. */
  141. public void scrollIntoElement(By by){
  142. WebElement webElement= waitElementVisible(by);
  143. JavascriptExecutor javascriptExecutor = (JavascriptExecutor) BrowserUtil.getDriver();
  144. javascriptExecutor.executeScript("arguments[0].scrollIntoView(0);", webElement);
  145. }
  146. /**
  147. * 根据title切换窗口的方法
  148. * @param title 窗口的标题
  149. */
  150. public void switchWindowByTitle(String title){
  151. WebDriver driver = BrowserUtil.getDriver();
  152. Set<String> handles = driver.getWindowHandles();
  153. // 切换窗口的方式--循环遍历handles集合
  154. for (String handle : handles) {
  155. //判断是哪一个页面的句柄??--根据什么来判断???title
  156. if(driver.getTitle().equals(title)){
  157. break;
  158. }else{
  159. //切换窗口--根据窗口标识来切换
  160. driver.switchTo().window(handle);
  161. }
  162. }
  163. }
  164. /**
  165. * 根据url内容切换窗口的方法
  166. * @param urlFlag 窗口的标题
  167. */
  168. public void switchWindowByUrl(String urlFlag){
  169. WebDriver driver = BrowserUtil.getDriver();
  170. Set<String> handles = driver.getWindowHandles();
  171. for (String handle : handles) {
  172. //根据url内容判断句柄
  173. if(driver.getCurrentUrl().contains(urlFlag)){
  174. break;
  175. }else{
  176. //切换窗口
  177. driver.switchTo().window(handle);
  178. }
  179. }
  180. }
  181. }

BrowserUtil类:

  1. import org.openqa.selenium.WebDriver;
  2. import org.openqa.selenium.chrome.ChromeDriver;
  3. import org.openqa.selenium.firefox.FirefoxDriver;
  4. import org.openqa.selenium.ie.InternetExplorerDriver;
  5. /**
  6. * @Description: 浏览器工具类,控制浏览器的生命周期,浏览器启动,关闭
  7. * @Author: ggf
  8. * @Date: 2021/05/15
  9. */
  10. public class BrowserUtil {
  11. /**
  12. *为解决多线程问题,通过ThreadLocal机制来控制
  13. */
  14. private static ThreadLocal<WebDriver> threadLocal = new ThreadLocal<WebDriver>();
  15. /**
  16. * 通过传入不同的浏览器名称,获取浏览器驱动
  17. * @param driverType 不同的浏览器 chrome ie Firefox
  18. */
  19. public static void setDriverType(String driverType) {
  20. // 判断输入内容是否为空。
  21. if (driverType != "" && driverType != null) {
  22. // 创建不同的浏览器驱动
  23. if ("chrome".equalsIgnoreCase(driverType)) {
  24. ChromeDriver chromeDriver = new ChromeDriver();
  25. setDriver(chromeDriver);
  26. }else if ("ie".equalsIgnoreCase(driverType)) {
  27. InternetExplorerDriver ieDriver = new InternetExplorerDriver();
  28. setDriver(ieDriver);
  29. }else if ("firefox".equalsIgnoreCase(driverType)) {
  30. FirefoxDriver fireDriver = new FirefoxDriver();
  31. setDriver(fireDriver);
  32. }
  33. }
  34. }
  35. /**
  36. * 从线程ThreadLocal中获取对象
  37. * @return
  38. */
  39. public static WebDriver getDriver() {
  40. return threadLocal.get();
  41. }
  42. /**
  43. * 设置对象到ThreadLocal中
  44. * @param driver
  45. */
  46. public static void setDriver(WebDriver driver) {
  47. threadLocal.set(driver);
  48. }
  49. /**
  50. * 关闭浏览器
  51. */
  52. public void closeBrowser() {
  53. getDriver().close();
  54. }
  55. }

web自动化框架—BasePage 类的简单封装的更多相关文章

  1. 基于Selenium的web自动化框架

    转自 : https://www.cnblogs.com/AlwinXu/p/5836709.html 1 什么是selenium Selenium 是一个基于浏览器的自动化工具,它提供了一种跨平台. ...

  2. 基于Selenium的Web自动化框架增强篇

    在写完上一篇“基于Selenium的Web自动化框架”(http://www.cnblogs.com/AlwinXu/p/5836709.html)之后一直没有时间重新审视该框架,正好趁着给同事分享的 ...

  3. 【转】基于Selenium的web自动化框架(python)

    1 什么是selenium Selenium 是一个基于浏览器的自动化工具,它提供了一种跨平台.跨浏览器的端到端的web自动化解决方案.Selenium主要包括三部分:Selenium IDE.Sel ...

  4. Web自动化框架LazyUI使用手册(2)--先跑起来再说(第一个测试用例-百度搜索)

    作者:cryanimal QQ:164166060 上篇文章中,简要介绍了LazyUI框架,本文便来演示,如何从无到有快速搭建基于lazyUI的工程,并成功运行第一个测试用例. 本文以百度搜索为例,选 ...

  5. Web自动化框架LazyUI使用手册(3)--单个xpath抓取插件详解(selenium元素抓取,有此插件,便再无所求!)

    概述 前面的一篇博文粗略介绍了基于lazyUI的第一个demo,本文将详细描述此工具的设计和使用. 元素获取插件:LazyUI Elements Extractor,作为Chrome插件,用于抓取页面 ...

  6. web自动化框架如何设计

    web自动化框架如何设计po模式总结: 1. 页面对象模型:当页面特别多的时候,代码更好的维护 2. Po是pageObject设计模式,用来管理和维护一组web元素的对象库 3. 每一个page c ...

  7. 关于Spring-JDBC测试类的简单封装

    关于Spring-JDBC测试类的简单封装 1.简单封装 /** * Created with IntelliJ IDEA. * * @Author: Suhai * @Date: 2022/04/0 ...

  8. Web自动化框架之五一套完整demo的点点滴滴(excel功能案例参数化+业务功能分层设计+mysql数据存储封装+截图+日志+测试报告+对接缺陷管理系统+自动编译部署环境+自动验证false、error案例)

    标题很大,想说的很多,不知道从那开始~~直接步入正题吧 个人也是由于公司的人员的现状和项目的特殊情况,今年年中后开始折腾web自动化这块:整这个原因很简单,就是想能让自己偷点懒.也让减轻一点同事的苦力 ...

  9. Web自动化框架LazyUI使用手册(1)--框架简介

    作者:cryanimal QQ:164166060 web端自动化简介 web端自动化,即通过自动化的方式,对Web页面施行一系列的仿鼠标键盘操作,以达到对Web页面的功能进行自动化测试的目的. 其一 ...

随机推荐

  1. polay计数原理

    公式: Burnside引理: 1/|G|*(C(π1)+C(π2)+C(π3)+.....+C(πn)): C(π):指不同置换下的等价类数.例如π=(123)(3)(45)(6)(7),X={1, ...

  2. 攻防世界 reverse android-app-100

     android-app-100  suctf-2016 jeb启动,找到点击事件: 验证流程: 输入作为参数 --> processObjectArrayFromNative 得到一返回值(r ...

  3. vue+element+oss实现前端分片上传和断点续传

    纯前端实现: 切片上传 断点续传 .断点续传需要在切上上传的基础上实现 前端之前上传OSS,无需后端提供接口.先上完整代码,直接复制,将new OSS里的参数修改成自己公司OSS相关信息后可用,如遇问 ...

  4. Windows + Jenkins + .NetFramework + SVN 持续部署

    Windows + Jenkins + .NetFramework + SVN 持续部署 环境准备 服务端环境 安装 Windows 服务器 1.阿里云购买临时服务器 阿里云:https://www. ...

  5. ICMP主机探测过程

    #1from scapy.all import * from random import randint from optparse import OptionParser #2 对用户输入的参数进行 ...

  6. Re:从零开始的Git保姆级使用教程

    观前提示: 本文主要介绍了用命令的方式对Git进行操作(全程用的win10系统),而对于TortoiseGit和github desktop等图形化操作知识,只进行简单介绍或提及,详细使用会在提到的地 ...

  7. k8s deployment 金丝雀发布 更新的 暂停 恢复 回滚

    假设现在有业务需求,计划将所有的nginx 从镜像版本1.14更新到1.15,这一次发布不紧需要平滑发布,还需要 金丝雀发布,及确认其中一个Pod没有问题后在进行剩余的更新. 暂停与恢复也可以使用ym ...

  8. 记一次xss漏洞挖掘

    博客园在整改中,无法更新文章,难受啊... 记录一次react的xss漏洞发现,比较有意思: 某个站: 直接输入<xxx>,直接把我跳转到了404,猜测可能做了一些验证: 尝试多重编码,发 ...

  9. OO第一单元总结——求导

    一.基于度量分析程序结构 (一)第一次作业 (1)设计思路 本次作业只涉及到简单幂函数通过加减运算而复合而成的函数,因此笔者自然的把函数分成了函数本体以及单个的项两个部分,在笔者的设计中两个类的功能如 ...

  10. 1035 Password

    To prepare for PAT, the judge sometimes has to generate random passwords for the users. The problem ...