Selenium

Selenium

是一个用于Web应用程序测试的工具

  • Selenium IDE,是浏览器的扩展插件,支持用户录制和回放测试
  • Selenium WebDrive,提供了各种语言环境的API来支持更多控制权和编写符合标准软件开发实践的应用程序。
  • SeleniumGrid,分布式自动化工具,可以在多个测试环境中以并发的方式执行测试脚本,实现测试脚本的并发执行,缩短大量的测试脚本的执行时间

用于Web应用程序测试的工具,Selenium是开源并且免费的,Selenium测试直接在浏览器中运行,就像真实用户所作的一样

支持多种操作系统、多种浏览器、多种编程语言

特点

  1. 开源软件:可以根据需求来增加工具的某些功能
  2. 跨平台:unix、windows
  3. 核心功能:可以在多个浏览器上进行自动化测试
  4. 多语言:Java、Python、C#、JS、Ruby等
  5. 程序稳定:目前已经被google、百度、腾讯广泛使用
  6. 功能强大:能够实现类似商业工具的大部分功能,因为开源行,可实现定制功能

Maven引入selenium框架/初始化

方法一
<!--selenium依赖-->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.4.0</version>
</dependency>
package com.test;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
public class FirstWebTest{
    public static void openChrome(){
        //chrome驱动
        System.setPropery("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
        //打开chrome浏览器
        ChromeDriver chromeDriver = new ChromeDriver();
        //访问google
        chromeDrvier.get("https://www.google.com");
    }
    public static void  openFireFox(){
        //firefox安装路径
        System.setProperty("webriver.firefox.bin","FireFox_Path");
        //firefox驱动
        FirefoxDriver firefoxDriver = new FirefoxDriver();
        //访问bing
        firefoxDriver.get("https://www.bing.com");
    }
    public static void OpenIE(){
        //IE驱动
        System.setProperty("webdriver.ie.driver","src/test/resources/IeDriverServer.exe");
		//IE保护模式解决方案01
		//打开IE浏览器->工具->安全->全部勾选启用保护模式
		//不推荐
		
        //IE保护模式解决方案02
        //取消IE安全设置(忽略IE的Protexted Mode的设置)
        DesiredCapadbilities capabilities = new DesiredCapabilities();
       capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true);
        //IE浏览器缩放设置
		capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING,true);
        
		//1.打开IE浏览器
		InternetExplorerDriver ieDriver = new InternetExplorerDriver();
		//2.打开baidu
		ieDriver.get("https://www.baidu.com");
    }
}
方法二
<dependency>
	<groupId>io.github.bonigarcia</groupId>
	<artifactId>webdrivermanager</artifactId>
	<version>3.6.2</version>
	<scope>test</scope>
</dependency>
//Call any of the line based on which browser you are using.
WebDriverManager.chromedriver().setup();
WebDriverManager.firefoxdriver().setup();
WebDriverManager.iedriver().setup();
WebDriverManager.operadriver().setup();
WebDriverManager.phantomjs().setup();
WebDriverManager.edgedriver().setup();
方法三
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.6.0</version>
</dependency>

