Selenium是一款非常强大的Web应用程序测试的工具,由于自己需要这块的需求所以简单学习了一下。以下输出的文档有参考官方文档以及几位大佬的博客而输出出来的,仅用于学习参考;
1 官网学习
2 第一个Selenium
2.1 下载驱动
首先得下载对应自己浏览器版本的驱动(一般都是在 (设置->关于 || 帮助->关于) 下面就可以找到版本号)
以下提供几个浏览器驱动链接;
2.2 添加java依赖
踩坑日记:如果想用4.0.0+版本的就需要避免与spring-boot-dependencies版本冲突
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.8.1</version>
</dependency>
2.3 DEMO-百度搜索
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import cn.hutool.system.OsInfo;
import java.util.Arrays;
@Slf4j
public class SeleniumTest {
public static void main(String[] args) throws Exception {
EdgeOptions options =new EdgeOptions();
// 全屏
options.addArguments("disable-infobars", "kiosk");
options.addArguments("--disable-popup-blocking");
// 告诉浏览器我不是自动化测试 可以在浏览器控制台输入window.navigator.webdriver
options.addArguments("disable-blink-features=AutomationControlled");
options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36 Edg/103.0.1264.49");
// 弹框取消
options.setExperimentalOption("excludeSwitches", Arrays.asList("enable-automation"));
options.setExperimentalOption("useAutomationExtension", false);
// 不加载图片, 提升速度
options.addArguments("--blink-settings=imagesEnabled=false");
// 设置页面和js的响应时间为20秒
options.setPageLoadTimeout(Duration.ofSeconds(20));
options.setScriptTimeout(Duration.ofSeconds(20));
OsInfo osInfo = new OsInfo();
if (osInfo.isLinux()) {
// 设置无头模式
options.setHeadless(Boolean.TRUE);
options.addArguments("headless");//无界面参数
options.addArguments("no-sandbox");//禁用沙盒,配合上面两个参数一起使用
// 设置驱动
System.setProperty("webdriver.chrome.driver", "/usr/local/webDriver/chromedriver");
} else {
// 设置驱动
System.setProperty("webdriver.chrome.driver", "F:\\WebDriver\\chromedriver.exe");
}
// 设置驱动
System.setProperty("webdriver.edge.driver", "F:\\WebDriver\\msedgedriver.exe");
// 1.创建webdriver驱动
WebDriver driver = new EdgeDriver(options);
// 2.打开百度首页
driver.get("https://www.baidu.com/");
// 3.获取输入框,输入selenium
driver.findElement(By.id("kw")).sendKeys("selenium");
// 4.获取“百度一下”按钮,进行搜索
driver.findElement(By.id("su")).click();
// 获取页面信息
String html = driver.getPageSource();
log.info("\n获取到页面:\n{}",html);
Thread.sleep(10000);
// 5.实例销毁并退出浏览器
driver.quit();
//实例不销毁,只是把浏览器关掉
//driver.close();
}
}
2.4 将驱动配置在环境变量中
比如我这个在F:\WebDriver下面
可以在环境变量 Path 下加入存放驱动的路径
然后Ctrl+R输入cmd,打开命令窗口后输入chromedriver.exe,只要运行成功了就证明配置成功了。
配置成功后我们代码就可以注释掉手动设置驱动了
//System.setProperty("webdriver.chrome.driver", "F:/WebDriver/chromedriver.exe");
在linux中的话,我们可以通过执行java命令忽略,我这里是把它放在/usr/local/webDriver/下面
nohup java -jar -Dwebdriver.chrome.driver=/usr/local/webDriver/chromedriver test.jar > test.log &
3 Selenium API
3.1 WebElement API
WebDriver driver = null;
driver = new ChromeDriver();
driver.get("url");
WebElement element = driver.findElement(By...);
// 清空内容
element.clear();
// 输入abc
element.sendKeys("abc");
// 也可以组合多个按键使用
element.sendKeys(Keys.CONTROL,"a"); //全选
element.sendKeys(Keys.CONTROL,"c"); //复制
element.sendKeys(Keys.CONTROL,"v"); //粘贴
element.sendKeys(Keys.ENTER); //回车
// 点击
element.click();
// 用来判断界面元素是否是可用的,返回值为boolean值。可以考虑结合判断语句一起使用
element.isEnabled();
// 通过该方法来判断界面上的某个元素是否是选中状态,返回值为boolean值
element.isSelected():
// 通过该方法用来提交form表单,用click也可以
element.submit();
// 获取标签的文本内容
element.getText();
// 获取标签,如 div 、p 、 h1 、h2
element.getTagName();
// 获取css样式值,如下代表获取颜色
element.getCssValue("color");
// 获取某个标签内的属性,如下代表获取src的值
element.getAttribute("src");
// 获取元素的尺寸,也就是元素的长和宽
element.getSize();
// 获取元素在页面上的坐标位置
element.getLocation():
//切换tab页
//获取当前页面句柄
String handle = driver.getWindowHandle();
//获取所有句柄,循环判断是否等于当前句柄
for (String handles:driver.getWindowHandles()) {
if (handles.equals(handle))
continue;
driver.switchTo().window(handles);
}
// 指定名称,切换tab页
for (String s : dr.getWindowHandles()) {
dr.switchTo().window(s);
System.out.println(s);
if (dr.getTitle().equals("百度")) {
System.out.println("切换到百度窗口!");
break;
}
}
3.2 Select
// 选择到select标签
WebElement element = driver.findElement(By...);
Select select=new Select(element);
select.selectByIndex(0);//根据值的位置来选择下拉框,从0开始
select.selectByValue("18");//根据属性value值的位置来选择下拉框
select.selectByVisibleText("北京");//根据可见值来选择下拉框
3.3 Actions
// 1、鼠标左键点击:
Actions action = new Actions(driver);
// 等价于 driver.findElement(By.cssSelector("css")).click();
action.click(driver.findElement(By.cssSelector("css")));
// 2、鼠标左键双击:
action.doubleClick(driver.findElement(By.cssSelector("css")));
// 3、鼠标左键按下操作:
action.clickAndHold(driver.findElement(By.cssSelector("css")));
// 4、鼠标左键移动到元素操作:
action.moveToElement(driver.findElement(By.cssSelector("css")));
// 5、鼠标右键点击操作:
action.contextClick(driver.findElement(By.cssSelector("css")));
// 6、组合的鼠标操作(将目标元素拖拽到指定的元素上):
action.dragAndDrop(driver.findElement(By.cssSelector("css")), driver.findElement(By.cssSelector("css")));
// 7、组合的鼠标操作(将目标元素拖拽到指定的位置上):
action.dragAndDropBy(driver.findElement(By.cssSelector("css")), 0, 100); // 其中 0为xOffset 为横坐标,100为yOffset 为纵坐标。
// 8.拖拽选择操作,鼠标按住不放,进行拖拽选择,然后释放鼠标,需要三个动作
action.clickAndHold(driver.findElement(By.id("1"))).moveToElement(driver.findElement(By.id("3"))).perform();
action.release();
// 9.拖拽示例2
actions.clickAndHold(element).perform(); //开始按下
Thread.sleep(200);
for (int i = 0; i < track.size(); i++) {
actions.moveByOffset(track.get(i), moveY).perform(); //根据xy轴坐标拖动
Thread.sleep(new Random().nextInt(300) + randomTime);
}
Thread.sleep(200);
actions.release(element).perform();//释放
// 键盘的模拟操作,包括普通按键,比如enter、backspace、tab等,还包括四个修饰键(Modifier Keys),分别是Caps
// Lock,Control,Option,Command。
// 普通按键使用时,直接使用sendkeys(theKeys)就可以,如按下enter键:
action.sendKeys(Keys.ENTER).perform();
// 使用快捷键alt+f4关闭窗口(但是该方法不稳定,时行时不行,不行居多)
action.keyDown(Keys.ALT).keyDown(Keys.F4).keyUp(Keys.ALT).perform();
// 使用ctrl+a全选
action.sendKeys(Keys.CONTROL + "a").perform();
3.4 JS
JavascriptExecutor jse = (JavascriptExecutor) dr;
jse.executeScript("window.document.getElementById('tooltip').click()");
jse.executeScript("window.open('http://www.qq.com/')");
4 选择器
定位器 | 描述 | 示例 |
class name | 定位class属性与搜索值匹配的元素 | By.className(“test”) |
css selector | 定位CSS 选择器匹配的元素 | By.cssSelector(“div div.test”) |
id | 定位id属性与搜索值匹配的元素 | By.id(“test”) |
name | 定位name属性与搜索值匹配的元素 | By.name(“test”) |
link text | 定位link text元素 | By.linkText(“登录”) |
partial link text | 定位link text可视文本部分与搜索值部分匹配的锚点元素。如果匹配多个元素,则只选择第一个元素。 | By.partialLinkText(“登”) |
tag name | 定位标签名称与搜索值匹配的元素 | By.tagName(“div”) |
xpath | 定位与XPath表达式匹配的元素 | By.xpath(“//div[@id=‘test’]”) |
4.1 CSS 选择器
选择器 | 示例 | 示例描述 |
* | * | 选择所有元素。 |
.class | .test | 选择 class=“test” 的所有元素。 |
#id | #test | 选择 id=“test” 的所有元素。 |
element | div | 选择所有<div>元素。 |
element,element | div,p | 选择所有<div>和<p>元素。 |
element element | div p | 选择所有<div>下面的<p>元素。 |
element>element | div>p | 选择所有<div>下面的<p>元素。 |
element+element | div+p | 选择与<div>同级的<p>元素。 |
[target] | [title] | 选择所有有title属性的元素 |
[target=value] | [title=“hello”] | 选择所有title="hello"的元素 |
[target~=value] | [title~=“he”] | 选择所有title属性包含有he的元素 |
element1~element2 | p~ul | 选择前面有 <p> 元素的每个 <ul> 元素。 |
element1~element2 | p~ul | 选择前面有 <p> 元素的每个 <ul> 元素。 |
[attribute^=value] | a[src^=“https”] | 选择其 src 属性值以 “https” 开头的每个 <a> 元素。 |
[attribute$=value] | a[src$=“.pdf”] | 选择其 src 属性以 “.pdf” 结尾的所有 <a> 元素。 |
[attribute*=value] | a[src*=“abc”] | 选择其 src 属性中包含 “abc” 子串的每个 <a> 元素。 |
:first-of-type | p:first-of-type | 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。 |
:last-of-type | p:last-of-type | 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。 |
:only-of-type | p:only-of-type | 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。 |
: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) | 同上,但是从最后一个子元素开始计数。 |
:last-child | p:last-child | 选择属于其父元素最后一个子元素每个 <p> 元素。 |
:root | :root | 选择文档的根元素。 |
:empty | p:empty | 选择没有子元素的每个 <p> 元素(包括文本节点)。 |
:not(selector) | :not(p) | 选择非 <p> 元素的每个元素。 |
5 Linux版本
5.1 安装chrome
# 下载离线包
wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
# centos 安装
yum localinstall google-chrome-stable_current_x86_64.rpm
# 查看版本
google-chrome -version
5.2 下载WebDriver
通过自己版本下载对应的web驱动,其实也可以放在项目中;
# 赋予执行权限
chmod a+x chromedriver
5.3 设置驱动
方式一:驱动文件在linux某个文件下
System.setProperty("webdriver.edge.driver", "/usr/local/webDriver/chromedriver");
方式二:驱动文件在项目resources下
Resource resource = new ClassPathResource("/webdriver/chromedriver");
URL url1 = resource.getURL();
System.load(url1.getPath());