Skip to content

selenium_advanced_interactions

虽然像 click() 和 sendKeys() 这样的基本命令涵盖了许多场景,但现代 Web 应用程序通常需要更复杂的用户交互,例如鼠标悬停、拖放(drag-and-drop)、双击或键盘快捷键。Selenium WebDriver 提供了 Actions 类来处理这些高级交互。

Actions 类的工作原理是构建一系列操作,然后按顺序执行这些操作。你必须始终在序列的末尾调用 perform() 来执行这些操作。

首先,你需要导入该类并创建一个实例,将 WebDriver 对象传递进去。

// 导入 Actions 类
// import org.openqa.selenium.interactions.Actions;
// 假设 'driver' 是你的 WebDriver 实例
Actions actions = new Actions(driver);

用于模拟将鼠标光标移动到元素上方,这可能会触发菜单或工具提示出现。

// 定位主菜单项
WebElement mainMenu = driver.findElement(By.id("main-menu-item"));
// 定位悬停时出现的子菜单项
// (它最初可能不可见,确保一旦可见,定位器能找到它)
WebElement subMenu = driver.findElement(By.id("submenu-item"));
// 构建序列:移动到主菜单,然后移动到子菜单,然后点击
actions.moveToElement(mainMenu).moveToElement(subMenu).click().perform();
// 备选方案:移动到主菜单,等待子菜单出现,然后点击子菜单
// actions.moveToElement(mainMenu).perform();
// WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
// WebElement visibleSubMenu = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("submenu-item")));
// actions.moveToElement(visibleSubMenu).click().perform(); // Or just visibleSubMenu.click();

模拟点击并按住一个元素(源),然后将其移动到另一个位置(目标),最后释放鼠标按钮。

// 定位要拖动的元素
WebElement sourceElement = driver.findElement(By.id("draggable"));
// 定位要放置的目标区域
WebElement targetElement = driver.findElement(By.id("droppable"));
// 选项 1:使用专用的 dragAndDrop 方法
actions.dragAndDrop(sourceElement, targetElement).perform();
// 选项 2:手动构建序列
// actions.clickAndHold(sourceElement).moveToElement(targetElement).release().perform();

模拟对元素进行鼠标右键点击,这通常会打开一个上下文菜单(context menu)。

// 定位要右键点击的元素
WebElement element = driver.findElement(By.id("context-menu-trigger"));
// 执行右键点击
actions.contextClick(element).perform();
// 然后你需要定位上下文菜单中的元素并与之交互

模拟双击一个元素。

// 定位要双击的元素
WebElement element = driver.findElement(By.id("double-click-item"));
// 执行双击
actions.doubleClick(element).perform();

Actions 类还可以发送按键,包括 Shift、Ctrl、Alt 等修饰键。使用 Keys 枚举(org.openqa.selenium.Keys)。

// 定位输入字段
WebElement inputField = driver.findElement(By.id("my-input"));
// 使用 Shift 键输入大写文本
actions.moveToElement(inputField)
.click()
.keyDown(Keys.SHIFT) // 按下 Shift
.sendKeys("hello") // 发送按键(将是大写)
.keyUp(Keys.SHIFT) // 释放 Shift
.sendKeys(" world") // 发送更多按键(正常情况)
.perform();
// 示例:发送 Ctrl+A(全选)
// actions.keyDown(Keys.CONTROL).sendKeys("a").keyUp(Keys.CONTROL).perform();
// 示例:发送 Enter 键
// actions.sendKeys(Keys.ENTER).perform();

如示例所示,你可以在调用 perform() 之前将多个操作链接在一起。这会创建一个单独的复合操作(composite action),由 WebDriver 执行。

WebElement element1 = driver.findElement(By.id("one"));
WebElement element2 = driver.findElement(By.id("two"));
// 示例链:移动到 element1,点击并按住,移动到 element2,释放
actions.moveToElement(element1)
.clickAndHold()
.moveToElement(element2)
.release()
.perform();
  • 始终调用 perform(): 操作只有在调用 perform() 后才会排队并执行。
  • 元素可见性: 在尝试对其进行操作之前,确保元素是可见且可交互的。如有必要,请使用显式等待(Explicit Waits)。
  • 浏览器焦点: 键盘操作通常需要浏览器窗口或特定元素获得焦点。使用 click() 或 moveToElement().click() 来确保焦点。
  • 复杂性: 尽管功能强大,但复杂的 Actions 序列有时可能不如简单的交互稳定。在标准命令不足时使用它们。

Actions 类显著扩展了 WebDriver 的功能,允许你自动化现代 Web 应用程序中几乎所有的用户交互。