元素定位

  • id:根据id来获取元素,返回单个元素,id值一般是唯一的

    <p id="a" name="b" class="c"></p>
    #id为a
    
    chromeDriver.findElementById("a");
    #定位id为a的元素
    
  • name:根据元素的name属性来获取元素,可能返回元素集合

    <p id="a" name="b" class="c"></p>
    #name为b
    
    chromeDriver.findElementByName("b");
    #定位到name为b的元素
    
  • tagName:根据元素的标签名来获取元素,可能返回元素集合

    <p id="a" name="b" class="c"></p>
    #标签名为p
    
    chromeDriver.findElementByTagName("p");
    #定位到标签名为p的元素
    
  • className:根据元素的class值来获取元素,可能返回元素集合

    <p id="a" name="b" class="c"></p>
    #class值为c
    
    chromeDriver.findElementByClassName("c");
    #定位到class值为c的元素
    
  • linkText:根据超链接的文本值来获取元素

    <a href="www.baidu.com">百度</a>
    #超链接的完整文本值为	百度
    
    chromeDriver.findElementByLinkText("百度").click();
    #定位到文本值为百度的超链接并点击
    
  • partialLinkText:根据超链接的部分文本值来获取元素

    <a href="www.baidu.com">百度</a>
    #超链接的完整文本值为	百度
    
    chromeDriver.findElementByPartialLinkText("百");
    #定位到超链接的文本值中含有“百"的元素
    
  • cssSelector

    • 根据tagName

      chromeDriver.findElementByCssSelector("input");
      
    • 根据ID

      chromeDriver.findElementByCssSelector("#text");
      //id为text
      
    • 根据className(样式名)

      chromeDriver.findElementByCssSelector(".className");
      //class值为className
      
    • css精确定位

      根据元素属性,属性名=属性值,id、class等都可以写成这种形式

      chromeDriver.findElementByCssSelector("input[name='xxx']")
      

      多属性

      chromeDriver.findElementByCssSelector("input[name='xxx'][class='xxx']")
      
  • xpath

    xpath其实就是一个path(路径),一个描述页面元素位置信息的路径,相当于元素的坐标。

    xpath基于XML文档树状结构,是XML路径语言,用来查询xml文档中的节点

    • 绝对定位

      从根目录开始找

      /html/body/div[2]/div/form/input

      缺点:一旦页面结构发生变化(比如重新设计时,路径少了两节),该路径也随之失效,必须重新写

    • 相对路径

      //*[@name='phone']匹配name=‘phone’的所有元素

      //a[text()='新闻']匹配文本值为新闻的超链接

      //a[contains(text(),'新')]匹配文本值含有的超链接元素

      路径解释

      • //匹配指定节点,不考虑它们的位置
      • *通配符,匹配任意元素节点
      • @选取属性
      • []属性判断条件表达式

      相对定位优点:

      灵活、方便、耦合性低

元素操作API

  • click()

    触发当前元素的点击事件

  • clear()

    清空内容

  • sendKeys()

    往文本框一类元素中写入内容

    element.sendKeys(Keys.CONTROL,"a");//ctrl+a
    element.sendKeys(Keys.CONTROL,"X");//ctrl+x
    element.sendKeys(Keys.CONTROL,"c");//ctrl+c
    element.sendKeys(Keys.CONTROL,"v");//ctrl+v
    element.sendKeys(Keys.ENTER);//回车
    element.sendKeys(Keys.BACK_SPACE);//删除
    element.sendKeys(Keys.SPACE);//空格
    
  • getTagName()

    获取元素的标签名

  • getAttribute()

    根据属性名获取元素属性值

  • getText()

    获取当前元素的文本值

  • isDisplayed()

    查看元素是否显示

WebDriver相关API

  • get(String url)

    访问指定url页面

  • getCurrentUrl()

    获取当前页面的url地址

  • getTitle()

    获取当前页面的标题

  • getPageSource()

    获取当前页面源代码

  • quit()

    关闭驱动对象以及所有相关的窗口

  • close()

    关闭当前窗口

  • getWindowHandle()

    返回当前页面句柄

  • getWindowHandles()

    返回所有由驱动对象打开页面所有的句柄,页面不同,句柄不一样

  • manage()

    此方法可以获取Options——浏览器菜单操作对象

    driver.manage().window()

    Options options = chromeDriver.manage();
    Dimension dimension=null;
    options.window().fullscreen();//全屏
    Thread.sleep(3000);
    dimension = options.window().getSize();
    System.out.println("窗口的高度\t"+dimension.getHeight()+"\n窗口的宽度\t"+dimension.getWidth());
    System.out.println("窗口的坐标\t"+options.window().getPosition().getX()+","+options.window().getPosition().getY());
    options.window().maximize();//最大化
    Thread.sleep(3000);
    dimension = options.window().getSize();
    System.out.println("窗口的高度\t"+dimension.getHeight()+"\n窗口的宽度\t"+dimension.getWidth());
    System.out.println("窗口的坐标\t"+options.window().getPosition().getX()+","+options.window().getPosition().getY());
    
  • navigate对象

    Navigation navigation = driver.navigate();
    //获取navigate对象
    
    navigation.to(url);
    //访问指定的url地址
    
    navigation.refresh();
    //刷新当前页面
    
    navigation.back();
    //浏览器回退操作
    
    navigation.forward();
    //浏览器前进操作
    

