Selenium是一个自动化测试工具,用于在Web应用程序中模拟用户操作。它提供了一组API,可以通过编程方式控制浏览器,并模拟用户的交互行为,例如点击、输入文本和导航等。Selenium支持多种编程语言,包括Java、C#、Python、Ruby、JavaScript等,并可以在多个浏览器和操作系统上运行测试。Selenium的目标是帮助测试人员自动化测试过程,提高测试效率和测试质量。
浏览器版本和浏览器驱动版本要保持一致(一般前三位一致即可),浏览器和对应的驱动见附件
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
此种方法不是最佳实践,最佳实践是连接已经打开的浏览器,退出时仅仅退出浏览器驱动,不退出已经打开的浏览器,见最佳实践部分
public class HelloSelenium {
@SneakyThrows
public static void main(String[] args) {
// 设置 ChromeDriver 的路径
System.setProperty("webdriver.chrome.driver", "C:\\118.0.5993.70\\chromedriver-win64\\chromedriver.exe");
// 配置 ChromeOptions
ChromeOptions options = new ChromeOptions();
// 指定特定版本的 Chrome 浏览器路径 浏览器版本和浏览器驱动版本要保持一致(一般前三位一致即可)
options.setBinary("C:\\118.0.5993.70\\chrome-win64\\chrome.exe");
// 可选:无头模式,不打开浏览器窗口 如果做爬虫不打开浏览器某些网站过不去,可能会遇到Enable JavaScript and cookies to continue
// options.addArguments("--headless");
// 解决一些系统的图形化渲染问题
options.addArguments("--disable-gpu");
// 在某些系统上需要添加此参数
options.addArguments("--no-sandbox");
// 解决资源共享内存的问题
options.addArguments("--disable-dev-shm-usage");
// 创建 ChromeDriver 实例
WebDriver driver = new ChromeDriver(options);
// 为浏览器驱动driver创建一个等待器,循环等待,直到条件达成或者超时,如果条件未达成超时就会跑出异常
WebDriverWait wait = new WebDriverWait(driver, 10);
try {
// 访问指定的 URL
driver.get("http://localhost:8080");
// 直接使用driver.findElement可能元素还没有加载出来读取不到,wait.until会一直检测,直到找到元素或者超时
// WebElement nameInput = driver.findElement(By.xpath("/html/body/div[1]/form/div[1]/div/div/input"));
WebElement nameInput = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("/html/body/div[1]/form/div[1]/div/div/input")));
nameInput.sendKeys("张无忌");
List<WebElement> buttons = driver.findElements(By.tagName("button"));
WebElement queryButton = buttons.stream().filter(item -> "查询".equals(item.getText())).findFirst().get();
queryButton.click();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 方便观察浏览器,避免马上退出
Thread.sleep(10 * 1000);
// 退出浏览器驱动程序,关闭所有关联的窗口。(如果不退出浏览器驱动器不会结束,多次运行会启动多个浏览器驱动,占用系统资源)
driver.quit();
}
}
options全部参数可参考https://peter.sh/experiments/chromium-command-line-switches/
// 请求一个页面,不支持前进和后退切换
driver.get(url);
// 和get类似,支持前进和后退切换
driver.navigate().to(url);
// 退到上一个页面 ,前提必须前进了一个页面才能回退
driver.navigate().back();
// 指前进到下一个页面 ,前提是必须后退后才能前进
driver.navigate().forward();
// 刷新当前页面
driver.navigate().refresh();
// 通用搜索,第一个 , By里包含常用的各种搜索
WebElement findElement(By by);
// 通用搜索,多个,By里包含常用的各种搜索
List<WebElement> findElements(By by);
// 关闭当前窗口,如果它是当前打开的最后一个窗口,则退出浏览器。
driver.close();
// 退出此驱动程序,关闭每个相关窗口。
driver.quit();
WebElement常用方法
public static By id(String id) {
return new ById(id);
}
public static By linkText(String linkText) {
return new ByLinkText(linkText);
}
public static By partialLinkText(String partialLinkText) {
return new ByPartialLinkText(partialLinkText);
}
public static By name(String name) {
return new ByName(name);
}
public static By tagName(String tagName) {
return new ByTagName(tagName);
}
路径可直接在浏览器中拷贝
public static By xpath(String xpathExpression) {
return new ByXPath(xpathExpression);
}
public static By className(String className) {
return new ByClassName(className);
}
public static By cssSelector(String cssSelector) {
return new ByCssSelector(cssSelector);
}
Point
对象表示,包含x
和y
坐标。Dimension
对象表示,包含width
和height
。WebDriverWait
和 ExpectedConditions
来等待特定条件(如元素可点击、元素存在等)。// 配置 ChromeOptions
ChromeOptions options = new ChromeOptions();
// 指定特定版本的 Chrome 浏览器路径 浏览器版本和浏览器驱动版本要保持一致(一般前三位一致即可)
options.setBinary("C:\\118.0.5993.70\\chrome-win64\\chrome.exe");
WebDriver driver = new ChromeDriver(options);
// 创建一个显示等待器,超时时间10S
WebDriverWait wait = new WebDriverWait(driver, 10)
// 循环寻找一个h3元素,10s内找到返回该元素,10s找不到抛出异常
WebElement h3 = wait.until(ExpectedConditions.presenceOfElementLocated(By.tagName("h3")));
隐式等待在Java中通过WebDriver
的manage().timeouts().implicitlyWait
方法实现。以下是一个示例代码:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class ImplicitWaitExample {
public static void main(String[] args) {
// 设置ChromeDriver的路径
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
// 初始化WebDriver
WebDriver driver = new ChromeDriver();
// 设置隐式等待时间为10秒
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// 打开一个网页
driver.get("http://example.com");
try {
// 查找元素 如果10s内找到则返回元素,如果10秒没有找到则抛出异常
WebElement element = driver.findElement(By.id("myElement"));
// 操作元素
element.click();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭浏览器
driver.quit();
}
}
}
在这个示例中,implicitlyWait
方法设置了一个最长等待时间为10秒,在查找元素时,如果元素未立即出现,WebDriver会等待这个时间内不断尝试查找元素。
2 隐式等待是指在代码中设置一个全局等待时间,在此时间内如果元素没有立即出现,程序将等待指定的时间,等待元素出现。隐式等待适用于整个测试用例,而不是针对某个特定的元素。隐式等待可以通过WebDriver.Timeouts.implicitlyWait()方法来设置。。
连接到已经打开的浏览器,需要浏览器开启debug端口,简单的开启方法
--remote-debugging-port=9222
(注意chrome.exe与新加内容之间有个空格,端口可以自由定义)
[ {
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/B3C592C54EB3552A0F5D76706A6EF844",
"id": "B3C592C54EB3552A0F5D76706A6EF844",
"title": "emp",
"type": "page",
"url": "http://localhost:8080/",
"webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/B3C592C54EB3552A0F5D76706A6EF844"
} ]
public void openChrome() {
// 设置 ChromeDriver 的路径
System.setProperty("webdriver.chrome.driver", "C:\\118.0.5993.70\\chromedriver-win64\\chromedriver.exe");
// 配置 ChromeOptions
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("debuggerAddress", "localhost:9222");
// 创建 ChromeDriver 实例
driver = new ChromeDriver(options);
}
public void closeChrome() {
// 退出浏览器驱动程序
driver.quit();
}
不要让ChromeDriver打开浏览器,让ChromeDriver链接到已经打开的浏览器,好处如下
复制出来的xpath直接粘贴到代码里即可
/html/body/div[2]/div[1]/div/div[1]/div/div/div[1]/div/form/div[2]/div/div[1]/div[1]/textarea
如果前端页面频繁更新,页面元素位置经常变动,就不太适合这种方式了
List<WebElement> textareaList = driver.findElements(By.tagName("textarea"));
for (WebElement textarea : textareaList) {
String placeholder = textarea.getAttribute("placeholder");
if (placeholder.contains("内容概要+适用人群+使用场景及目标+其他说明")) {
// 拿到了资源描述文本框
}
}
基于selenium的crud