当前位置: 首页 > news >正文

selenium(二)基于java、元素操控、Frame切换、元素等待

元素操控

选择到元素之后,我们的代码会返回元素对应的 WebElement对象,通过这个对象,我们就可以 操控 元素

输入sendKeys

项目实战:在网银环境下载流水[交易明细]的时候,需要指定查询日期,有些银行是可以直接输入起止日期的

sendKeys在元素(如输入框元素)中输入字符串

WebElement input = driver.findElement(By.id("key"));
//清空输入框
input.clear();
//在输入框中输入内容
input.sendKeys("蓝牙耳机");

对于input输入框的元素,要获取里面的输入文本

// 找到元素
WebElement element = driver.findElement(By.id("usernameid"));        
element.getAttribute("value");

点击click

click点击元素

//单击搜索按钮
driver.findElement(By.xpath("//*[@id='search']/div/div[2]/button")).click();

下拉框[select]

项目实战:在网银环境中选择账号,选择交易类型等等

如下是标准的select标签中,如下:

选择下拉列表中的值呢

  • selectByValue 语法
  • selectByVisibleText 语法
  • select.selectByIndex()语法;

简单场景举例如下,选择下拉框变为 “10进制”转"16进制"

 webDriver.get("https://tool.ip138.com/hexconvert/");//选择10进制WebElement webElementFrom = webDriver.findElement(By.xpath("//*[@id=\"from_type\"]"));Select fromDropList = new Select(webElementFrom);fromDropList.selectByVisibleText("10进制");//选择16进制WebElement webElementTo = webDriver.findElement(By.xpath("//*[@id=\"to_type\"]"));Select toDropList = new Select(webElementTo);toDropList.selectByVisibleText("16进制");//打印下拉框中所有的选项List<WebElement> options = toDropList.getOptions();for (WebElement option : options) {System.out.println(option.getText());}

下拉框[非select]

项目实战:但是更多的网银环境中,选择账号的时候,他不是用的标准的select标签,额....而是使用li标签或者div标签

如下的下拉框

就是用div标签实现的

简单场景举例:

//点击下拉选择账号
driver.findElement(By.xpath("//*[@id=\"PaMng_aQry_aXDtlQry\"]/div[2]/div/div[1]/div[1]/div/div[2]/div/span")).click();
List<WebElement> accountListStr = driver.findElements(By.xpath("//*[@id=\"PaMng_aQry_aXDtlQry\"]/div[2]/div/div[1]/div[1]/div/div[2]/div/div/ul/li"));
System.out.println("accountListStr.size()"+accountListStr.size());
for(int x=0;x<accountListStr.size();x++){System.out.println(accountListStr.get(x).getText());//下拉框选择账号8888888if(accountListStr.get(x).getText().contains("8888888")){accountListStr.get(x).click();break;}
}

操作复选框

项目实战:在网银环境中,下载回单的时候,勾选全选按钮。

可以直接使用点击复选框进行勾选

 //点击全选driver.findElement(By.xpath("//*[@id=\"checkAll\"]")).click();

也可以使用

简单场景举例如下,我们勾选全局搜索和忽略大小写


操作单选框

如下图,我们操作使得打开网站后,选择时间戳为“13位”,因为默认选中的是10位

 webDriver.get("https://m.bejson.com/convert/unix/");//13位时间戳(毫秒级)WebElement radio = webDriver.findElement(By.xpath("//*[@id=\"kt_post\"]/div/div/div/div/div/form/div[2]/div[1]/div[2]/input"));//如果处于未选中状态,则单击选中if (!radio.isSelected()) {radio.click();}

链接 link

链接a标签的操作

// 找到链接元素
WebElement link1 = driver.findElement(By.linkText("小坦克"));
WebElement link11 = driver.findElement(By.partialLinkText("坦克"));// 点击链接
link1.click();

举例:


表格操作

网页表格

寻找一个在线的被测试的网页表格,假设如下:

Personal pronouns table (mdn.github.io)

th和td的区别

<tr>...</tr> 定义一行标签,一组行标签内可以建立多组由<td>或<th>标签所定义的单元格

<th>...</th> 定义表头单元格。表格中的文字将以粗体显示

<td>...</td> 定义单元格标签,一组<td>标签将将建立一个单元格

//创建浏览器实例
WebDriver driver = new ChromeDriver();//打开chrome
driver.get("https://mdn.github.io/learning-area/html/tables/basic/personal-pronouns.html");//打开一个在线的网页表格
//获取页面表格对象
WebElement element = driver.findElement(By.xpath("/html/body/table"));
//获取表格行数
List<WebElement> tr = element.findElements(By.tagName("tr"));
System.out.println("表格行数:" + tr.size());

Action

使用 Action 类来生成用户事件,例如右键单击 WebDriver 中的元素。参考代码片段:

Actions action = newActions(driver);  
WebElement element = driver.findElement(By.id("elementId"));  
//右键单击元素
action.contextClick(element).perform();
//鼠标悬停
action.moveToElement(element).perform();

拖放

Actions builder = newActions(driver);  
Action dragAndDrop = builder.clickAndHold(fromWebElement)  .moveToElement(toWebElement)  .release(toWebElement)  .build();  
dragAndDrop.perform();

Web 元素可见性

WebDriver 允许用户检查 Web 元素的可见性。这些网络元素可以是按钮、单选按钮、下拉菜单、复选框、框、标签等,它们与以下方法一起使用。

  • isDisplayed()
  • isSelected()
  • isEnabled()

窗口和标签页

网页访问

方式一:get方法

//访问京东
webDriver.get("https://www.jd.com/");

方式二:

//访问京东
webDriver.navigate().to("https://www.jd.com/");

窗口最大化

一些别的页面操作

1、页面最大化

//将浏览器窗口最大化
webDriver.manage().window().maximize();
//访问京东
webDriver.navigate().to("https://www.jd.com/");

2、获取页面Title属性

//获取页面Title属性
String title = webDriver.getTitle();
System.out.println(title);

3、获取页面的源代码

//访问京东
webDriver.navigate().to("https://www.jd.com/");
//获取网页的源代码
String pageSource = webDriver.getPageSource();
System.out.println(pageSource);

4、刷新页面

driver.navigate().refresh();

标签页切换

在某个页面点击链接打开了一个新的标签页,此时selenium是无法定位到新标签页的元素。

这就涉及到句柄的概念了,句柄就是标签页对象的唯一标识,每个标签页都有自己的句柄,可以通过句柄来实现标签页的切换,从而定位到对应标签页的元素。

//获取当前所有打开的浏览器窗口的句柄
Set<String> windowHandles = webDriver.getWindowHandles();
for (String windowHandle : windowHandles) {System.out.println(windowHandle);System.out.println(webDriver.switchTo().window(windowHandle).getTitle());
}
//获取当前浏览器窗口的句柄
String windowHandle = webDriver.getWindowHandle();
System.out.println("当前窗口句柄:"+windowHandle);System.out.println("当前窗口句柄:"+windowHandle);

控制台打印输出如下

根据URL进行切换标签页,如果URL包含对应的字符串的话,则切换到相应标签页。

pub_switchByUrl("ib.cdb.com.cn/b2bmain");

void pub_switchByUrl(String urlPatten){	ar.driver.switchTo().defaultContent();Set handles = ar.driver.getWindowHandles();for(String handle : handles){ar.driver.switchTo().window(handle);if(ar.driver.getCurrentUrl().contains(urlPatten))break;}
}

窗口关闭

  • driver.close() 关闭当前标签页
  • driver.quit()  关闭所有标签页

webDriver.close()

如果打开了多个页面是关不干净的,close()只关闭当前的一个页面。

使用时要注意 “当前页面” 这四个字,意味着当你关闭新打开的页面时,需要切换窗口才能操作新窗口并将它关闭。

webDriver.quit()

quit()是退出了所有Webdriver所有的窗口,并退出驱动程序。


Frame

iframe标签

HTML 内联框架元素 (<iframe>) 表示嵌套的browsing context。它能够将另一个 HTML 页面嵌入到当前HTML页面中。

在 HTML 文档中 <frame> 每出现一次,就会创建一个 Frame对象

通常我们使用iframe直接直接在页面嵌套iframe标签指定src就可以了。

<iframe src="demo_iframe.html"></iframe>

可以通过iframe嵌套通用的页面, 提高代码的重用率, 比如页面的头部样式和底部版权信息


Frame切换

在使用selenium打开一个网页时,我们的操作范围默认是当前的 html ,并不包含被嵌入的html文档里面的内容。如果我们要操作被嵌入的 html 文档 中的元素, 就必须把操作范围切换到被嵌入的文档中。

 WebDriver对象的switch_to属性转换,形如

//其中switchFlag可以是frame元素的name或者 ID属性及 frame 所对应的 WebElement 对象。
driver.switchTo().frame(switchFlag);

例如frame元素的 id 为‘frame1’,切换语句为:driver.switch_to.frame('frame1')

例如frame元素的name属性值为‘innerFrame’ ,切换语句为:driver.switch_to.frame('innerFrame')

为什么要切换frame表单

参数可以是id,name或者能定位到frame的元素。推荐使用name