等待

硬性等待

Thread.sleep(long millis)

线程休眠,强制等待

隐式等待

driver.manage.timeouts().implicitlyWait(long time,TimeUnit)

在设置的超时时间范围内不断查找元素,直到找到元素或者超时

优点:相对灵活

缺点:设置时针对全局的,在WebDriver实例整个生命周期有效,但并不是所有的元素都需要等待。

private ChromeDriver chromeDriver;
private Navigation navigation;
@Before
public void setUp() {
    System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver.exe");
    chromeDriver = new ChromeDriver();
    navigation = chromeDriver.navigate();
}
@After
public void tearDown() {
    chromeDriver.quit();
    navigation = null;
    chromeDriver = null;
}
@Test
public void testImplicitlyWait() {
    //在driver实例化完成之后设置隐式等待,设置超时时间为3S
    chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
    chromeDriver.get("https://www.google.com");
    WebElement input = chromeDriver.findElementByXPath("//input[@class='gLFyf']");
    input.sendKeys("selenium");
    input.sendKeys(Keys.ENTER);
    chromeDriver.findElementByXPath("//h3[text()='Selenium']").click();
}
显示等待

用来等待某个条件发生后再继续执行后续代码(如找到元素、元素可点击、元素已显示等

设置方式

WebDriverWait wait = new WebDriverWait(WebDriver driver, long timeOutInSeconds);

WebElement element = wait.until(expectConaition);

方法等待条件
visibilityOfElementLocated(By locator)页面元素再页面存在并且可见
elementToBeClickable(By locator)页面元素是否在页面上可用和可被单击
elementToBeSelected(WebElement element)页面元素处于被选中状态
textToBePresentInElement(By locator)在页面元素中是否包含特定的文本
presenceOfElementLocated(By locator)页面元素在页面中存在
chromeDriver.get("https://www.google.com");
WebElement input = chromeDriver.findElementByXPath("//input[@class='gLFyf']");
input.sendKeys("selenium");
input.sendKeys(Keys.ENTER);
//显示等待
WebDriverWait webDriverWait = new WebDriverWait(chromeDriver,3);//超时3s
webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//h3[text()='Selenium']")));//元素存在且可见
chromeDriver.findElementByXPath("//h3[text()='Selenium']").click();

特殊元素操作

模态框

Modal Dialogue Box ,又叫做模式对话框,是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。如单击【确定】或【取消】按钮等将该对话框关闭。

  • alert
  • confirm
private ChromeDriver chromeDriver;
private Navigation navigation;
@BeforeClass
public static void setUpBeforeClass() {
    System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
}
@Before
public void setup() {
    chromeDriver = new ChromeDriver();
    navigation = chromeDriver.navigate();
    chromeDriver.get(" C:/Users/lf-27/OneDrive/eclipse/webauto/src/main/resources/alert.html");
    chromeDriver.manage().window().maximize();
    chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
}
@After
public void dearDown() {
    navigation = null;
    chromeDriver.quit();
    //chromeDriver = null;
}
@AfterClass
public static void dearDownAfterclass() {
    //待定
}
@Test
public void testAlert() {
    //点击按钮
    chromeDriver.findElementById("btn").click();
    //switchTo.alert	找到对应的alert弹框
    Alert alert = chromeDriver.switchTo().alert();
    System.out.println(alert.getText());//获取alert上的value值
    alert.accept();//确认
    //alert.dismiss();//取消
}
@Test
public void testConfirm() throws InterruptedException {
    //点击按钮
    chromeDriver.findElementById("confirm").click();
    Thread.sleep(2000);
    //找到对应的comfirm弹框
    Alert alert = chromeDriver.switchTo().alert();
    alert.accept();
    //alert.dismiss();
    System.out.println(alert.getText());
    alert.accept();
}
iframe

iframe切换

四种切换方式:

  • driver.switchTo().frame(index);
  • driver.switchTo().frame(id);
  • driver.switchTo().frame(name);
  • driver.switchTo().frame(WebElement);

切换之后,回到默认内容页面(否则会找不到元素)

driver.switchTo().defaultcontent();

private ChromeDriver chromeDriver;
private Navigation navigation;
@BeforeClass
public static void setUpBeforeClass() {
    System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
}
@Before
public void setUp() {
    chromeDriver = new ChromeDriver();
    navigation = chromeDriver.navigate();
    chromeDriver.get("C:/Users/lf-27/Onedrive/eclipse/webauto/src/main/resources/a.html");
    chromeDriver.manage().window().maximize();
    chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
}
@After
public void dearDown() {
    navigation = null;
    chromeDriver.quit();
}
@Test
public void test1001() throws InterruptedException {
    //在默认的页面找输入框并输入数据
    chromeDriver.findElementById("aa").sendKeys("aaa");
    //进入第一个内嵌页面定位元素并输入数据
    //切换iframe
    chromeDriver.switchTo().frame("bframe");
    chromeDriver.findElementById("bb").sendKeys("bbb");
    //
    chromeDriver.switchTo().frame("cframe");
    chromeDriver.findElementById("cc").sendKeys("ccc");
    //切换回默认的页面
    chromeDriver.switchTo().defaultContent();
    chromeDriver.findElementById("aa").clear();
    Thread.sleep(3000);
}
window

当你要操作另一个窗口页面的元素时,一定要注意先切换窗口切换方式:传入要操作窗口的name或者句柄handle

driver.switchTo().window(nameOrHandle)

如何获取到窗口的句柄

  • driver.getWindowHandle();//获取当前窗口的句柄
  • driver.getWindowHandles();//获取测试打开的所有窗口句柄
private ChromeDriver chromeDriver;
private Navigation navigation;
@BeforeClass
public static void setUpBeforeClass() {
    System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
}
@Before
public void setUp() {
    chromeDriver = new ChromeDriver();
    navigation = chromeDriver.navigate();
    chromeDriver.get("C:/Users/lf-27/Onedrive/eclipse/webauto/src/main/resources/window/a.html");
    chromeDriver.manage().window().maximize();
    chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
}
@After
public void dearDown() {
    navigation = null;
    chromeDriver.quit();
}
@Test
public void windowTest() throws InterruptedException {
    chromeDriver.findElementById("aa").sendKeys("this is first window");
    Thread.sleep(3000);
    System.out.println("跳转前句柄\t"+chromeDriver.getWindowHandle());
    chromeDriver.findElementById("bb").click();
    System.out.println("跳转后句柄\t"+chromeDriver.getWindowHandle());
    //进入到b窗口后获取所有句柄
    Set<String> handles = chromeDriver.getWindowHandles();
    for(String handle:handles) {
        //切换句柄
        chromeDriver.switchTo().window(handle);
        //符合条件则break
        if(chromeDriver.getTitle().equals("b")) {
            //对b窗口元素进行定位
            break;
        }
    }
    System.out.println("切换句柄\t"+chromeDriver.getWindowHandle());
    chromeDriver.findElementById("bb").sendKeys("this is second window");
    Thread.sleep(3000);
}
select下拉框

如果页面元素是一个下拉框,我们可以将此web元素封装为Select对象

  • Select select = new Select(WebElement element);

api

select.getOptions();//获取所有选项
select.selectByIndex(index);//根据索引选中对应的元素,从0开始
select.selectByValue(value);//选择指定value值对应的选项
select.selectByVisibleText(text);//选中文本值对应的选项
//select下拉框处理
chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
chromeDriver.get("https://www.baidu.com");
//根据父元素找子元素
chromeDriver.findElementByXpath("//div[@id='ul']/a[text()='设置']")).click();
chromeDriver.findElementByXpath("//a[text()='高级搜索']").click();

