目录
注:要先把Selenium以及对应浏览器版本的驱动配置好
Hello,world!
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Test01 {
public static void main(String[] args) {
WebDriver wd=new ChromeDriver();//创建对象
wd.get("http://baidu.com");//打开网页
wd.manage().window().maximize();//窗口最大化
wd.close();//关闭网页
}
}
元素定位
定位方法 | Java语言实现实例 |
---|---|
id 定位 | driver.findElement(By.id(“id的值”)); |
name定位 | driver.findElement(By.name(“name的值”)); |
链接的全部文字定位 | driver.findElement(By.linkText(“链接的全部文字”)); |
链接的部分文字定位 | driver.findElement(By.partialLinkText(“链接的部分文字”)); |
css 方式定位 | driver.findElement(By.cssSelector(“css表达式”)); |
xpath 方式定位 | driver.findElement(By.xpath(“xpath表达式”)); |
Class 名称定位 | driver.findElement(By.className(“class属性”)); |
TagName 标签名称定位 | driver.findElement(By.tagName(“标签名称”)); |
Jquery方式 | Js.executeScript(“return jQuery.find(“jquery表达式”)”) |
F12打开开发者控制台
Ctrl+F打开搜索框,在搜索框里可以搜索文本,css selector 和 xpath
Xpath定位
xpath即为XML路径语言(XML Path Language),是由国际标准化组织W3C指定的,一种用来确定XML文档节点位置的语言
xpath定位优点
-
相较于其他定位方式,可支持更多定位方法,如:布尔逻辑判断、模糊定位等
-
可支持web定位、Android app原生页面定位
xpath定位缺点
需要从头到尾解析整个页面,速度较慢
xpath调试方法
方法1:在浏览器开发者模式的elements中,Ctrl+F搜索栏输入xpath表达式
方法2:在浏览器开发者模式的console中,按如下格式可验证表达式
$x("xpath表达式") # 表达式中存在引号,则使用单引号,'$'可更换为'$$'
xpath节点
在xpath中,有七种类型的节点(node):元素、属性、文本、命名空间、处理指令、注释以及文档节点(或称为根节点) 在开始xpath语法前,我们需要简单了解这几种节点:
节点名称 | 说明 | 示例 |
---|---|---|
元素节点 | 网页中的各个标签 | 如<textarea>...</textarea>、<p>...</p> |
根节点 | 网页的第一个元素节点 | 网页的根节点通常为<html>...<html> |
属性节点 | 标签中的各个属性 | 如<div id='su' >...</div>,id即为div节点的属性 |
文本节点 | 标签的文本 | 如<div>啦啦啦</div>,'啦啦啦'即为div节点的文本 |
xpath语法
xpath使用路径表达式描述目标节点与网页头的关系
绝对路径 & 相对路径 路径表达式有两种结构,分别为:
绝对路径:从根节点/html开始往下,一层层的表示出来直到需要的节点为止。以百度输入框为例,表达式为:
/html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[1]
相对路径:从任意节点开始,根据节点描述信息找到需要的节点。同样以百度输入框为例,表达式为:
//input[@id='su']
对比两种表达式,可以发现:
-
相对路径更简洁,方便阅读
-
相对路径更稳定,当前端页面有结构变动就容易引起绝对路径发生变化
因此,在项目中几乎都是使用相对路径进行定位
xpath基本表达式
表达式 | 说明 | 示例 | 示例说明 |
---|---|---|---|
nodename | 选取此节点的所有子节点 | html | 选取<html>根节点的所有子节点 |
/ | 从根节点选取,或者用来选择子节点 | /html/body/textarea | 选择<body>中的所有<textarea>子节点 |
// | 从匹配节点开始选取,或者选择后代节点 | /html/body//textarea | 选择<body>中的所有<textarea>后代节点 |
| | 选择多个节点 | //div|//a | 选择所有<div>节点和<a>节点 |
.. | 选择当前节点的父节点 | //p/.. | 选择所有<p>的父节点 |
* | 选择所有节点 | /html/body/* | 选择<body>中的所有节点 |
xpath谓语表达式
谓语表达式(predicate):紧跟在节点后面,嵌入在[]中的一段表达式,可用来筛选多个同名节点 谓语表达式作用原理:获取节点信息,通过表达式判断节点是否符合要求,为True则返回该节点 谓语格式:
节点名称[谓语]
常用谓语 | 说明 | 示例 | 示例说明 |
---|---|---|---|
n | 节点编号 | //div[2] | 选择所有<div>节点且该节点是其父级的第二个<div>节点 |
last() | 最后一个节点 | //div[last()] | 选择所有<div>节点且该节点是其父级的最后一个子节点 |
position() | 比较节点编号 | //div[position() < 3] | 选择所有<div>节点且该节点是其父级的前两个<div>节点 |
@属性 | 属性 | //input[@id] | 选择所有<input>节点且该节点带id属性 |
@属性='属性值' | 比较属性 | //input[@id='kw'] | 选择所有<input>节点且该节点id属性为'kw' |
text() | 比较节点文本 | //a[text()='新闻'] | 选择所有<a>节点且该节点文本为'新闻' |
谓语运算符 | 说明 | 示例 | 示例说明 |
---|---|---|---|
= != > < >= <= | 大小比较 | /html/body/div[position()=2] | 选择<body>中的第2个<div>子节点 |
+ - *、 div mod | 加减乘除求余 | /html/body/div[last()-1] | 选择<body>中的倒数第2个<div>子节点 |
and or not() | 或、且、非运算 | //*[@id='kw' and @class='s_ipt'] | 选择所有id='kw'并且class='s_ipt'的节点 |
contains() | 包含 | //*[contains(text(), '新闻')] | 选择所有文本带有'新闻'二字的节点 |
starts-with() | 以...开始 | //*[starts-with(@id, 's')] | 选择所有文本以'新闻'开头的节点 |
ends-with() | 以...结尾 | ends-with('XML','X') | 选择所有XML以‘X’结尾的节点 |
matches() | 参数匹配指定的模式 | matches("Merano","ran") | 略 |
备注:
-
last()、position()、text()、not()这类带有括号的表达式,实质都是xpath提供的函数,本篇文章只列出了常用函数
-
根据W3C标准,第一个节点编号应该是[1],但在IE5及更高版本中第一个节点编号是[0]
xpath轴(axis)
轴:表示所选节点与当前节点之间的树关系,用来筛选对于当前节点有相同关系的一类节点 轴格式:
当前节点/轴名称::节点名称
轴 | 说明 | 示例 | 示例说明 |
---|---|---|---|
ancestor | 先辈节点 | //input[@id='kw']/ancestor::\ * | 选择id='kw'的<input>节点的所有先辈节点 |
ancestor-or-self | 先辈节点以及当前节点 | 略 | 略 |
attribute | 节点属性 | 略 | 略 |
child | 子节点,等同于/ | /html/body/child::div | 选择<body>中的所有<div>子节点 |
descendant | 后代节点,等同于// | /html/body/descendant::div | 选择<body>中的所有<div>后代节点 |
descendant-or-self | 后代节点以及当前节点 | 略 | 略 |
following | 结束标签之后的所有节点 | 略 | 略 |
namespace | 命名空间 | 略 | 略 |
parent | 父节点 | 略 | 略 |
preceding | 开始标签之前的所有节点 | 略 | 略 |
preceding-sibling | 当前节点之前的所有同级节点 | 略 | 略 |
self | 当前节点 | 略 | 略 |
Xpath定位原文链接:selenium教程 —— xpath定位_selenium xpath定位-CSDN博客
CSS定位
绝对路径是从开始标签(html)一级一级找到目标元素,上下级元素分隔符为>或者空格
driver.find_element_by_css_selector("html body div div div div div form span input").send_keys("小龙女")
driver.find_element_by_css_selector("html>body>div>div>div>div>div>form>span>input").send_keys("小龙女")
1、css属性定位
css选择器策略 | 示例 | 说明 |
---|---|---|
#id | #telA | 选择id="telA"的所有元素。 |
.class | .telA | 选择 class="telA”的所有元素。 |
[属性名=属性值] | [name=telA] | 除了id和class属性,其他属性的定位格式 |
[attribute] | [target] | 选择带有target 属性所有元素。 |
* | * | 选择所有元素。 |
2、css属性值模糊匹配定位
css选择器策略 | 示例 | 说明 |
---|---|---|
[attribute^=value] | a[src^="https"] | 选择其src 属性值以"https”开头的每个<a>元素。 |
[attribute$=value] | a[src$=".pdf"] | 选择其src属性以".pdf“结尾的所有<a>元素。 |
[attribute*=value] | a[src*="abc"] | 选择其src 属性中包含“abc"子串的每个<a>元素。 |
[attribute~=value] | a[title~=flower] | 定位标签属性title值中有独立flower词汇的节点 |
[attribute|=value] | a[lang|=en] | 用于选取带有以指定值开头的属性值的元素。 |
注意:[attribute|=value] 该值必须是整个单词,比如 lang="en",或者后面跟着连字符,比如 lang="en-us"。
3、css标签定位
css选择器策略 | 示例 | 说明 |
---|---|---|
element | p | 定位所有<p>元素。 |
标签名[属性名=属性值] | input#telA | 定位id属性值为telA的所有<input>元素 |
4、css层级关系定位
css选择器策略 | 示例 | 说明 |
---|---|---|
element,element | div,p | 选择所有 <div> 元素和所有 <p> 元素。 |
element element | div p | 选择 <div> 元素内部的所有 <p> 元素。包括子孙后代。 |
element>element | div>p | 选择父元素为 <div> 元素的所有 <p> 元素。只包括子代。 |
element+element | div+p | 选择紧接在 <div> 元素之后的所有 <p> 元素。同辈元素。 |
5、css索引定位
css选择器策略 | 示例 | 说明 |
---|---|---|
:only-child | p:only-child | 选择属于其父元素的唯一子元素的每个 <p> 元素。 |
:nth-child(n) | p:nth-child(2) | 选择属于其父元素的第二个子元素的每个 <p> 元素。 |
:nth-last-child(n) | p:nth-last-child(2) | 同上,从最后一个子元素开始计数。 |
:nth-of-type(n) | p:nth-of-type(2) | 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。 |
:nth-last-of-type(n) | p:nth-last-of-type(2) | 同上,从最后一个子元素开始计数。 |
6、css逻辑运算定位
css选择器策略 | 示例 | 说明 |
---|---|---|
标签名[属性名1=属性值1] [属性名2=属性值2] | input[type='telA'] [placeholder='电话A'] | 同时匹配多个属性 |
7、css元素状态定位
css选择器策略 | 示例 | 说明 |
---|---|---|
:empty | p:empty | 选择没有子元素的每个 <p> 元素(包括文本节点)。 |
:target | #news:target | 选择当前活动的 #news 元素。 |
:enabled | input:enabled | 选择每个启用的 <input> 元素。 |
:disabled | input:disabled | 选择每个禁用的 <input> 元素。 |
:checked | input:checked | 选择每个被选中的 <input> 元素。 |
:not(selector) | :not(p) | 选择非 <p> 元素的每个元素。 |
CSS定位原文链接:Selenium基础 — CSS选择器定位大全_selenium css定位_测试-八戒的博客-CSDN博客
常用基本对象操作方法
操作 | 代码 |
---|---|
点击 | click() |
文本框输入文本 | sendkeys() |
清空文本框 | clear() |
获取文本 | getText() |
获取title | getTitle() |
判断元素是否展示 | isDisplayed() |
判断选择框是否选取 | isSelected() |
判断输入框是否为可输入 | isEnabled() |
单元素及多元素定位管理
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class Test02 {
public static WebDriver wd;
public static void elementSelect(String xpath) {
WebElement element1;
element1=wd.findElement(By.xpath(xpath));
element1.sendKeys("test");//填写内容
}//单元素定位
public static void elementsSelect(String xpath) {
List<WebElement> elements1;//放到List集合中
WebElement element1;
elements1=wd.findElements(By.xpath(xpath));
System.out.println(elements1.size());//元素个数
element1=elements1.get(1);
System.out.println(element1);
}//多元素定位
public static void main(String[] args) {
wd=new ChromeDriver();
wd.get("http://www.mooctest.net/#/loginPage");
wd.manage().window().maximize();
Test02.elementSelect("//input[@type=\"text\"]");
Test02.elementsSelect("//input");
//wd.close();
}
}
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class Test03 {
public static void main(String[] args) {
WebDriver wd=new ChromeDriver();
wd.get("http://ke.qq.com");
wd.manage().window().maximize();
wd.findElement(By.xpath("//input")).sendKeys("jdbc");
wd.findElement(By.linkText("搜索")).click();
List<WebElement> elements1=wd.findElements(By.cssSelector(" span.kc-course-card-student-apply-num---KvJiqW"));
int size=elements1.size();
for(int i=0;i<size;i++) {
System.out.println(elements1.get(i).getText());
}
}
}
一些对象及体系
//弹出框对象:
Alert alert=driver.switchTo().alert();//切换到弹出框alert上
alert=wd.switchTo().alert();
alert.dismiss();
alert.accept();
alert.sendKeys();
alert.getText();
//Select对象
//import org.openqa.selenium.support.ui
//把select定位存到element中
Select select=new Select(element);
select.selectByIndex(3);
//iframe对象
//把iframe定位存到element中
wd.switchTo().frame(element);
wd.switchTo().parentFrame();//切到上一层frame
wd.switchTo().frame("frameName");//类型为String
wd.switchTo().defaultContent();//切到最顶层
//窗体对象
String handle=driver.getWindowHandle();//获取当前句柄
//弹出新窗体
Set<String> handles=driver.getWindowHandles();//获取句柄集
handles.remove(handle);//移除原窗体句柄,句柄集只有新窗体句柄
driver.switchTo().window(handles.iterator().next());//切到新窗体
driver.switchTo().window(handle);//切回原窗体
//或者直接这样写
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
//鼠标事件
Actions actions=new Actions(wd);
//定位element
actions.moveToElement(element).perform();
//键盘事件
try{
Robot robot=new Robot();
robot.keyPress(KeyEvent.VK_ENTER);//按住回车
robot.ketRelease(KeyEvent.VK_ENTER);//松开回车
}catch(AWTException e){
e.printStackTrace();
}
//JavaScript对象
String ss="myalert();";//定义JavaScript语句
ss="document.getElementById(\"输入ID\").value=\"输入值\";";//赋值
ss="document.getElementById(\"输入ID\").removeAttribute(\"readonly\")";//移除只读
JavascriptExecutor js=(JavasciptExecutor)wd;
js.executeScript(ss);
//等待体系
Thread.sleep(2000);//线程等待 等2秒 放到try catch中
wd.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);//全局等待
//显式等待
WebElement element=new WebDriverWait(driver,30).until(ExpectedConditions.presenceOfElementLocated(By))
//显示等待可以自定义等待的条件,用于更加复杂的页面等待条件
//1.页面元素是否在页面上可用和可被单击
elementToBeClickable(By locator)
//2.页面元素处于被选中状态
elementToBeSelected(WebElement element)
//3.页面元素在页面中存在
presenceOfElementLocated(By locator)
//4.在页面元素中是否包含特定的文本
textToBePresentInElement(By locator)
//5.页面元素值
textToBePresentInElementValue(By locator,java.lang.String text)
//截图体系
pom.xml中加上
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
File screenShotFile=((TakesScreenshot)wd).getScreenshotAs(OutputType.FILE);
try{
FileUtils.copyFile(screenShotFile,new File("保存路径"));
}catch (IOException e){
e.printStackTrace();
}
//日志体系
pom.xml中加上
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
在resources目录下放log4j2.xml
private static final Logger logger=LogManager.getLogger(ResolverUtil.Test.class.getname());
logger.log(Level.INFO,"testops log");
logger.error("testops error log");
Web功能测试示例
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
public class Example {
// Mooctest Selenium Example
// <!> Check if selenium-standalone.jar is added to build path.
public static void test(WebDriver driver) {
// TODO Test script
// eg:driver.get("https://www.baidu.com/")
// eg:driver.findElement(By.id("wd"));
try {
driver.get("https://www.yoojia.com/");
driver.manage().window().maximize();
Thread.sleep(5000);
driver.findElement(By.className("city-small")).click();
Thread.sleep(8000);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/header/div/div/div[2]/div[1]/div[2]/section/div/div[2]/div[1]/div[2]/div[3]/div")).click();
Thread.sleep(1500);
driver.findElement(By.linkText("车型库")).click();
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/main/div/aside/div[2]/div[1]/p[1]")).click();
Thread.sleep(1500);
driver.findElement(By.linkText("40万以上")).click();
Thread.sleep(1500);
driver.findElement(By.linkText("轿车")).click();
Thread.sleep(1500);
driver.findElement(By.linkText("德国")).click();
Thread.sleep(1500);
driver.findElement(By.linkText("价格从高到低")).click();
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/main/div/section/div[2]/div[2]/div[8]/a/img")).click();
Thread.sleep(1500);
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/main/div/div[2]/div/div/h2[2]")).click();
Thread.sleep(1500);
driver.findElement(By.linkText("参数")).click();
Thread.sleep(1500);
driver.switchTo().window(driver.getWindowHandles().toArray()[2].toString());
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/main/div/div[1]/div/div[2]")).click();
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/main/div/div[1]/div/div[8]")).click();
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/main/div/div[1]/div/div[12]")).click();
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/main/div/div[1]/div/div[16]")).click();
Thread.sleep(1500);
driver.close();
Thread.sleep(1500);
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"app\"]/section/main/div/div[2]/div/div/h2[3]")).click();
Thread.sleep(1500);
driver.findElement(By.className("title-more")).click();
Thread.sleep(1500);
driver.switchTo().window(driver.getWindowHandles().toArray()[2].toString());
Thread.sleep(1500);
driver.findElement(By.cssSelector("#tab-内饰")).click();
Thread.sleep(1500);
driver.findElement(By.cssSelector("#tab-空间")).click();
Thread.sleep(1500);
driver.findElement(By.cssSelector("#tab-官方图")).click();
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"pane-官方图\"]/div/div/ul/li/div[2]/div[1]/img")).click();
Thread.sleep(1500);
driver.switchTo().window(driver.getWindowHandles().toArray()[3].toString());
Thread.sleep(1500);
driver.findElement(By.xpath("//*[@id=\"pane-官方图\"]/div/div[1]/div[3]")).click();
Thread.sleep(1500);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// Run main function to test your script.
WebDriver driver = new ChromeDriver();
try { test(driver); }
catch(Exception e) { e.printStackTrace(); }
finally { driver.quit(); }
}
}