在切换其他frame页面之前,需要将WebDriver 对象切换回默认区域:

webDriver.switchTo().defaultContent();

通常采用id和name就能够解决绝大多数问题。但有时候frame并无这两项属性,则可以用index和WebElement来定位:

  1. index从0开始,传入整型参数即判定为用index定位,传入str参数则判定为用id/name定位
  2. WebElement对象,即用find_element系列方法所取得的对象,我们可以用tag_name、xpath等来定位frame对象

多层嵌套frame

frame需层层切!

有时候我们会遇到嵌套的frame,如下:

<html><iframe id="frame1"><iframe id="frame2" / ></iframe>
</html>

从主文档切到frame2,一层层切进去

driver.switch_to.frame("frame1")
driver.switch_to.frame("frame2")

从frame2再切回frame1,这里selenium给我们提供了一个方法能够从子frame切回到父frame,而不用我们切回主文档再切进来

driver.switch_to.parent_frame() # 如果当前已是主文档,则无效果
  • 如果需要操作多个嵌套的iframe,‌需要逐层进入。‌例如,‌先进入最外层的iframe,‌然后进入内部的iframe。‌

  • 完成操作后,‌可以使用switch_to_parent_frame()switch_to_default_content()回到上一级或最外层的页面。‌

在处理iframe时,‌需要特别注意iframe的加载状态,‌确保在尝试访问iframe中的元素之前,‌iframe已经完全加载完成。‌


安居客登录

登录 (anjuke.com)

如下,红色区域部分是一个<iframe>标签

frame嵌套页面再比如:优酷登录窗口


弹窗

alert弹框

警告消息框 alert 方法有一个参数,即希望对用户显示的文本字符串。该字符串不是 HTML 格式。该消息框提供了一个“确定”按钮让用户关闭该消息框,并且该消息框是模式对话框,也就是说,用户必须先关闭该消息框然后才能继续进行操作。

selenium处理alert() 提示框:

  1. driver.switchTo().alert(); 获取alert
  2. alert.accept(); 点确定
  3. alert.dismiss(); 点取消
  4. alert.getText();获取alert的内容

confirm弹框

确认消息框 使用确认消息框可向用户问一个“是-或-否”问题,并且用户可以选择单击“确定”按钮或者单击“取消”按钮。confirm 方法的返回值为 true 或 false。该消息框也是模式对话框:用户必须在响应该对话框(单击一个按钮)将其关闭后,才能进行下一步操作。

1


div弹窗

div弹窗是浏览器中比较好定位的弹窗,定位的方法与普通的元素一样。不过这里会有一个坑,明明可以找到这个按钮,但是就是定位不到。这个就是因为当前有div弹窗弹出的时候,需要设置一下等待时间,等页面元素加载完毕,再去做其他操作。这里用百度登陆为例子:


元素等待

强制等待

强制等待:sleep

sleep,设置等待多长时间,就要等待多长时间。等待完成后,才会继续下一步:

//设置等待时间,单位是秒
sleep(3)

由于web加载的速度取决于测试的硬件、网速、服务器的响应时间等因素。如果时间设置太长,容易造成时间浪费,如果设置太短又可能会造成在web还没有加载完所需要定位的element,而出现报错。由于等待时间无法确定,使用太多的sleep会影响运行速度,大大地降低效率。


隐式等待

隐式等待:implicitlyWait

采用implicitly_wait()方法来设置等待时间,这种方法要比time.sleep更智能一些。

使用implicitlyWait方法设定查找页面元素的最大等待时间,调用findElement方法时
没有立刻找到定位元素,则程序会每间隔一段时间就尝试判断页面的D0M中是否出现被查找元素,若超过设定的等待时长依旧没有找到,则抛出NoSuchElementException

//只需要设置一次,所有的元素都可有最多 10s 的等待加载的时间
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
WebElement element = driver.findElement(By.id("exampleId"));

隐式等待默认设置等待时间为0,同时隐式等待是对driver起作用,所以只要设置一次即可,不需要到处设置。

隐式等待原理:

在每次进行 find_element时起作用,implicitlyWait()会将一个超时的时间阀值传递给 WebDriver,在findelement或者findelements的时候,首先去找 web element,如果没有找到,判断时间否超超过 implicitlyWait()传递进来的阀值,如果没有超过,则再次找这个element,直到找到 element 或者时间超过最大阀值。


显式等待

显式等待:使用ExpectedConditions类中自带方法, 可以进行显试等待的判断。

WebDriverWait(driver,10,1) 在等待期间,每隔1s一定时间,调用until或until_not里的方法,直到它返回True或False.

  • driver:浏览器驱动。
  • 10:最长超时时间,默认以秒为单位。
  • 1:检测的的间隔(步长) 时间,默认为 0.5s。