//定位到时间下拉框
WebElemenet webElement = chromeDriver.findElementByName("gpc");
//把webElement封装成Select对象
Select select = new Select(webElement);
//根据index值选
select.selectByIndex(0);//第一个
Thread.sleep(1000);
//根据value值选择
//select.selectByValue();
//根据文本值选择
select.selectByVisibleText("最近一个月");
日期时间控件

分为两种情况

  • 控件没有限制手动输入,则直接调用sendKeys方法写入时间数据

    //可以输入的input类型时间日期控件
    chromeDriver.findElementByXpath("//form[@id='J_FlightForm']//input[@name='depDate']").sendKeys("2000-01-01");
    
  • 控件有限制输入,则可以执行一段js来改变元素的value属性值

    JavascriptExecutor jsExecutor = (JavascriptExecutor)driver;
    jsExcutor.executeScript("...");
    
    //限制输入的时间日期控件
    //javaScript执行对象
    JavaScriptExecutor javascriptExecutor = (JavaScriptExecutor)chromeDriver;
    javascriptExecutor.executeScript("document.getElementById(\"train_date\").reomveAttribute(\"readonly\")");
    chromeDriver.findElementById("train_date").clear();
    chromeDriver.findElementById("train_date").sendKeys("2000-01-10");
    
鼠标操作

