自动化测试Selenium(4)

news2024/12/26 23:07:20

WebDriver相关api

定位一组元素

webdriver可以很方便地使用findElement方法来定位某个特定的对象, 不过有时候我们需要定位一组对象, 这时候就要使用findElements方法.

定位一组对象一般用于一下场景:

批量操作对象, 比如将页面上的checkbox都勾上.

先获取一组对象, 再在这组对象中过滤出需要具体定位的对象. 比如定位出页面上的checkbox, 然后选取最后一个.

通过类似下面这种形式可以定位一组元素. 

List<WebElement> webElements = webDriver.findElements(.......); 

下面我们在实际场景下使用一下, 先给出我们需要用到的html代码, 放入resource即可:

<html>
<head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <title>Checkbox</title>
</head>
<body>
<h3>checkbox</h3>
<div class="well">
  <form class="form-horizontal">
    <div class="control-group">
      <label class="control-label" for="c1">checkbox1</label>
      <div class="controls">
        <input type="checkbox" id="c1" />
      </div>
    </div>
    <div class="control-group">
      <label class="control-label" for="c2">checkbox2</label>
      <div class="controls">
        <input type="checkbox" id="c2" />
      </div>
    </div>
    <div class="control-group">
      <label class="control-label" for="c3">checkbox3</label>
      <div class="controls">
        <input type="checkbox" id="c3" />
      </div>
    </div>
    <div class="control-group">
      <label class="control-label" for="r">radio</label>
      <div class="controls">
        <input type="radio" id="r1" />
      </div>
    </div>
    <div class="control-group">
      <label class="control-label" for="r">radio</label>
      <div class="controls">
        <input type="radio" id="r2" />
      </div>
    </div>
  </form>
</div>
</body>
</html>

测试代码如下:

    private static void test10() {
        WebDriver webDriver = new ChromeDriver();
        //这个是提供前端代码在文件中的路径
        webDriver.get("file:///C:/Users/86133/Desktop/%E6%96%87%E7%AB%A0/%E8%AF%BE%E4%BB%B6/html/%E6%B5%8B%E8%AF%95%E7%94%A8/test01.html");
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
        //找到所有的input框
        List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));
        for(int i = 0; i < webElements.size(); i++) {
            //如果每个元素type等于checkbox进行点击(注:这里可能是radio-单选框, checkbox-多选框)
            //getAttribute获取页面的属性值, 比对
            if(webElements.get(i).getAttribute("type").equals("checkbox")) {
                webElements.get(i).click();
            }
        }
    }

测试结果:

 

可以看到成功地完成了多选.

多层框架/窗口定位

对于一个web应用, 经常会出现框架(frame)或窗口(window)的应用, 这也就给我们的定位带来了一定的困难.

窗口是操作系统中的基本用户界面元素, 用于承载应用程序的可视化界面, 通常由标题栏, 菜单栏, 工具栏, 客户区和边框组成.  而框架是一种高级的GUI组件, 用于创建具有特定功能和外观的窗口, 通常是窗口的一种特殊类型或子类,具有额外的功能和布局选项

定位一个frame: webDriver.switchTo().frame()

定位一个窗口window: webDriver.switchTo().window()

多层框架的定位

switchTo.frame(): 通过frame的id或者name或者frame自带的其它属性来定位框架, 这里switchTo().frame()把当前定位的主体切换到了frame里.

webDriver.switchTo().defaultContent(): 从frame中嵌入的页面里跳出, 跳回到最外面的默认页面中.

下面我们来测试一下(需求: 定位到inner, 并点击click), 先给出外层frame的html代码:

<html>
<head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <title>frame</title>
<!--  <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" />-->
  <script type="text/javascript">$(document).ready(function(){
  });
  </script>
</head>
<body>
<div class="row-fluid">
  <div class="span10 well">
    <h3>frame</h3>
    <iframe id="f1" src="inner.html" width="800", height="600"></iframe>
  </div>
</div>
</body>
<!--<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>-->
</html>

inner.html:

<html>
<head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <title>inner</title>
</head>
<body>
<div class="row-fluid">
  <div class="span6 well">
    <h3>inner</h3>
    <iframe id="f2" src="https://www.baidu.com/"
            width="700"height="500"></iframe>
    <a href="javascript:alert('watir-webdriver better than selenium webdriver;')">click</a>
  </div>
</div>
</body>
</html>

测试代码:

    private static void test11() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("file:///C:/Users/86133/Desktop/%E6%96%87%E7%AB%A0/%E8%AF%BE%E4%BB%B6/html/%E6%B5%8B%E8%AF%95%E7%94%A8/test02.html");
        webDriver.switchTo().frame("f1");
        webDriver.findElement(By.cssSelector("body > div > div > a")).click();
    }

