Java充电社
专辑
博文
联系我
本人继续续收门徒,亲手指导
UI自动化
-> UI自动化第3篇:元素操作专题
1、UI自动化第1篇:环境搭建与简单示例
2、UI自动化第2篇:元素定位专题
3、UI自动化第3篇:元素操作专题
上一篇:UI自动化第2篇:元素定位专题
<div style="display:none"></div> ## 目录 [TOC] ## 1. 前言 在熟悉了元素定位之后,我们接下来就要学习对定位到的元素进行操作这项内容了。我简要做了个总结,如下图: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/204/0687c039-6304-464d-8ebc-42dad16a054b.png) ## 2. 基本操作 元素的基本操作有很多,常用的有三个:click(点击)、clear(清空)、sendkeys(输入内容)、submit(提交)。何为基本操作,即这些方法在`WebElement`接口类中定义,通过实例化的`WebElement`直接调用。 1. `void click()`:单击目标元素。 2. `void submit()`:提交当前`form`(表单)内容到远程服务器,注意是特定于表单元素而言的。 3. `void sendKeys(CharSequence... keysToSend)`:使用此方法模拟键入元素,这可能会设置元素的值。一般是对文本输入元素进行此操作,否则会报错`org.openqa.selenium.ElementNotInteractableException: element not interactable` 4. `void clear()`:如果此元素是文本输入元素(`INPUT`型元素和`TEXTAREA`元素),则将清除该值。对其他元素没有影响。此方法并不会触发鼠标和键盘操作。 5. `String getTagName()`:获取并返回此元素的`tagName`(`String`类型)。 6. `String getAttribute(String name)`:获取并返回当前元素的给定属性的值(`String`类型)。 7. `boolean isSelected()`:确定是否选择了此元素。此操作仅适用于输入元素,如`checkboxes`(复选框)、`options in a select`(下拉选择框中的选项) 和 `radio buttons`(单选框按钮) 8. `boolean isEnabled()`:元素当前是否已启用?除了禁用的输入元素之外的内容,通常都会返回`true`。 9. `String getText()`:获取此元素及子元素的可见(即不被CSS隐藏)内文本,不带任何前导或尾随空格。 10. `boolean isDisplayed()`:是否显示此元素? 11. `Point getLocation()`:获取并返回此元素的左上角在页面上的位置(以一组`x,y`轴坐标值表示)。 12. `Dimension getSize()`:获取并返回此元素的高度和宽度(一对整型像素值,如332,450) 13. `Rectangle getRect()`:呈现元素的位置和大小。 14. `String getCssValue(String propertyName)`:获取并返回此元素给定`CSS`属性的值(`String`类型) ## 3. select操作 `select`,即下拉选择框,这类元素的操作一般是选中`select`中的某一项,`selenium`中的`Select`类提供了很多对`select`元素的操作方法。 首先,从`Select`类的有参构造函数可以看出,在初始化一个`select`时,需要`WebElement`作为入参。接下来,我们看看,`Select`类提供了哪些函数吧。 首先,我们最关心的当然是,下拉选择的相关方法,其中单选3个方法: 1. `void selectByVisibleText(String text)`:使用可见文本来选中某一项 2. `void selectByIndex(int index)`:使用索引来选中某一项 3. `void selectByValue(String value)`:使用`value`来选中某一项 相对应的,多选也有4个方法(当然多选需要`select`标签的`multiple`属性的值为`multiple`): 1. `void deselectAll()`:选中所有项 2. `void deSelectByVisibleText(String text)`:使用可见文本来选中某一项。 3. `void deSelectByIndex(int index)`:使用索引来选中某一项。 4. `void deSelectByValue(String value)`:使用`value`来选中某一项。 另外,还提供一些其他方法: 1. `boolean isMultiple()`:此`select`元素的`multiple`属性的值是否为`multiple`? 2. `List<WebElement> getOptions()`:返回此`select`元素所有的项。 3. `List<WebElement> getAllSelectedOptions()`:返回此`select`元素所有选中状态的项的集合。 4. `WebElement getFirstSelectedOption()`:返回此`select`元素第一个选中状态的项。 5. `setSelected(WebElement option, boolean select)`:使得此`select`元素的某项被点击(从而被选中),这个方法是下拉选择的相关方法的核心实现方法。 下面用一个实例演示一下`select`的操作。 **示例代码-select-1:** ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>UI自动化测试页面</title> </head> <body> <div id="div"> <select id="city" multiple="multiple"> <option value="">请选择一个城市</option> <option value="010" selected>北京</option> <option value="021">上海</option> <option value="0571">杭州</option> </select> </div> </body> </html> ``` **实现代码-select-1:** ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.Select; /** * @author muguozheng * @date 2020/4/18 17:56 * @Description: 元素定位测试 * @modify */ public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 访问测试页面-路径改成自己的 driver.get("file:///E:/project/automation/src/test/java/test.html"); // 获取select元素 WebElement element = driver.findElement(By.cssSelector("#city")); // 实例化一个select Select select = new Select(element); select.selectByVisibleText("上海"); // 增加延时以便观察 Thread.sleep(3000); select.selectByIndex(3); Thread.sleep(3000); select.selectByValue("010"); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` ## 4. 页面跳转 这里的页面跳转是广义上的,包括跳转到`window`(新页面)、`frame`、`alert`弹窗等。在selenium中,是借助`switchTo()`函数完成的。我们查看源码,发现`switchTo()`函数的返回值是`TargetLocator`,这是接口类`WebDriver`的一个内部接口,这个内部接口定义一系列跳转方法。 这些方法的返回值都是`WebDriver`,我们可以理解为driver的焦点发生了转移。因此,有一点需要留意,既然焦点转移到了新的页面上,那么想要定位原页面的元素,就要跳转回去。 ### 4.1. frame跳转 1. `WebDriver frame(int index)`:根据索引获取`frame` 2. `WebDriver frame(String nameOrId)`:根据name或id获取`frame` 3. `WebDriver frame(WebElement frameElement)`:根据`WebElement`(也就是可以用xpath、css等定位到`frame`元素作为参数)获取`frame` 4. `WebDriver parentFrame()`:转移焦点到父级内容,如果当前内容是顶级内容,将不发生变化。 下面进行实例演示。 **页面代码-frame-1:** ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>UI自动化测试页面</title> </head> <body> <div id="div"> <select id="city"> <option value="">请选择一个城市</option> <option value="010">北京</option> <option value="021">上海</option> <option value="0571">杭州</option> </select> </div> <iframe style="height:1000px;width:100%" id="myIframe" src="http://www.baidu.com"></iframe> </body> </html> ``` **实现代码-frame-1:** ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.Select; public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 访问测试页面 driver.get("file:///E:/project/automation/src/test/java/test.html"); // 跳转到frame // driver.switchTo().frame("myIframe") 通过nameOrId跳转 // frame(WebElement frameElement)方式跳转 driver.switchTo().frame(driver.findElement(By.xpath("//*[@id='myIframe']"))); // 在frame中进一步操作 driver.findElement(By.id("kw")).sendKeys("测试"); Thread.sleep(3000); // 跳转回父级页面 driver.switchTo().parentFrame(); Select select = new Select(driver.findElement(By.id("city"))); select.selectByValue("010"); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` ### 4.2. 窗口跳转 当我们点击了`a`标签元素时,会触发打开链接页面的事件,有两种情形: 1. 在当前窗口加载新页面内容 2. 新建一个窗口加载新页面内容,这种情况在`a`标签有`target="_blank"`时触发 当发生第2种情况时,同上文的`frame`类似,由于driver的焦点还停留在原窗口,我们在新窗口的页面上定位元素时,自然会产生错误,因此引出`driver`焦点跳转问题。 `selenium`提供了唯一的窗口跳转方法:`WebDriver window(String nameOrHandle)`,方法的入参`nameOrHandle`意为窗口名称(`name`)或句柄(`handle`),但查看源码和很多资料也没弄清楚窗口的`name`是什么,只好先研究一下`handle`了。 通过handle跳转窗口有3种思路: 1. 先记录当前窗口句柄记为句柄1(`String getWindowHandle()`),打开新页面后获取所有窗口句柄的集合,遍历此集合,与句柄1不同则跳转该句柄所指向的窗口。 2. 打开新的页面后获取当前所有窗口句柄(`Set<String> getWindowHandles()`),通过索引(越晚打开的窗口,其索引越大)来跳转到目标窗口。 3. 打开新的页面后获取当前所有窗口句柄,通过窗口标题(`title`)来跳转到目标窗口。 下面通过一个例子来进行演示,我们要实现的场景是: 1. 打开【UI自动化测试页面】,点击超链接,在新窗口打开【UI自动化-新页面】。 2. 在【UI自动化-新页面】的输入框输入"新页面"。 3. 返回【UI自动化测试页面】,在输入框输入【原页面】。 **页面代码-window-1:** ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>UI自动化测试页面</title> </head> <body> <div id="div"> <a id="new_page" target="_blank" href="file:///E:/project/58coin/automation/src/test/java/testNew.html">点击跳转新页面</a> </div> <div style="margin-top: 10px"> <input type="text" id="input"> </div> </body> </html> ``` **页面代码-window-2:** ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>UI自动化-新页面</title> </head> <body> <div> <input type="text" id="new_input"> </div> </body> </html> ``` **实现代码-window-1(句柄对比方式):** ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.Set; public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 访问测试页面 driver.get("file:///E:/project/automation/src/test/java/test.html"); // 获取当前窗口句柄 String handlePresent = driver.getWindowHandle(); // 点击超链接打开新页面 driver.findElement(By.id("new_page")).click(); // 遍历句柄集合,与handlePresent不同,则是新窗口,跳转并结束遍历 Set<String> handles = driver.getWindowHandles(); for (String handle : handles) { if (!handle.equals(handlePresent)) { driver.switchTo().window(handle); break; } } System.out.println("当前页面title:" + driver.getTitle()); driver.findElement(By.cssSelector("#new_input")).sendKeys("新页面"); Thread.sleep(1000); // 暂停1s以便观察 // 跳转到原来窗口 driver.switchTo().window(handlePresent); System.out.println("当前页面title:" + driver.getTitle()); driver.findElement(By.id("input")).sendKeys("原页面"); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` **实现代码-window-2(索引方式):** ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.ArrayList; import java.util.List; import java.util.Set; public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 访问测试页面 driver.get("file:///E:/project/automation/src/test/java/test.html"); // 点击超链接打开新页面 driver.findElement(By.id("new_page")).click(); Set<String> winSet = driver.getWindowHandles();//获取所有句柄 List<String> winList = new ArrayList<String>(winSet);//转成list列表 // 跳转到最新打开的窗口 driver.switchTo().window(winList.get(winList.size() - 1)); System.out.println("当前页面title:" + driver.getTitle()); driver.findElement(By.cssSelector("#new_input")).sendKeys("新页面"); Thread.sleep(1000); // 暂停1s以便观察 // 跳转到倒数第二个打开的窗口 driver.switchTo().window(winList.get(winList.size() - 2)); System.out.println("当前页面title:" + driver.getTitle()); driver.findElement(By.id("input")).sendKeys("原页面"); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` **实现代码-window-3(标题方式):** ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.Set; public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 访问测试页面 driver.get("file:///E:/project/automation/src/test/java/test.html"); // 点击超链接打开新页面 driver.findElement(By.id("new_page")).click(); // 获取窗口句柄的集合(set) Set<String> handles = driver.getWindowHandles(); // 遍历并通过title判断目标窗口 for (String handle : handles) { if (driver.switchTo().window(handle).getTitle().contains("UI自动化-新页面")) { driver.switchTo().window(handle); break; } } System.out.println("当前页面title:" + driver.getTitle()); driver.findElement(By.cssSelector("#new_input")).sendKeys("新页面"); Thread.sleep(1000); // 暂停1s以便观察 // 遍历并通过title判断目标窗口 for (String handle : handles) { if (driver.switchTo().window(handle).getTitle().contains("UI自动化测试页面")) { driver.switchTo().window(handle); break; } } System.out.println("当前页面title:" + driver.getTitle()); driver.findElement(By.id("input")).sendKeys("原页面"); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` ### 3.3. alert跳转 alert弹窗本质是js原生代码,不是标签元素,并且一个页面中最多有且仅有一个alert弹窗,如果页面中出现了alert弹窗,一定要先处理它,不然无法进行其他操作。alert弹窗切换的操作非常简单。 Alert接口中提供了以下几个方法: 1. `void dismiss()`:点击弹窗的取消按钮 2. `void accept()`:点击弹窗的确认按钮 3. `String getText()`:获取弹窗的文本内容 4. `void sendKeys(String keysToSend)`:向弹窗中输入内容 下面演示一个示例: **页面代码-alert-1:** ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>UI自动化测试页面</title> <script type="text/javascript"> function display_alert() { alert("I am an alert box!!") } </script> </head> <body> <div> <input type="button" id="alert" onclick="display_alert()" value="Display alert box"/> <input type="text" id="input"> </div> </body> </html> ``` **实现代码-alert-1:** ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 访问测试页面 driver.get("file:///E:/project/automation/src/test/java/test.html"); // 点击弹窗按钮 driver.findElement(By.id("alert")).click(); // 弹窗确定:没有这一步处理,后续操作将报错 driver.switchTo().alert().accept(); // 输入框输入内容 driver.findElement(By.id("input")).sendKeys("测试"); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` ## 5. 鼠标操作 在selenium中,所有的鼠标操作的实现全部由`Actions`类提供。首先,Actions类提供了多个有参构造方法: ```java public Actions(WebDriver driver) public Actions(Keyboard keyboard, Mouse mouse) public Actions(Keyboard keyboard) ``` 但后两个构造方法只是扩展方法,很少用。第一个构造方法才是最重要的,它的入参是当前的`WebDriver`。 再让我们看一下这个类提供了哪些操作鼠标的方法: 1. `Actions clickAndHold(WebElement target)`:在特定元素上单击鼠标左键(不释放) 2. `Actions release(WebElement target)`:在特定元素上释放鼠标左键 3. `Actions doubleClick(WebElement target)`:在特定元素上双击鼠标左键 4. `Actions moveToElement(WebElement target)`:移动鼠标指针到特定元素 5. `Actions contextClick(WebElement target)`:在特定元素上右键单击 6. `Actions dragAndDrop(WebElement source, WebElement target)`:拖拽元素 7. **`void perform()`**:执行具体的操作。前面6个方法都是声明一个操作,只有调用`perform()`后才会真正执行操作。 下面以拖拽元素做一下鼠标操作的演示: ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.interactions.Actions; public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 访问测试页面 driver.get("https://www.runoob.com/try/try-cdnjs.php?filename=jqueryui-api-droppable"); // 跳转到右侧iframe driver.switchTo().frame("iframeResult"); WebElement source = driver.findElement(By.id("draggable")); WebElement target = driver.findElement(By.id("droppable")); Actions actions = new Actions(driver); actions.dragAndDropBy(source, 110, 120).perform(); Thread.sleep(2000); // 延时以观察效果 actions.dragAndDrop(source, target).perform(); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` ## 6. 键盘操作 对于键盘的模拟操作,`Actions` 类中有提供 `keyUp(CharSequence key)`、`keyDown(CharSequence key)`、`sendKeys(CharSequence key)` 等方法来实现。 另外在Keys类中,提供了很多模拟按键,如`BACK_SPACE`、`ENTER`等。 对于普通键盘,使用 `sendKeys(CharSequence key)` 就可以实现: ```java Actions action = new Actions(driver); action.sendKeys(Keys.BACK_SPACE);// 模拟按下并释放 BACK_SPACE键 action.sendKeys(Keys.ENTER);// 模拟按下并释放回车键 123 ``` 而对于修饰键,在 WebDriver 中需要用到 KeyDown(theKey)、keyUp(theKey) 方法来操作。 ```java Actions action = new Actions(driver); action.keyDown(Keys.CONTROL);// 按下 Ctrl 键 action.keyDown(Keys.SHIFT);// 按下 Shift 键 action.keyDown(Key.ALT);// 按下 Alt 键 action.keyUp(Keys.CONTROL);// 释放 Ctrl 键 action.keyUp(Keys.SHIFT);// 释放 Shift 键 action.keyUp(Keys.ALT);// 释放 Alt 键 1234567 ``` > 修饰键是键盘上的一个或者一组特别的键,包括Shift、Ctrl、Alt(Option)、AltGr、Windows logo、Command、FN(Function)等,与一般按键同时使用的时候,用来临时改变一般键盘的普通行为。 我们发现, `Actions` 类和`WebElement` 类都有一个`sendKeys(CharSequence key)`方法,这两个方法对于一般的输入操作基本上相同,不同点在于以下几点: 1. `Actions` 中的`sendKeys(CharSequence key)`对于修饰键 (Modifier Keys) 的调用并不会释放,也就是说当调用 `actions.sendKeys(Keys.ALT)`、`actions.sendKeys(Keys.CONTROL)`、 `action.sendKeys(Keys.SHIFT)`的时候,相当于调用 actions.keyDown(keysToSend),而如果在现实的应用中想要模拟按下并且释放这些修饰键,应该再调用 `action.sendKeys(keys.NULL)` 来完成这个动作。 2. 当 `Actions` 的 `sendKeys(keysToSend)` 执行完之后,焦点就不在当前元素了。所以我们可以使用 sendKeys(Keys.TAB) 来切换元素的焦点,从而达到选择元素的作用,这个最常用到的场景就是在用户名和密码的输入过程中。 下面以一个百度搜索测试的例子来演示键盘操作: ```java import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.interactions.Actions; public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 访问测试页面 driver.get("http://www.baidu.com"); WebElement input = driver.findElement(By.id("kw")); input.sendKeys("测试试"); // 按下退格键删除最后一个字 input.sendKeys(Keys.BACK_SPACE); Thread.sleep(1000); Actions actions = new Actions(driver); // 按下回车键 actions.sendKeys(Keys.ENTER).perform(); Thread.sleep(15000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` ## 7. 元素等待 在UI自动化执行过程中,如果页面或元素没有加载完成,就进行下一步操作,无疑是会抛出异常的,因此`selenium`提供了多种元素等待的方法。 ### 6.1 隐式等待 隐式等待是一种全局设置,在driver的整个生命周期都有效,设置方式如下: ```java driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); ``` 按源码解释,驱动程序会轮询页面,直到找到该元素(找到后立即执行下一步)或超时(抛出`org.openqa.selenium.NoSuchElementException`)。这种设置应该谨慎,充分考虑`Xpath`等方式定位元素较慢的可能性。 ### 6.2 显式等待 显示等待相对于隐式等待更加灵活,能针对各个元素进行单独的设置。只有满足显式等待的条件满足,测试代码才会继续向后执行后续的测试逻辑,如果超过设定的最大显式等待时间阈值, 这测试程序会抛出异常。 等待方法由`ExpectedConditions`类提供,常用的有以下几个(E代表ExpectedCondition): 1. `E<Boolean> titleIs(final String title)`:判断标题是否是给定标题。 2. `E<Boolean> titleContains(final String title)`:判断标题是否包含给定标题。 3. `E<WebElement> presenceOfElementLocated(final By locator)`:判断页面元素在页面中存在。 4. `E<Boolean> textToBePresentInElement(final WebElement element, final String text)`:给定元素中是否包含特定的文本。 5. `E<WebElement> elementToBeClickable(final By locator)`:判断给定元素是否可点击。 6. `E<Boolean> elementToBeSelected(WebElement element)`:判断给定元素是否处于选中状态。 还有非常多的其他判断方法,可以根据场景灵活选用。下面以百度搜索为例,演示显示等待的使用: ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; public class ElementTest { public static void main(String[] args) { // 指定浏览器驱动的路径 String driverPath = "E:/source/driver/chromedriver_80_2.exe"; System.setProperty("webdriver.chrome.driver", driverPath); // 创建一个chrome driver WebDriver driver = new ChromeDriver(); // 页面最大化 driver.manage().window().maximize(); try { // 设定显示等待时间为3s WebDriverWait wait = new WebDriverWait(driver, 3); // 访问测试页面 driver.get("http://www.baidu.com"); // 设置By.id("abc")这个元素加载完成才进行下一步,最多等待3s,否则抛出异常 wait.until(ExpectedConditions.presenceOfElementLocated(By.id("abc"))); driver.findElement(By.id("kw")).sendKeys("测试"); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } } ``` > 来源:`https://blog.csdn.net/mu_wind/article/details/105683312` <a style="display:none" target="_blank" href="https://mp.weixin.qq.com/s/_S1DD2JADnXvpexxaBwLLg" style="color:red; font-size:20px; font-weight:bold">继续收门徒,亲手带,月薪 4W 以下的可以来找我</a> ## 最新资料 1. <a href="https://mp.weixin.qq.com/s?__biz=MzkzOTI3Nzc0Mg==&mid=2247484964&idx=2&sn=c81bce2f26015ee0f9632ddc6c67df03&scene=21#wechat_redirect" target="_blank">尚硅谷 Java 学科全套教程(总 207.77GB)</a> 2. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484192&idx=1&sn=505f2faaa4cc911f553850667749bcbb&scene=21#wechat_redirect" target="_blank">2021 最新版 Java 微服务学习线路图 + 视频</a> 3. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484573&idx=1&sn=7f3d83892186c16c57bc0b99f03f1ffd&scene=21#wechat_redirect" target="_blank">阿里技术大佬整理的《Spring 学习笔记.pdf》</a> 4. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484544&idx=2&sn=c1dfe907cfaa5b9ae8e66fc247ccbe84&scene=21#wechat_redirect" target="_blank">阿里大佬的《MySQL 学习笔记高清.pdf》</a> 5. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485167&idx=1&sn=48d75c8e93e748235a3547f34921dfb7&scene=21#wechat_redirect" target="_blank">2021 版 java 高并发常见面试题汇总.pdf</a> 6. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485664&idx=1&sn=435f9f515a8f881642820d7790ad20ce&scene=21#wechat_redirect" target="_blank">Idea 快捷键大全.pdf</a> ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/1/2883e86e-3eff-404a-8943-0066e5e2b454.png)
#custom-toc-container