自动化测试时,有些元素不适合直接点击或者进行某些操作时,可以使用Selenium的Actions类来模拟鼠标键盘操作,通过Actions对象可以发起鼠标左键、右键、移动鼠标等操作。

actions.clickAndHold(onElement).moveToElement(toElement).release).build().perform();
private ChromeDriver chromeDriver;
@BeforeClass
public static void setUpBeforeClass() {
    System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
}
@Before
public void setUp() {
    chromeDriver = new ChromeDriver();
    chromeDriver.get("http://www.treejs.cn/v3/demo/cn/exedit/drag.html");
    chromeDriver.manage().window().maximize();
    chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
}
@After
public void dearDown() {
    //		chromeDriver.quit();
}
@Test
public void testDrag() {
    //鼠标操作
    WebElement sourceElement = chromeDriver.findElementById("treeDemo_2_span");
    WebElement targetElement = chromeDriver.findElementById("treeDemo_3_span");
    //实例化Acitons
    Actions actions = new Actions(chromeDriver);
    //鼠标相关操作
    //clickAndHold()	点击并按住
    //moveToElement()	移动到指定元素
    //release().build()	释放、构建
    //perform()	运行
    actions.clickAndHold(sourceElement).moveToElement(targetElement).release().build().perform();
}
文件上传
  • 使用sendKeys写入文件的路径

    <input type="file" id="fu" value="选择文件">
    
    private ChromeDriver chromeDriver;
    @BeforeClass
    public static void setUpBeforeClass() {
        System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
    }
    @Before
    public void setUp() {
        chromeDriver = new ChromeDriver();
        chromeDriver.get("C:\\Users\\lf-27\\OneDrive\\eclipse\\webauto\\src\\main\\resources\\upload.html");
        chromeDriver.manage().window().maximize();
        chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
    }
    @After
    public void dearDown() {
        //		chromeDriver.quit();
    }
    @Test
    public void testUpload() {
        chromeDriver.findElementByXPath("//input[@value='选择文件']").sendKeys("C:\\Users\\lf-27\\OneDrive\\downloads\\HK.pem");
        chromeDriver.findElementByXPath("//input[@id='upload']").click();
    }
    
  • 如果文件上传不是input元素,而是使用第三方的控件。并且不是input元素,那么这种情况就很棘手了,必须使用一些第三方的工具,比如autoit等来完成。

验证码
  • 去除验证码

    改代码

  • 自动识别

    有门槛

  • 万能验证码(推荐)

    改代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值