运行结果(建议自行测试):

 

这时可以看到成功定位了, 并完成了指定的点击操作. 

多层窗口定位

有可能嵌套的不是框架, 而是窗口, 还有针对窗口的方法: switchTo.window("windowName");

下拉框处理

下拉框是我们最常见的一种页面元素, 对于一般的元素, 我们只需要一次就定位, 但是对于下拉框里的内容需要进行两次定位, 先定位到下拉框对下拉框进行操作时, 在定位到下拉框里的选项.

测试一下, 先给出html代码:

<html>
<body>
<select id="ShippingMethod" onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod">
  <option value="12.51">UPS Next Day Air ==> $12.51</option>
  <option value="11.61">UPS Next Day Air Saver ==> $11.61</option>
  <option value="10.69">UPS 3 Day Select ==> $10.69</option>
  <option value="9.03">UPS 2nd Day Air ==> $9.03</option>
  <option value="8.34">UPS Ground ==> $8.34</option>
  <option value="9.25">USPS Priority Mail Insured ==> $9.25</option>
  <option value="7.45">USPS Priority Mail ==> $7.45</option>
  <option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>

现在我们来选择性地定位元素:

    private static void test12() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("file:///C:/Users/86133/Desktop/%E6%96%87%E7%AB%A0/%E8%AF%BE%E4%BB%B6/html/%E6%B5%8B%E8%AF%95%E7%94%A8/test03.html");
        //定位到下拉框
        WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));
        //创建Select对象来操作下拉框列表
        Select select = new Select(webElement);
        sleep(3000);
        //选择到第3个元素(下标从0开始)
        select.selectByIndex(3);
        sleep(3000);
        //选择到值为12.51的元素
        select.selectByValue("12.51");
    }

请自行测试以查看结果.

弹窗操作

有时候在页面中可能会"蹦出"一些弹窗, 那么我们应该怎么对弹窗操作呢? 下面给出几种操作方法:

我们通过 switch().alert()来对弹窗进行操作, 下面给出几种常见的操作组合:
1.弹窗确认: switchTo().alert().accept();

2.弹窗取消: switchTo().alert().dismiss();

3.向弹窗中输入内容: switchTo().alert().sendKeys(".....");

下面我们给出html代码,我们来测试一下: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button onclick="Click()">这是一个弹窗</button>
</body>
<script type="text/javascript">
  function Click() {
    let name = prompt("请输入姓名:");
    let parent = document.querySelector("body");
    let child = document.createElement("div");
    child.innerHTML = name;
    parent.appendChild(child)
  }
</script>
</html>

测试代码:

    private static void test13() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("file:///C:/Users/86133/Desktop/%E6%96%87%E7%AB%A0/%E8%AF%BE%E4%BB%B6/html/%E6%B5%8B%E8%AF%95%E7%94%A8/test04.html");
        //找到"这是一个弹窗"按钮并点击
        webDriver.findElement(By.cssSelector("button")).click();
        sleep(3000);
        //弹窗取消
        webDriver.switchTo().alert().dismiss();
        sleep(3000);
        webDriver.findElement(By.cssSelector("button")).click();
        //在弹窗中输入内容
        webDriver.switchTo().alert().sendKeys("初音未来");
        //弹窗确认
        sleep(3000);
        webDriver.switchTo().alert().accept();
    }

选择文件并放置

这个与输入类似, 使用sendKeys()操作即可.

eg: webDriver.findElement(By.cssSelector("")).sendKeys("文件路径");

跳转页面选择元素

在前面, 我们学习了在一个页面中选择元素, 就是通过一个元素的标签或者类名什么的来进行定位. 那么我要问一个问题, 在当前页面中选择一个元素, 再在会跳转到的页面选择一个元素, 那么这个元素还生效吗? 我们不妨来测试一下:

比如先在百度首页点击新闻, 然后跳转后输入新闻联播:

按照先前的方法, 我们来测试一下:

我们发现这里报错了, 这里我们得出结论: 

在页面跳转后, 已选择的下拉表元素可能会丢失选中状态, 这取决于页面的实现和浏览器的行为(即你要找的元素默认是在get方法打开的页面来寻找的). 通常情况下, 页面跳转后, 之前的页面会被清除, 包括下拉列表的选中状态. 并且还有一个问题,跳转后的页面和当前的页面可能会出现id一致的问题.

那么我们应该怎么解决这个问题呢?

 针对上面发现的问题, 就是出现在,页面跳转后丢失了选中状态, 所以我们应该在页面跳转之后保持选中状态, 可以考虑在页面跳转前记录当前选中的选项值, 并在跳转后再次选中该值. 或者在页面跳转后重新定位到下拉列表元素, 并重新选择之前选中的选项.

那么怎么实现呢?

这就使用到了获取句柄的方法.

句柄的定义: 总的来说, 句柄是一个通用的概念, 用来引用和操作各种对象. 它提供了一种抽象的方式来管理和访问对象, 使得程序能够更灵活地进行处理.

在Selenium WebDriver中, getWindowHandle()和getWindowHandles()方法用于处理浏览器窗口和标签页的句柄.

 1.getWindowHandle(): 这个方法用于获取当前浏览器窗口或标签页的句柄(handle). 句柄是一个字符串, 表示当前窗口或标签页的唯一标识符.

String currentWindowHandle = webDriver.getWindowHandle();

2.getWindowHandles(): 这个方法用于获取当前浏览器所有窗口或标签页的句柄集合. 返回的是一个包含所有窗口句柄的集合.

Set<String> windowHandles = webDriver.getWindowHandles();

修改一下代码:

    private static void test11() throws InterruptedException {
        WebDriver webDriver =  new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
        Thread.sleep(3000);
        //通过getWindowHandles获取所有的窗口句柄
        //通过getWindowHandle获取的get打开的页面窗口句柄.
        System.out.println(webDriver.getWindowHandle());
        //获取到所有的窗口句柄,存储到一个set集合中
        Set<String> handles = webDriver.getWindowHandles();
        String target_handle = "";
        for(String handle : handles) {
            target_handle = handle;
        }
        //这个就是打开新窗口的句柄
        webDriver.switchTo().window(target_handle);
        Thread.sleep(3000);
        webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");
        webDriver.findElement(By.cssSelector("#s_btn_wr")).click();
    }

运行, 发现能够正确处理逻辑了.

截图功能

这里直接给出代码:

    private static void test12() throws InterruptedException, IOException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com/");
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");
        webDriver.findElement(By.cssSelector("#su")).click();
        Thread.sleep(3000);
        //使用WebDriver截图功能进行页面截图, 首先将WebDriver强制转换为TakesScreenshot接口
        //然后调用getScreenshotAs方法获取截图文件
        File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
        //使用FileUtils工具将截图文件保存到本地
        FileUtils.copyFile(file, new File("D://2024419jietu.png"));
    }

运行代码, 发现截图成功:

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1607659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【代码随想录】【回文子串】day57:● 647. 回文子串 ● 516.最长回文子序列 ● 动态规划总结篇

回文子串 def countSubstrings(self, s):# 动态规划解法# dp[i][j] s[i-j]区间的回文子串的数目 dp[i][j]取决于dp[i1]和dp[j-1]count0dp[[False]*len(s) for _ in range(len(s))]for i in range(len(s)-1,-1,-1):for j in range(i,len(s)):if s[i]s[j] :if j-i<1:count1dp[…

全新升级轻舟知识付费系统引流变现至上利器

知识付费系统&#xff1a;引流变现至上利器 本系统参考各大主流知识付费系统&#xff0c;汇总取其精华&#xff0c;自主研发&#xff0c;正版授权系统。 我们给你搭建搭建一个独立运营的知识付费平台&#xff0c;搭建好之后&#xff0c;你可以自由的运营管理。网站里面的名称…

嵌入式软件考试——网络基础知识

1 主要知识点 OSI/RMTCP/IPIP地址与网络划分DNS与DHCP网络规划与设计网络故障诊断 2 OSI/RM 2.1 OSI七层模型 OSI七层模型 Bit流&#xff1a;物理层(集中器/中继器) 帧&#xff1a;数据链路层(网桥/交换机) 包&#xff1a;网络层(路由器) 段&#xff1a;传输层 报文&#xf…

SpringBoot框架——7.整合MybatisPlus

这篇主要介绍Springboot整合MybatisPlus&#xff0c;另外介绍一个插件JBLSpringbootAppGen,以及一个经常用于测试的基于内存的h2数据库。 Mybatisplus是mybatis的增强工具&#xff0c;和tk-mybatis相似&#xff0c;但功能更强大&#xff0c;可避免重复CRUD语句&#xff0c;先来…

uniapp_微信小程序_预约时间组件的使用

一、官方文档 DatetimePicker 选择器 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 (uviewui.com) 二、完成的效果 之前使用的是Calendar 日历 这个太耗性能了&#xff0c;直接页面卡顿&#xff0c;所以就换成以上选择器了 三、代码 <u-datetime-p…

graphviz使用

安装 brew install graphviz测试 https://github.com/martisak/dotnets?tabreadme-ov-file

图文教程 | Git安装配置、常用命令大全以及常见问题

前言 因为多了一台电脑&#xff0c;平时写一些代码&#xff0c;改一些文件&#xff0c;用U盘存着转来转去特别麻烦。于是打算用Git管理我的文件&#xff0c;方便在两个终端之间传输数据啥的。也正好给新电脑装好Git。 &#x1f4e2;博客主页&#xff1a;程序源⠀-CSDN博客 &…

