• 自动化测试Selenium(4)


    WebDriver相关api

    定位一组元素

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

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

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

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

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

    List webElements = webDriver.findElements(.......); 

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

    1. <html>
    2. <head>
    3. <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    4. <title>Checkboxtitle>
    5. head>
    6. <body>
    7. <h3>checkboxh3>
    8. <div class="well">
    9. <form class="form-horizontal">
    10. <div class="control-group">
    11. <label class="control-label" for="c1">checkbox1label>
    12. <div class="controls">
    13. <input type="checkbox" id="c1" />
    14. div>
    15. div>
    16. <div class="control-group">
    17. <label class="control-label" for="c2">checkbox2label>
    18. <div class="controls">
    19. <input type="checkbox" id="c2" />
    20. div>
    21. div>
    22. <div class="control-group">
    23. <label class="control-label" for="c3">checkbox3label>
    24. <div class="controls">
    25. <input type="checkbox" id="c3" />
    26. div>
    27. div>
    28. <div class="control-group">
    29. <label class="control-label" for="r">radiolabel>
    30. <div class="controls">
    31. <input type="radio" id="r1" />
    32. div>
    33. div>
    34. <div class="control-group">
    35. <label class="control-label" for="r">radiolabel>
    36. <div class="controls">
    37. <input type="radio" id="r2" />
    38. div>
    39. div>
    40. form>
    41. div>
    42. body>
    43. html>

    测试代码如下:

    1. private static void test10() {
    2. WebDriver webDriver = new ChromeDriver();
    3. //这个是提供前端代码在文件中的路径
    4. 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");
    5. webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
    6. //找到所有的input框
    7. List webElements = webDriver.findElements(By.cssSelector("input"));
    8. for(int i = 0; i < webElements.size(); i++) {
    9. //如果每个元素type等于checkbox进行点击(注:这里可能是radio-单选框, checkbox-多选框)
    10. //getAttribute获取页面的属性值, 比对
    11. if(webElements.get(i).getAttribute("type").equals("checkbox")) {
    12. webElements.get(i).click();
    13. }
    14. }
    15. }

    测试结果:

     

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

    多层框架/窗口定位

    对于一个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代码:

    1. <html>
    2. <head>
    3. <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    4. <title>frametitle>
    5. <script type="text/javascript">$(document).ready(function(){
    6. });
    7. script>
    8. head>
    9. <body>
    10. <div class="row-fluid">
    11. <div class="span10 well">
    12. <h3>frameh3>
    13. <iframe id="f1" src="inner.html" width="800", height="600">iframe>
    14. div>
    15. div>
    16. body>
    17. html>

    inner.html:

    1. <html>
    2. <head>
    3. <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    4. <title>innertitle>
    5. head>
    6. <body>
    7. <div class="row-fluid">
    8. <div class="span6 well">
    9. <h3>innerh3>
    10. <iframe id="f2" src="https://www.baidu.com/"
    11. width="700"height="500">iframe>
    12. <a href="javascript:alert('watir-webdriver better than selenium webdriver;')">clicka>
    13. div>
    14. div>
    15. body>
    16. html>

    测试代码:

    1. private static void test11() {
    2. WebDriver webDriver = new ChromeDriver();
    3. 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");
    4. webDriver.switchTo().frame("f1");
    5. webDriver.findElement(By.cssSelector("body > div > div > a")).click();
    6. }

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

     

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

    多层窗口定位

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

    下拉框处理

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

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

    1. <html>
    2. <body>
    3. <select id="ShippingMethod" onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod">
    4. <option value="12.51">UPS Next Day Air ==> $12.51option>
    5. <option value="11.61">UPS Next Day Air Saver ==> $11.61option>
    6. <option value="10.69">UPS 3 Day Select ==> $10.69option>
    7. <option value="9.03">UPS 2nd Day Air ==> $9.03option>
    8. <option value="8.34">UPS Ground ==> $8.34option>
    9. <option value="9.25">USPS Priority Mail Insured ==> $9.25option>
    10. <option value="7.45">USPS Priority Mail ==> $7.45option>
    11. <option value="3.20" selected="">USPS First Class ==> $3.20option>
    12. select>
    13. body>
    14. html>

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

    1. private static void test12() throws InterruptedException {
    2. WebDriver webDriver = new ChromeDriver();
    3. 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");
    4. //定位到下拉框
    5. WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));
    6. //创建Select对象来操作下拉框列表
    7. Select select = new Select(webElement);
    8. sleep(3000);
    9. //选择到第3个元素(下标从0开始)
    10. select.selectByIndex(3);
    11. sleep(3000);
    12. //选择到值为12.51的元素
    13. select.selectByValue("12.51");
    14. }

    请自行测试以查看结果.

    弹窗操作

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

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

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

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

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

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Titletitle>
    6. head>
    7. <body>
    8. <button onclick="Click()">这是一个弹窗button>
    9. body>
    10. <script type="text/javascript">
    11. function Click() {
    12. let name = prompt("请输入姓名:");
    13. let parent = document.querySelector("body");
    14. let child = document.createElement("div");
    15. child.innerHTML = name;
    16. parent.appendChild(child)
    17. }
    18. script>
    19. html>

    测试代码:

    1. private static void test13() throws InterruptedException {
    2. WebDriver webDriver = new ChromeDriver();
    3. 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");
    4. //找到"这是一个弹窗"按钮并点击
    5. webDriver.findElement(By.cssSelector("button")).click();
    6. sleep(3000);
    7. //弹窗取消
    8. webDriver.switchTo().alert().dismiss();
    9. sleep(3000);
    10. webDriver.findElement(By.cssSelector("button")).click();
    11. //在弹窗中输入内容
    12. webDriver.switchTo().alert().sendKeys("初音未来");
    13. //弹窗确认
    14. sleep(3000);
    15. webDriver.switchTo().alert().accept();
    16. }

    选择文件并放置

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

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

    跳转页面选择元素

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

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

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

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

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

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

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

    那么怎么实现呢?

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

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

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

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

    String currentWindowHandle = webDriver.getWindowHandle();

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

    Set windowHandles = webDriver.getWindowHandles();

    修改一下代码:

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

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

    截图功能

    这里直接给出代码:

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

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

     

     

     

     

     

  • 相关阅读:
    基于象鼻虫损害优化算法求解装箱问题附Matlab代码
    闭包会牺牲多少性能?它是如何产生内存消耗及性能消耗的?
    2022牛客多校十 F-Shannon Switching Game?(博弈+bfs)
    BootStrap-前端框架
    STN向城域云网演进浅析
    【无标题】
    JavaAPI常用类01
    基于神经网络和遗传算法的unity开发框架
    数字IC设计经验整理(二)
    freeswitch-1.10.7 on centos7编译安装
  • 原文地址:https://blog.csdn.net/asdssadddd/article/details/137948482