显式等待能自定义等待条件,只要满足等待条件即可执行下一步代码操作,一般需要配合该类的until()和until_not()方法一起用.

表示程序每隔一定时间就检查一遍条件是否成立,如果成立了就执行下一步,否则就继续等。直到超过设置的最长时间,然后抛出超时错误TimeoutException

//判断某元素是否可访问并且可启用,比如能够点击
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(webElement));//判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于0
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOf(webElement));//判断某元素否被选中
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeSelected(webElement));

常用的显示等待条件如下:


自定义显示等待

注意ExpectedConditions的写法变成了自定义

WebDriverWait wait = new WebDriverWait(driver, Manager_Config.getCmdTimeout() / 1000);
try {Alert alert = wait.until(new ExpectedCondition<Alert>() {@Overridepublic Alert apply(WebDriver driver) {try {return driver.switchTo().alert();} catch (NoAlertPresentException e) {return null;}}});if (alert != null)alert.accept();

 执行js

执行js脚本

executeScript是同步方法,用它执行js代码会阻塞主线程执行,直到js代码执行完毕;

import org.openqa.selenium.JavascriptExecutor;//第一行代码将driver强制转换为JavascriptExecutor
JavascriptExecutor js = (JavascriptExecutor) driver;//第二行代码是执行js,参数script是要执行的js语句,第二个参数对于executeScript这个方法,取决于js语句是否需要参数。
js.executeScript(String script, object... args);

executeScript方法返回值Boolean, Long, String, List or WebElement. 或者是 null.

  • 如果返回一个页面元素(document element), 这个方法就会返回一个WebElement
  • 如果返回浮点数字,这个方法就返回一个double类型的数字
  • 返回非浮点数字,方法返回Long类型数字
  • 返回boolean类型,方法返回Boolean类型
  • 如果返回一个数组,方法会返回一个List
  • 其他情况,返回一个字符串
  • 如果没有返回值,此方法就会返回null

应用举例:用js弹出alert

 JavascriptExecutor js = (JavascriptExecutor) webDriver;js.executeScript("alert('Test Case Execution Is started Now..')");webDriver.switchTo().alert().accept();

有些情况下,selenium提供的API无法完成对应的操作或者操作比较麻烦,此时可以借助JS脚本来实现,例如执行滑动滚动条。

js ='window.scrollTo(0,100)' # 要执行的JS脚本语句driver.execute_script(js) # 执行JS脚本

Edge驱动下载

Edge驱动下载:Microsoft Edge - Webdriver (windows.net)

Firefox驱动:https://github.com/mozilla/geckodriver/releases/

.Firefox驱动名称为geckodriver

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Go语言基础】调度器模型GPM与垃圾回收器GC
  • GNU/Linux - RSYSLOG
  • 基于大数据分析景区消费行为影响因素研究【消费等级预测、携程,去哪网数据抓取】
  • 去雾去雨算法
  • 力扣top300:1.两数之和
  • 37-RPC HTTP区别是什么
  • 用于目标说话人提取的统一视听线索
  • CSS3 3D 转换
  • GPT-6曝光!阉割版「草莓」秋季兑现
  • qtcreator的vim模式下commit快捷键ctrl+g,ctrl+c没有反应的问题
  • labelImg使用
  • 基于网络技术的天气数据查询
  • 在 Spring Boot 中为 MyBatis 添加拦截器
  • .Net 6.0--通用帮助类--FileHelper
  • python基础语法1
  • JavaScript 如何正确处理 Unicode 编码问题!
  • 【EOS】Cleos基础
  • Brief introduction of how to 'Call, Apply and Bind'
  • CSS3 变换
  • css的样式优先级
  • Javascript Math对象和Date对象常用方法详解
  • Mocha测试初探
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • redis学习笔记(三):列表、集合、有序集合
  • vue-cli在webpack的配置文件探究
  • WebSocket使用
  • yii2权限控制rbac之rule详细讲解
  • 动态规划入门(以爬楼梯为例)
  • 仿天猫超市收藏抛物线动画工具库
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • #nginx配置案例
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (1)常见O(n^2)排序算法解析
  • (1)虚拟机的安装与使用,linux系统安装
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (超详细)语音信号处理之特征提取
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (六)Flink 窗口计算
  • (七)Appdesigner-初步入门及常用组件的使用方法说明
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .net 无限分类
  • .net 中viewstate的原理和使用
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [.NET]桃源网络硬盘 v7.4
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标
  • [BZOJ3757] 苹果树
  • [C#]winform部署yolov5-onnx模型