3d模型渲染怎么会没材质---模大狮模型网

在进行3D模型渲染时&#xff0c;有时会遇到材质丢失的问题&#xff0c;这可能会给设计师们带来一些困扰。材质是渲染的重要组成部分&#xff0c;它们赋予了模型真实感和视觉吸引力。然而&#xff0c;当模型在渲染过程中出现没有材质的情况时&#xff0c;可能会导致最终效果不如…

Spring Boot 2.x 将 logback 1.2.x 升级至 1.3.x

场景 安全部门针对代码进行漏洞扫描时&#xff0c;发现 logback-core 和 logback-classic 都属于 1.2.x 版本&#xff0c;这个版本存在 CVE 漏洞&#xff0c;并且建议升级到 1.3.x 版本。 问题 将两个包直接升级到 1.3.x 版本时&#xff0c;Spring Boot Web 服务启动直接出现…

基于springboot+vue+Mysql的地方废物回收机构管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

C语言中的数据结构--双向链表

前言 上一节我们已经学习完了单链表&#xff08;单向不带头不循环链表&#xff09;的所有内容&#xff0c;我们在链表的分类里面知道了&#xff0c;链表分为单向的和双向的&#xff0c;那么本节我们就来进行双向链表&#xff08;带头双向循环链表&#xff09;的学习&#xff0c…

Java 的注释

文章目录 java 的注释共有三种形式单行注释多行注释文档注释文档注释的文档需要命令进行生成GBK 不可映射问题 与大多数的编程语言一样&#xff0c;Java 中的注释也不会出现在可执行程序中。 因此我们可以在源程序中根据需要添加任意多的注释&#xff0c;而不必担心可执行代码受…

优秀Burp插件 提取JS、HTML中URL插件

Burp Js Url Finder 攻防演练过程中&#xff0c;我们通常会用浏览器访问一些资产&#xff0c;但很多接口/敏感信息隐匿在html、JS文件中&#xff0c;通过该Burp插件我们可以&#xff1a; 1、发现通过某接口可以进行未授权/越权获取到所有的账号密码 2、发现通过某接口可以枚举用…

【数据结构与算法】贪心算法及例题

目录 贪心算法例题一&#xff1a;找零问题例题二&#xff1a;走廊搬运物品最优方案问题输入样例例题三&#xff1a;贪心自助餐 贪心算法 贪心算法是一种在每一步选择中都采取当前状态下最优的选择&#xff0c;以期望最终达到全局最优解的算法。它的核心思想是每次都选择当前最…

python语言零基础入门——变量与简单数据类型

目录 一、变量 1.创建变量 2.变量的修改 3.变量的命名 &#xff08;1&#xff09;常量 &#xff08;2&#xff09;标识符 &#xff08;3&#xff09;关键字 &#xff08;4&#xff09;命名规则 二、简单数据类型 1.变量的数据类型 2.数据类型 3.整型&#xff08;In…

Java项目:基于Springboot+vue实现的校园志愿者管理系统(源码+数据库+环境配置和运行指导视频+系统讲解视频)

一、项目简介 本项目是一套基于Springbootvue实现的校园志愿者管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&…

适合咖啡机小流量开关的流量计有哪些

在选择适合咖啡机小流量开关的流量计时&#xff0c;霍尔式流量计和光电式流量计是常用的流量计。 霍尔式流量计采用了霍尔效应的原理。它将带有两极磁铁的叶轮放置于垂直于磁场的环境中&#xff0c;当液体流经时&#xff0c;叶轮会因流体的作用而转动&#xff0c;产生GS值&…

BCLinux8U6系统部署oceanbase分布式数据库社区版之一、准备 OBD 中控机

本文记录了在BCLinux8U6操作系统的虚拟服务器准备oceanbase开源数据库的 OBD 中控机的过程。 一、中控机环境 1、虚拟服务器硬件配置 2、操作系统版本信息 [rootlocalhost ~]# cat /etc/os-release NAME"BigCloud Enterprise Linux" VERSION"8.6 (Core)&qu…

最强开源大模型 Llama 3震撼发布!开源模型将追上GPT-4,4000亿参数模型也在路上

就在昨晚&#xff0c;Meta官宣了开源的Llama 3 8B和70B版本。 8B模型在多项指标中超越了Gemma 7B和Mistral 7B Instruct&#xff0c;而70B模型则超越了闭源的Claude 3 Sonnet&#xff0c;和Gemini Pro 1.5。 此外Meta还有一个still training的400B参数版本&#xff0c;它和GP…

编程入门(五)【Visual Studio Code安装与C/C++语言运行】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言VScode安装与环境配置编写第一个C语言程序总结 前言 经过了前面对计算机…