Selenium学习(Java + Edge)

慈云数据 2024-03-19 技术支持 115 0

Selenium

/səˈliːniəm/

1. 简介

​ Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Safari、Google Chrome、Opera、Edge等。

​ 适用于自动化测试,js动态爬虫(破解反爬虫)等领域。

​ Selenium的核心Selenium Core基于JsUnit,完全由JavaScript编写,因此可以用于任何支持JavaScript的浏览器上。selenium可以模拟真实浏览器,自动化测试工具,支持多种浏览器。

Selenium官方

2. 组成

  • Selenium IDE:嵌入到Firefox浏览器中的一个插件,实现简单的浏览器操作录制与回放功能,主要用于快速创建BUG及重现脚本,可转化为多种语言;
  • Selenium RC: 核心组件,支持多种不同语言编写自动化测试脚本,通过其服务器作为代理服务器去访问应用,达到测试的目的;
  • Selenium WebDriver(重点):一个浏览器自动化框架,它接受命令并将它们发送到浏览器。它是通过特定于浏览器的驱动程序实现的。它直接与浏览器通信并对其进行控制。Selenium WebDriver支持各种编程语言,如Java、C# 、PHP、Python、Perl、Ruby;
  • Selenium grid:测试辅助工具,用于做分布式测试,可以并行执行多个测试任务,提升测试效率。

    3. 特点

    1. 开源、免费
    2. 多浏览器支持:FireFox、Chrome、IE、Opera、Edge;
    3. 多平台支持:Linux、Windows、MAC;
    4. 多语言支持:Java、Python、Ruby、C#、JavaScript、C++;
    5. 对Web页面有良好的支持;
    6. 简单(API 简单)、灵活(用开发语言驱动);
    7. 支持分布式测试用例执行。

    4. 配置

    ​ 采用Java编写自动化测试代码。

    4.1 环境依赖

    注意:浏览器版本必须与Selenium驱动版本一致!

    Edge:118.0.2088.76 x64

    Selenium驱动:118.0.2088.76

    Maven依赖:4.8.0

    JDK:1.8.0_361

    4.2 下载对应浏览器的驱动

    注意:下载的驱动包需要与当前浏览器版本对对应。

    4.4 配置驱动包

    ​ 将驱动包解压到jdk / bin目录下。

    5. 运行

    5.1 创建Maven项目

    在这里入图片描述

    在这里插入图片描述

    5.2 导入Selenium依赖

    pom.xml

        
            org.seleniumhq.selenium
            selenium-java
            4.8.0
        
        
            commons-io
            commons-io
            2.6
        
    
    

    5.3 在test /java下创建类

    在这里插入图片描述

    或者直接在src -> main -> java下新建。

    5.4 在自动化测试类中编写代码

    // 自动化测试类
    public class AutoTest  {
        public void Test() throws InterruptedException, IOException {
            // Edge驱动
            EdgeOptions edgeOptions = new EdgeOptions();
            // 允许所有请求(允许浏览器通过远程服务器访问不同源的网页,即跨域访问)
            edgeOptions.addArguments("--remote-allow-origins=*");
            EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);
            // 启动需要打开的网页
            edgeDriver.get("https://www.baidu.com");
            // 退出
            edgeDriver.quit();
        }
    }
    
    import java.io.IOException;
    // 启动类
    public class RunAutoTest {
        public static void main(String[] args) throws InterruptedException, IOException {
            AutoTest autoTest = new AutoTest();
            autoTest.Test();
        }
    }
    

    5.5 启动

    6. 使用

    6.1 请求

    方法说明
    driver.get(url)请求一个页面,不支持前进和后退切换
    driver.navigate().to(url)和get类似,支持前进和后退切换
    driver.navigate().forward(url)指前进到下一个页面(必须后退一个页面后才能前进)
    driver.navigate().back(url)退到上一个页面(必须前进了一个页面才能回退)
    driver.navigate().refresh(url)刷新当前页面

    6.2 定位元素

    方法描述
    driver.findElement(By.id())使用元素的唯一标识ID进行定位
    driver.findElement(By.name())使用元素的名称属性进行定位
    driver.findElement(By.className())使用元素的类名进行定位
    driver.findElement(By.tagName)使用元素的标签名进行定位
    driver.findElement(By.partialLinkText())使用链接文本进行定位
    driver.findElement(By.cssSelector)使用CSS选择器进行定位
    driver.findElement(By.xpath)使用XPath表达式进行定位

    cssSelector:

    在这里插入图片描述

    cv工程


    元素定位—cssSelector

    1. 根据tagName

      By.cssSelector("input");// 不推荐,tagName会重复
      
    2. 根据ID

      By.cssSelector("input#id");
      By.cssSelector("#id");
      
    3. 根据className(样式名)

      By.cssSelector(".className");
      By.cssSelector("input.className");
      

    css精确定位

    1. 根据元素属性,属性名=属性值(id、calss等都可使用此形式)

      // By.cssSelector("标签名[属性名='属性值']");
      By.cssSelector("input[name='xxx']");
      
    2. 多属性

      By.cssSelector("标签名[属性名='属性值'][属性名='属性值']");
      

    6.3 获取内容

    方法说明
    String getPageSource()获取页面html
    String getTitle()获取页面标题
    String getText()获取此元素(包括子元素)的可见(即未被CSS隐藏)文本
    String getTagName()获取此元素的标签名
    String getAttribute(String name)获取元素指定属性的值
    Point getLocation()获取当前元素,基于页面左上角的为准
    Dimension getSize()渲染元素的宽度和高度是多少
    String getCurrentUrl()获取表示浏览器正在查看的当前URL的字符串
    String getCssValue(String propertyName)获取指定元素的CSS属性的值

    6.4 操作行为

    方法说明
    clear()如果该元素是文本输入元素,则会清除该值
    submit()提交from表单
    click()单击此元素
    sendKeys()使用此方法模拟在元素中键入,可以设置其值

    注意:

    ​ 有些页面是使用动态加载js的,会导致html页面正常显示,但js还没执行完毕,相关事件还没绑定到具体的元素上。导致出现操作无效或程序抛出异常。

    ​ 可以在加载页面时强制等待,全部加载完毕后再进行后续操作。

    6.5 窗口

    方法说明
    driver.manage().window().setSize(new Dimension(1024, 768))设置当前窗口的大小
    driver.manage().window().setPosition()设置当前窗口的位置(相对于屏幕的左上角)
    driver.manage().window().getSize()获取当前窗口的大小
    driver.manage().window().getPosition()获取当前窗口相对于屏幕左上角的位置
    driver.manage().window().fullScreen()全屏当前窗口
    driver.manage().window().maximize()最大化当前窗口

    6.6 切换指定窗口

    ​ 当浏览器每次打开一个标签页的时候,会自动的给一个标签进行标识,这个标识我们称之为“句柄”。

    方法说明
    String getWindowHandle()返回当前窗口句柄,通过将其传递给switchTo(),进行切换窗口
    driver.switchTo().window(windowHandle)切换到指定句柄的窗口
        String curHandle = edgeDriver.getWindowHandle();// 获取当前页面句柄
        System.out.println("当前句柄:" + curHandle);
        Set handles = edgeDriver.getWindowHandles();// 获取所有页面句柄
        for (String handle : handles) {
            if (!handle.equals(curHandle)) {// 发生页面切换
                edgeDriver.switchTo().window(handle);// 切换窗口
            }
        }
    

    6.7 iframe切换

    方法说明
    driver.switchTo().frame(index)根据index进行切换
    driver.switchTo().frame(id)根据id进行切换
    driver.switchTo().frame(name)根据name进行切换
    driver.switchTo().frame(WebElement)根据WebElement进行切换
    driver.switchTo().defaultContent()切换后,回到默认内容页面(否则会找不到元素)

    6.8 模拟键盘和鼠标

    6.8.1 键盘事件
    方法说明
    driver.findElement(By.id(“kw”)).sendKeys(Keys.CONTROL, “a”)ctrl+a
    driver.findElement(By.id(“kw”)).sendKeys(Keys.CONTROL, “c”)ctrl+c
    driver.findElement(By.id(“kw”)).sendKeys(Keys.CONTROL, “v”)ctrl+v
    driver.findElement(By.id(“kw”)).sendKeys(Keys.TAB)TAB键
    driver.findElement(By.id(“kw”)).sendKeys(Keys.ENTER)回车键
    driver.findElement(By.id(“kw”)).sendKeys(Keys.SPACE)空格键
    6.8.2 鼠标事件
    Actions actions = new Actions(driver);
    
    方法说明
    actions.contextClick(element).perform()右键点击enement的元素
    actions.clickAndHold(element).perform()左键单击enement元素
    actions.doubleClick(element).perform()鼠标左键双击enement元素
    actions.moveToElement(element).perform()鼠标悬停enement元素(中间)
    actions.moveToElement(element,x,y).perform()鼠标悬停enement元素(指定位置)
    actions.moveToElement(x,y).perform();将鼠标从其当前位置移动鼠标
    Actions dragAndDrop(WebElement source, WebElement target)拖动元素, 在源元素的位置执行点击并保持,移动到目标元素的位置,然后释放鼠标
    Actions dragAndDropBy(WebElement source, int xOffset, int yOffset) 拖动到指定位置拖动到指定位置

    6.9 等待

    6.9.1 强制等待
        Thread.sleep(millisecond);
    

    程序阻塞执行,不建议。

    6.9.2 显式等待

    ​ 显式等待是添加到代码中的循环,在应用程序退出循环并继续执行代码中的下一个命令之前,它会轮询应用程序以查找特定条件以评估为true。如果在指定的超时值之前未满足条件,则代码将给出超时错误。

    WebElement revealed = driver.findElement(By.id("revealed"));
    Wait wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    driver.findElement(By.id("reveal")).click();
    wait.until(d -> revealed.isDisplayed());
    revealed.sendKeys("Displayed");
    
    6.9.3 隐式等待

    ​ 这是一个全局设置,适用于整个会话的每个元素位置调用。默认值为0,这意味着如果找不到元素,它将立即返回错误。如果设置了隐式等待,则在返回错误之前,驱动程序将等待所提供值的持续时间。请注意,一旦找到元素,驱动程序将返回元素引用,代码将继续执行,因此较大的隐式等待值不一定会增加会话的持续时间。

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    

    注意:

    ​ 不要混合隐式和显式等待。这样做可能会导致不可预测的等待时间。

    ​ 例如,设置10秒的隐式等待和15秒的显式等待可能会导致20秒后发生超时。

    6.10 弹窗

    1. 警告弹窗中, 切换到弹窗,调用 accept()
    2. 确认弹窗中, 切换到弹窗,调用 accept() 或者 dismiss()
    3. 提示弹窗中, 切换到弹窗, 可以先输入文本, 调用 sendKeys(), 然后调用 accept() 或者 dismiss().

      提示:这里的 sendKeys() 在页面上看不到输入文本的执行效果

    driver.get("...");
    Thread.sleep(3000);
    // 打开弹窗
    driver.findElement(By.cssSelector("body > input[type=button]")).click();
    Thread.sleep(3000);
    // 切换到弹窗进行弹窗的处理
    Alert alert = driver.switchTo().alert();
    Thread.sleep(3000);
    // 弹窗输入文本
    alert.sendKeys("abcdef");
    // 点击确认
    alert.accept();
    // 点击取消
    // alert.dismiss();
    driver.quit();
    
    6.10.1 警告弹窗

    警告弹窗中, 切换到弹窗,调用 accept()

    6.10.2 确认弹窗

    确认弹窗中, 切换到弹窗,调用 accept() 或者 dismiss()

    6.10.3 提示弹窗

    提示弹窗中, 切换到弹窗, 可以先输入文本, 调用 sendKeys(), 然后调用 accept() 或者 dismiss().

    提示:这里的 sendKeys() 在页面上看不到输入文本的执行效果

    6.11 下拉选择框

    方法说明
    select.getOptions()获取所有选项
    select.selectByIndex(index)根据索引选中对应的元素
    select.selectByValue(value)选择指定value值对应的选项
    select.selectByVisibleText(text)选中文本值对应的选项
    
    
        
        
        Document
    
    
    
        **12.5**
        **6.6**
        **486.4**
        **21.12**
        **99.99**
    
    
    
    
    package org.example;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.edge.EdgeDriver;
    import org.openqa.selenium.edge.EdgeOptions;
    import org.openqa.selenium.support.ui.Select;
    import java.time.Duration;
    public class Main {
        public static void main(String[] args) throws Exception {
            EdgeOptions edgeOptions = new EdgeOptions();
            edgeOptions.addArguments("--remote-allow-origins=*");
            EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);
            edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待
            edgeDriver.get("file:///D:/idea-workspace/WebTest/src/main/resources/web/fileUpload/select.html");
    //        WebElement webElement = edgeDriver.findElement(By.cssSelector("sss"));
    //        Select select = new Select(webElement);
            Select select = new Select(edgeDriver.findElement(By.cssSelector("#sss")));
            // 根据文本选择
            Thread.sleep(3000);
            select.selectByVisibleText("**99.99**");
            // 根据索引值选择
            Thread.sleep(3000);
            select.selectByIndex(1);
            // 根据属性值选择
            Thread.sleep(3000);
            select.selectByValue("6.6");
            Thread.sleep(1000);
            edgeDriver.quit();
        }
    }
    
    6.11.1 根据文本选择
    WebElement webElement = driver.findElement(By.cssSelector("#Method"));
    // 创建选择框对象(将此web元素封装为Select对象)
    Select select = new Select(webElement)
    // 根据文本来选择
    select.selectByVisibleText("选择框文本");
    Thread.sleep(3000);
    driver.quit();
    
    6.11.2 根据属性值选择
    WebElement webElement = driver.findElement(By.cssSelector("#Method"));
    // 创建选择框对象(将此web元素封装为Select对象)
    Select select = new Select(webElement)
    // 根据属性值来选择
    select.selectByValue("选择框属性值");
    Thread.sleep(3000);
    driver.quit();
    
    6.11.3 根据序号选择

    注意:select下拉框索引值从0开始!

    WebElement webElement = driver.findElement(By.cssSelector("#Method"));
    // 创建选择框对象(将此web元素封装为Select对象)
    Select select = new Select(webElement)
    // 根据序号来选择
    select.selectByIndex(1);
    Thread.sleep(3000);
    driver.quit();
    

    6.12 文件上传

    public void fileUploadController() throws InterruptedException {
    	driver.get("");
    	Thread.sleep(3000);
    	
    	driver.findElement(By.cssSelector("body > div > div > input[type=file]")).sendKeys("文件路径");
    	Thread.sleep(3000);
    	driver.quit();
    }
    

    
    
        
        
        Document
    
    
    
    

    package org.example;
    import org.openqa.selenium.By;
    import org.openqa.selenium.edge.EdgeDriver;
    import org.openqa.selenium.edge.EdgeOptions;
    import java.time.Duration;
    public class Main {
        public static void main(String[] args) throws InterruptedException {
            System.out.println("Hello world!");
            EdgeOptions edgeOptions = new EdgeOptions();
            edgeOptions.addArguments("--remote-allow-origins=*");
            EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);
            edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待
            edgeDriver.get("file:///D:/idea-workspace/WebTest/src/main/resources/web/fileUpload/fileUpload.html");
            Thread.sleep(3000);
            edgeDriver.findElement(By.cssSelector("#fu")).sendKeys("D:/idea-workspace/WebTest/src/main/resources/web/fileUpload/fileUpload.html");
            Thread.sleep(3000);
            edgeDriver.quit();
        }
    }
    

    在这里插入图片描述

    在这里插入图片描述

    注意:如果上传文件前端控件源码不是input类型,需要使用第三方工具,比如:autoit

    6.13 时间日期控件

    • 控件没有限制手动输入,则直接调用sendKeys方法写入时间数据。
    • 控件有限制输入,则可以通过执行一段js脚本来改变元素的value属性值。
      6.13.1 方式一
      package org.example;
      import org.openqa.selenium.By;
      import org.openqa.selenium.WebElement;
      import org.openqa.selenium.edge.EdgeDriver;
      import org.openqa.selenium.edge.EdgeOptions;
      import org.openqa.selenium.support.ui.Select;
      import java.time.Duration;
      public class Main {
          public static void main(String[] args) throws InterruptedException {
              EdgeOptions edgeOptions = new EdgeOptions();
              edgeOptions.addArguments("--remote-allow-origins=*");
              EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);
              edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待
              edgeDriver.get("https://www.fliggy.com/?ttid=seo.000000580&seoType=origin");
              edgeDriver.findElement(By.cssSelector("#J_FlightForm > fieldset > div:nth-child(5) > div > div > input")).sendKeys("2000-01-01");
              Thread.sleep(1000);
              edgeDriver.quit();
          }
      }
      
      6.13.2 方式二
      	见 6.13 执行脚本
      

      6.13 执行脚本

      方法说明
      driver.executeScript()参数为要执行的js脚本
      package org.example;
      import org.openqa.selenium.By;
      import org.openqa.selenium.WebElement;
      import org.openqa.selenium.edge.EdgeDriver;
      import org.openqa.selenium.edge.EdgeOptions;
      import org.openqa.selenium.support.ui.Select;
      import java.time.Duration;
      public class Main {
          public static void main(String[] args) throws InterruptedException {
              EdgeOptions edgeOptions = new EdgeOptions();
              edgeOptions.addArguments("--remote-allow-origins=*");
              EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);
              edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待
              edgeDriver.get("https://www.12306.cn/index/");
      //        edgeDriver.findElement(By.id("train_date"));
      //        edgeDriver.executeScript("var v = train_date;\n" + "v.autocomplete = true");
              edgeDriver.executeScript("var v = train_date; v.autocomplete = true");
              edgeDriver.findElement(By.id("train_date")).clear();
              edgeDriver.findElement(By.id("train_date")).sendKeys("2000-01-01");
              Thread.sleep(1000);
              edgeDriver.quit();
          }
      }
      

      在这里插入图片描述

      在这里插入图片描述

      6.14 浏览器参数设置

      EdgeOptions edgeOptions = new EdgeOptions();
      edgeOptions.addArguments("--remote-allow-origins=*");
      
      addArguments可接收参数说明
      “–disable-gpu”禁用GPU加速
      “–headless”在无头模式下运行浏览器,即不显示图形界面
      “–incognito”在隐身模式下启动浏览器
      “–disable-extensions”禁用浏览器扩展
      “–disable-notifications”禁用浏览器通知
      “–disable-popup-blocking”禁用弹出窗口拦截功能
      “–start-maximized”启动时最大化浏览器
      “–disable-infobars”禁用信息栏(例如Chrome正在受到自动测试软件控制)
      “–ignore-certificate-errors”忽略证书错误
      “–proxy-server=http://hostname:port”设置代理服务器

      注意:浏览器的参数设置需要在创建浏览器对象之前进行设置。

      6.15 验证码

      6.15.1 万能验证码(推荐)

      ​ 后端代码添加测试通用验证码。

      6.15.2 去除验证码

      ​ 后端去除验证码。

      6.15.3 自动识别(难度大)

      ​ 可以付费调用自动识别API,不推荐。

      6.16 退出

      方法说明
      driver.close()关闭当前窗口(如果是当前打开的最后一个窗口,则退出浏览器)
      driver.quit()退出此驱动程序,关闭每个相关窗口

      在操作完毕后必须调用quit()进行释放资源,否则驱动将持续在内存中不会被释放掉。

      7. 最后

      码字不易,xdm,qiuqiu点个👍吧!

      在这里插入图片描述

微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon