selenium浏览器自动化测试【基于java】

Selenium准备

Selenium是一个用于Web应用程序的自动化测试工具。它直接运行在浏览器中,可以模拟用户在浏览器上面的行为操作。

chrome下载

https://www.google.com/chrome/ 

下载的结果是 “ChromeSetup.exe”,双击该文件,安装程序会自动启动。

默认安装位置:C:\Program Files\Google\Chrome\Application\chrome.exe

结果我的在:C:\Users\91073\AppData\Local\Google\Chrome\Application\chrome.exe

。。。为啥?


下载驱动

最新版:Chrome for Testing availability

查看谷歌浏览器版本

谷歌浏览器输入网址的地方输入:chrome://version

下载与浏览器对应(或相近)版本的浏览器驱动:http://chromedriver.storage.googleapis.com/index.html

 备用地址:CNPM Binaries Mirror

解压后得到一个chromedriver.exe驱动文件


禁用自动升级

关闭自动升级方法:

1.右键单击【计算机】——【管理】——【计算机管理本地】——【系统工具】——【任务计划程序】——【任务计划程序库】——这里找到两个和Google自动更新相关的任务计划【GoogleUpdateTaskMachineCore】与【GoogleUpdateTaskMachineUA】,把这两个选项禁用。

2.在【服务和应用程序】——【服务】,这里找到了两个和Google更新相关的服务【Google更新服务(gupdate)】、【Google更新服务(gupdatem)】,右键——选择属性——启动类型禁用即可;


卸载谷歌浏览器

在卸载当前版本之前,建议备份你的书签、扩展、密码等资料。

  1. 通过Windows + R快捷键调出“运行”对话框。
  2. 键入APPWIZ.CPL和命中输入。

这将带您到所有已安装应用程序的列表。从列表中选择Google Chrome,然后点击卸载 命令。


降级版本

版本报错

Caused by: org.openqa.selenium.SessionNotCreatedException: session not created: This version of ChromeDriver only supports Chrome version 114
Current browser version is 116.0.5845.97 with binary path C:\Users\91073\AppData\Local\Google\Chrome\Application\chrome.exe

Google浏览器历史版本下载地址

Download older versions of Google Chrome for Windows, Linux and Mac

按住alt键,双击桌面的谷歌浏览器桌面图标

拷贝目标路径:C:\Users\lenovo\AppData\Local\Google\Chrome\Application\chrome.exe

打开命令提示符,输入如下并回车键;

cd C:\Users\lenovo\AppData\Local\Google\Chrome\Application

输入“chrome.exe--disable-remote-words-auto-upgrade--version=版本号”,然后按回车键。在这里,请将“版本号”替换为所需的版本号。


Selenium入门

maven坐标

打开selenium的仓库地址 :https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java

直接拷贝到pom文件吧,,

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.5</version>
</dependency>

<!-- 测试工具testng-->
<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.14.3</version>
    <scope>test</scope>
</dependency>

入门案例

如果浏览器驱动未加入环境变量,那么创建浏览器驱动的时候,需要指定浏览器驱动的路径

public class Client {

    public static void main(String[] args) throws InterruptedException {
        //配置浏览器驱动地址
        System.setProperty("webdriver.chrome.driver", "D:\\tools\\chrome\\driver113\\chromedriver.exe");
        //打开Chrome浏览器
        WebDriver webDriver = new ChromeDriver();
        TimeUnit.SECONDS.sleep(5);
        //打开百度网站
        webDriver.get("https://www.baidu.com");
        TimeUnit.SECONDS.sleep(2);
        //输入框输入搜索关键词 selenium 中文官网
        webDriver.findElement(By.id("kw")).sendKeys("selenium 中文官网");
        TimeUnit.SECONDS.sleep(2);
        //点击百度一下按钮
        webDriver.findElement(By.id("su")).submit();
        TimeUnit.SECONDS.sleep(2);
        //查询所有搜索的结果
        List<WebElement> resultElements = webDriver.findElements(By.className("result"));
        if (!resultElements.isEmpty()) {
            //找到第一条结果的第一个链接
            List<WebElement> aTagElements = resultElements.get(0).findElements(By.tagName("a"));
            if (!aTagElements.isEmpty()) {
                //新开一个窗口打开此链接
                String href = aTagElements.get(0).getAttribute("href");
                System.out.println(href);
                ((JavascriptExecutor) webDriver).executeScript(String.format("window.open('%s')", href));
            }
        }
        TimeUnit.SECONDS.sleep(10);
        //关闭浏览器
        webDriver.quit();
    }
}

结果,很神奇的哦


命令行打开浏览器

new ChromeDriver(options);

如果希望Chrome 浏览器启动时附带启动参数,可通过addArguments 方式加载。

希望测试某个浏览器插件,可通过addExtensions方式提前加载以.crx 为扩展名的插件

感觉上和addArguments有点类似,不过setExperimentalOption是设置实验选项ChromeDriver选项尚未通过ChromeOptions API公开),这个方法我比较经常用来设置浏览器默认下载路径

对于一台机器上安装了多个版本的Chrome浏览器,可以使用setBinary 指定待测试Chrome。

让 selenium 连接我们手动打开的浏览器

打开浏览器有两种方式:图标点击和命令行运行。

图标点击不用多说,我们经常使用这种方式打开浏览器。命令行方式允许我啰嗦一句,找到浏览器的安装目录,在安装目录中输入 chrome.exe 就可以了。 比如我的 chrome 浏览器安装在

C:\Users\91073\AppData\Local\Google\Chrome\Application

这个路径,则在这个目录下打开 cmd 命令行,输入 chrome.exe,就可以打开一个浏览器

在浏览器打开的时候设置额外的参数,为它提供不同的功能。 通过 selenium 连接浏览器,需要用到两个参数 --remote-debugging-port 和 --user-data-dir

  • --remote-debugging-port 这个参数允许我们通过远程的方式连接,selenium 当然也可以。
  • --user-data-dir 这个参数指定一个独立的目录存放产生的用户数据,在连接时也要设置,否则会失效。
chrome.exe --remote-debugging-port=9222 --user-data-dir="F:\selenium\ChromeProfile"

有了远程调试地址,selenium 连接浏览器就变的很简单,只需要加 2 行代码。 创建一个选项,绑定debuggerAddress 远程调试地址。 此时就可以用 selenium 控制之前手工打开的浏览器了。

            //配置浏览器驱动地址
            System.setProperty("webdriver.chrome.driver", "F:\\webrpaTest\\RPA\\RoboticProcessAutomation\\browser\\driver\\chrome\\121\\chromedriver.exe");
            ChromeOptions options = new ChromeOptions();
            options.setBinary("C:\\Users\\91073\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe");
            //设置 Chrome 的远程调试端口地址
            options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
//            WebDriver driver = new ChromeDriver(ChromeDriverService.createDefaultService(), options);
            WebDriver driver = new ChromeDriver(options);
            System.out.println(driver.getTitle());

WebDriver 实例化参数

Chome浏览器部分

executable_path:浏览器驱动程序路径,如果没有制定,则默认使用环境变量PATH中设置的路径

options:启动选项 (Options对象通常位于各浏览器的 WebDriver 模块下,列如:from selenium.webdriver.浏览器名称.options import Options),建议优先使用options 参数来设置浏览器(options 基于 capabilities,在实例化某个浏览器的Options对象时会自动写入该浏览器预设的 capabilities)

  • service_log_path:驱动程序存放日志文件的位置

  • keep_alive:表示在与 ChromeDriver 进行链接时,是否带上 HTTP 请求头Connection: keep-alive,既是否使用长链接,布尔类型参数,默认值为True

  • service_args:浏览器驱动程序的参数,根据所使用的浏览器驱动不同,参数也有可能不同。

Edge浏览器部分

  • executable_path:浏览器驱动程序路径,如果没有制定,则默认使用环境变量PATH中设置的路径
  • capabilities:非浏览器特定的字典对象,传入浏览器启动参数时需要使用到
    port:驱动程序启用的端口号,如果不填写,则自动使用任意闲置的端口号,默认参数为0
    verbose:是否在服务中设置详细日志记录
    service_log_path:驱动程序存放日志文件的位置
    log_path:不推荐使用的 service_log_path 参数
    keep_alive:表示在与 EdgeDriver 进行链接时,是否带上 HTTP 请求头Connection: keep-alive,既是否使用长链接,布尔类型参数,默认值为True


元素定位

web自动化的难点和重点之一,就是如何 选择 我们想要操作的web页面元素。

id定位

id 定位 driver.findElement(By.id(“id的值”));

如果元素有id属性 ,这个id 必须是当前html中唯一的。所以如果元素有id, 根据id选择元素是最简单高效的方式。

  1. 使用WebDriver对象的findElement函数定义一个Web页面元素
  2. 使用findElements函数可以定位页面的多个元素

使用 find_elements 选择的是符合条件的 所有 元素, 如果没有符合条件的元素, 返回空列表

List<WebElement> listOfElements = driver.findElements(By.xpath("//div"));
webElement.findElements(By.tagName("tr"));
  • 如果没有匹配条件的元素,Find Elements命令将返回一个空列表

使用 find_element 选择的是符合条件的 第一个 元素, 如果没有符合条件的元素, 抛出 NoSuchElementException 异常

定位的页面元素需要使用WebElement对象来存储,以便后续使用


class定位

class 定位    driver.findElement(By.className(“class属性”));

 //企查查
 webDriver.get("https://www.qcc.com/");
 TimeUnit.SECONDS.sleep(2);
 //查企业 查老板 查风险 查招标 找关系
 List<WebElement> elements = webDriver.findElements(By.className("search-type"));

class 属性通常用于指向样式表的类

在html中,class规定元素的类名,语法格式为“<元素名称 class="value">”。class属性大多数时候用于指向样式表中的类(class)。

html标签是允许定义多个class类名的。比如:

<div class = "exp1 exp2"></div>

上边这个div就用到了exp1、exp2这两个class类,对于个数是没有限制,只需每个类名之间用空格隔开就好。


tag 名 定位

TagName 标签名称定位    driver.findElement(By.tagName(“标签名称”));

选择所有的tag名为 div的元素,如下所示


name定位

name定位    driver.findElement(By.name(“name的值”));

css定位

CSS定位为的优势在于定位速度比Xpath定位快,且比Xpath定位更加稳定

css 方式定位    driver.findElement(By.cssSelector(“css表达式”));

Xpath定位

xpath路径开头

xpath 是XML Path的简称, 用于在XML文档中选择文档中的节点。基于XML树状文档结构,Xpath语言可以在整棵树中寻找指定的节点。

xpath 方式定位
driver.findElement(By.xpath(“xpath表达式”));

xpath 有两种表示方法,绝对路径和相对路径,

绝对路径是指从根开始,以/开始,如/html/body/div,

相对路径是指在一个路径下,另外的路径以这个路径作为参照,以//开始。从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。

  • XPath表达式中的//表示在HTML文档的全部层级位置进行查找

举例如下:

//百度一下
webDriver.get("https://www.baidu.com");
WebElement element = webDriver.findElement(By.xpath("//*[@id='su']"));

这里为啥是//*[@] 呢?

  • //表示从任意位置去查找
  • *是标签名
  • @是属性定位

强烈建议使用相对路径和属性值结合的定位方式来编写xpath定位表达式。如

By.xpath("//*[@id='su']")

xpath获取

xpath获取技巧:网页的html是一种特殊的XML文档。使用浏览器调试工具,可以直接获取xpath语句

右键-检查(或者F12),然后点击这个箭头,就可以在浏览器上选择元素了

使用Chrome 来直接获取元素的XPath.

通过层级关系和索引定位(索引从1开始):

//*[@id="content"]/div/div[2]/div[4]/div[2]/h2/div[2]/form/div

标签+属性定位

XPath通过idnameclass属性定位。语法如下:

//标签名[@属性名='属性值']
//用XPath通过id属性定位  
element1 = driver.find_element_by_xpath("//input[@id='kw']")

//用XPath通过name属性定位  
element2 = driver.find_element_by_xpath("//input[@name='wd']")

//用XPath通过class属性定位  
element3 = driver.find_element_by_xpath("//*[@class='s_ipt']")

总结

  1. 如果不想制定标签名称,可以用*号表示任意标签。
  2. 有时候同一个属性,同名的比较多,这时候可以通过标签筛选下,定位更准一点。
  3. 如果想制定具体某个标签,就可以直接写标签名称

List pageUl = ar.driver.findElements(By.xpath("//ul[@class='bfe-pager']"));//获取页数


层级定位

通过层级关系定位,注意:最终定位的是子标签....语法如下:

 //父标签名[@父标签属性名='属性值']/子标签

在页面中,定位下面代码片段中的<input>标签

<p id="p1">
    <label for="userA">账号A</label>
    <input required="" value="">
</p>

答案如下:

driver.find_element_by_xpath("//p[@id='p1']/input")

索引定位

索引定位元素,语法如下:

//父标签名[@父标签属性名='属性值']/子标签[索引值]   索引从1开始

比如我要定位如下图片的“京东家电连接”

答案是:

//*[@id=\"navitems-group1\"]/li[2]/a

用id="navitems-group1"定位到如下图片这里,这些是一些li标签

//*[@id="navitems-group1"]/li[1]/a

//*[@id="navitems-group1"]/li/a

注意:如果是第一个元素,索引值可以不加。因为不加索引值会选取ul下的全部li标签
而我们用的是单数定位形式,默认选择第一个。


文本定位

//标签名[text()=‘文本’]

xpath定位时,定位某一元素不好定时,可以定位其子级元素,然后通过 /… 定位到它的父级元素

HTML实例:<button type="button" class="ant-btn ant-btn-primary"><span>新 建</span></button>
xpath定位://span[text()='搜 索']/..

逻辑定位

XPath逻辑定位说明:

  1. xpath还有一个比较强的功能,可以支持与(and)、或(or)、非(not)。
  2. 一般用的比较多的是and运算,同时满足两个属性。

父子、兄弟、相邻节点定位方式

获取文本

//h5[text()='可用余额'

//span[text() = '全部']/parent::label/span[1]

子节点定位父节点

result = html.xpath('//a[@id="parentSpan"]/text()')

获取 href 属性

# 8、获取 href 属性
result = html.xpath('//a[@id="parentSpan"]/@href')

操控元素

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

输入框 send_keys

操控元素:send_keys在元素中输入字符串,通常是对输入框这样的元素

//访问京东
webDriver.navigate().to("https://www.jd.com/");
WebElement input = webDriver.findElement(By.id("key"));
//清空输入框 //*[@id="key"]
input.clear();
//在输入框中输入内容
input.sendKeys("蓝牙耳机");

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

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

按钮 click

操控元素:click点击元素

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

效果就是模拟人:打开京东---输入“蓝牙耳机”--点击搜索

//访问京东
webDriver.navigate().to("https://www.jd.com/");
WebElement input = webDriver.findElement(By.id("key"));
//清空输入框 //*[@id="key"]
input.clear();
//在输入框中输入内容
input.sendKeys("蓝牙耳机");
//单击搜索按钮
WebElement search = webDriver.findElement(By.xpath("//*[@id='search']/div/div[2]/button"));
search.click();

下拉选择框

获取元素包含的信息,比如文本内容,元素的属性

在下拉列表中选择值?

  • 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());
 }

操作复选框

如下图,我们勾选全局搜索和忽略大小写

操作单选框

如下图,我们操作使得打开网站后,选择时间戳为“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

链接的操作

// 找到链接元素
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();

窗口切换

//获取当前所有打开的浏览器窗口的句柄
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);

控制台打印输出如下


窗口关闭

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();


frame切换/窗口切换 | 白月黑羽 (byhy.net)


安居客登录

登录 (anjuke.com)

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


弹窗

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弹窗弹出的时候,需要设置一下等待时间,等页面元素加载完毕,再去做其他操作。这里用百度登陆为例子:


执行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();

隐式等待

强制等待:sleep

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

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

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

隐式等待:implicitlyWait

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

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

隐式等待的默认最长等待时间是0,一旦设置完成,这个隐式等待会在webdriver对象实例的整个生命周期起作用

---------------

隐式等待原理:

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


显式等待

显式等待:WebDriverWait类

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>() {
		@Override
		public Alert apply(WebDriver driver) {
			try {
				return driver.switchTo().alert();
			} catch (NoAlertPresentException e) {
				return null;
			}
		}
	});
	if (alert != null)
		alert.accept();

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

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

.Firefox驱动名称为geckodriver

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值