ActionChains 鼠标高级操作 — 左击 / 右击 / 双击 / 移动 / 按住 / 释放 / 拖拽 / 滚动,8 道实战练习
element.click() 或 ActionChains(driver).click(el).perform()# 快速参考 from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains btn = driver.find_element(By.ID, "p1_btn") btn.click() # 方式 A(推荐) ActionChains(driver).click(btn).perform() # 方式 B
p1_btn 按钮 → 单击 → 断言 p1_result 包含「单击事件触发」
操作步骤:
① 用 driver.find_element(By.ID, "p1_btn") 定位「单击我」按钮;
② 调用 btn.click() 或 ActionChains(driver).click(btn).perform() 执行单击;
③ 用 driver.find_element(By.ID, "p1_result").text 断言结果包含「单击事件触发」。
💡 提示:在 Selenium 中通过 btn.click() 触发单击,或用 ActionChains(driver).click(btn).perform(),然后用 btn.is_enabled() 检查按钮可点击状态。
# 练习 1 参考答案 · 左击 from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains driver.get("https://autotest-505.pages.dev/mouse_op_practice.html") btn = driver.find_element(By.ID, "p1_btn") actions = ActionChains(driver) # 方式 A:ActionChains.click() actions.click(btn).perform() # 方式 B:WebElement.click()(更常用) btn.click() result = driver.find_element(By.ID, "p1_result").text assert "单击事件触发" in result
ActionChains(driver).context_click(el).perform()# 快速参考 from selenium.webdriver.common.action_chains import ActionChains btn = driver.find_element(By.ID, "p2_btn") ActionChains(driver).context_click(btn).perform()
操作步骤:
① 用 driver.find_element(By.ID, "p2_btn") 定位「在此处右击」按钮;
② 调用 ActionChains(driver).context_click(btn).perform() 执行右击;
③ 断言 p2_menu 菜单元素可见,或 p2_result 包含「右键菜单已弹出」。
💡 提示:Selenium 中通过 ActionChains(driver).context_click(btn).perform() 触发右击,contextmenu 事件会被 JS 拦截并弹出自定义菜单。
# 练习 2 参考答案 · 右击 from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains driver.get("https://autotest-505.pages.dev/mouse_op_practice.html") btn = driver.find_element(By.ID, "p2_btn") actions = ActionChains(driver) # 在元素上右击 actions.context_click(btn).perform() # 断言菜单可见 menu = driver.find_element(By.ID, "p2_menu") assert menu.is_displayed()
ActionChains(driver).double_click(el).perform()# 快速参考 from selenium.webdriver.common.action_chains import ActionChains import time bulb = driver.find_element(By.ID, "p3_bulb") ActionChains(driver).double_click(bulb).perform() time.sleep(0.3)
操作步骤:
① 用 driver.find_element(By.ID, "p3_bulb") 定位灯泡图标;
② 调用 ActionChains(driver).double_click(bulb).perform() 执行双击;
③ 等待 0.3 秒,断言 p3_result 包含「已点亮」或「已熄灭」。
💡 提示:浏览器原生 dblclick 事件等于两次间隔 300-500ms 的 click,Selenium 用 ActionChains(driver).double_click(el).perform() 一次完成。
# 练习 3 参考答案 · 双击 from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains import time driver.get("https://autotest-505.pages.dev/mouse_op_practice.html") bulb = driver.find_element(By.ID, "p3_bulb") actions = ActionChains(driver) # 双击切换状态 actions.double_click(bulb).perform() time.sleep(0.3) result = driver.find_element(By.ID, "p3_result").text assert "已点亮" in result
ActionChains(driver).move_to_element(el).perform()# 快速参考 from selenium.webdriver.common.action_chains import ActionChains trigger = driver.find_element(By.ID, "p4_trigger") ActionChains(driver).move_to_element(trigger).perform() submenu = driver.find_element(By.ID, "p4_submenu") assert submenu.is_displayed()
操作步骤:
① 用 driver.find_element(By.ID, "p4_trigger") 定位「悬停我」按钮;
② 调用 ActionChains(driver).move_to_element(trigger).perform() 悬停;
③ 断言 p4_submenu 子菜单元素可见。
💡 提示:move_to_element() 对应 DOM 的 mouseenter,常用于触发 CSS :hover 菜单或 tooltip,离开后 mouseleave 会关闭子菜单。
# 练习 4 参考答案 · 移动 from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains driver.get("https://autotest-505.pages.dev/mouse_op_practice.html") trigger = driver.find_element(By.ID, "p4_trigger") actions = ActionChains(driver) # 把鼠标移到元素上(悬停) actions.move_to_element(trigger).perform() # 断言子菜单可见 submenu = driver.find_element(By.ID, "p4_submenu") assert submenu.is_displayed()
ActionChains(driver).click_and_hold(el).perform()# 快速参考 from selenium.webdriver.common.action_chains import ActionChains import time btn = driver.find_element(By.ID, "p5_btn") # 按住不放(不 release) ActionChains(driver).click_and_hold(btn).perform() time.sleep(1) # 观察加载效果
操作步骤:
① 用 driver.find_element(By.ID, "p5_btn") 定位「按住不放」按钮;
② 调用 ActionChains(driver).click_and_hold(btn).perform() 按住;
③ 等待 1 秒,断言按钮文字包含「加载中」或 p5_result 包含「按住」。
💡 提示:click_and_hold() 按住后不会自动释放,必须显式调用 release(),常用于拖拽的第一阶段。
# 练习 5 参考答案 · 按住 from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains import time driver.get("https://autotest-505.pages.dev/mouse_op_practice.html") btn = driver.find_element(By.ID, "p5_btn") actions = ActionChains(driver) # 按住不放(不释放) actions.click_and_hold(btn).perform() time.sleep(1) # 保持按住 1 秒观察状态 assert "加载中" in btn.text
ActionChains(driver).release().perform() 或分步组合# 快速参考 from selenium.webdriver.common.action_chains import ActionChains src = driver.find_element(By.ID, "p6_source") tgt = driver.find_element(By.ID, "p6_target") ActionChains(driver) \ .click_and_hold(src) \ .move_to_element(tgt) \ .release() \ .perform()
操作步骤:
① 定位 p6_source(源)和 p6_target(目标)两个区域;
② 用 click_and_hold(source).move_to_element(target).release().perform() 组合执行;
③ 断言 p6_target 显示「已接收」或 p6_result 包含「释放完成」。
💡 提示:前端拖动 = mousedown→mousemove→mouseup,对应 Selenium 的 click_and_hold().move_to_element().release()。
# 练习 6 参考答案 · 释放(分步组合) from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains driver.get("https://autotest-505.pages.dev/mouse_op_practice.html") source = driver.find_element(By.ID, "p6_source") target = driver.find_element(By.ID, "p6_target") actions = ActionChains(driver) # 分步:按住 → 移动 → 释放 actions.click_and_hold(source) \ .move_to_element(target) \ .release() \ .perform() assert "已接收" in target.text
ActionChains(driver).drag_and_drop(source, target).perform()# 快速参考 from selenium.webdriver.common.action_chains import ActionChains card = driver.find_element(By.ID, "p7_card1") tgt = driver.find_element(By.ID, "p7_target") ActionChains(driver).drag_and_drop(card, tgt).perform()
操作步骤:
① 定位卡片 p7_card1/2/3 和目标区 p7_target;
② 循环调用 ActionChains(driver).drag_and_drop(card, target).perform();
③ 断言 p7_result 包含「全部 3 张」或目标区显示所有卡片。
💡 提示:前端卡片拖动需要自己实现 mousedown→mousemove→mouseup;Selenium 用 drag_and_drop(source, target) 一行搞定。
# 练习 7 参考答案 · 拖拽 from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains import time driver.get("https://autotest-505.pages.dev/mouse_op_practice.html") target = driver.find_element(By.ID, "p7_target") actions = ActionChains(driver) card_ids = ["p7_card1", "p7_card2", "p7_card3"] for cid in card_ids: card = driver.find_element(By.ID, cid) actions.drag_and_drop(card, target).perform() time.sleep(0.3) # 断言 assert "3" in driver.find_element(By.ID, "p7_result").text
ActionChains(driver).scroll_to_element(el).perform() 或 JS 注入driver.execute_script("el.scrollIntoView()") 作为 fallback 方案element.is_displayed() 确认元素可见# 快速参考 from selenium.webdriver.common.action_chains import ActionChains target = driver.find_element(By.ID, "p8_target") # 方式 A:Selenium 4.2+ 原生 ActionChains(driver).scroll_to_element(target).perform() # 方式 B:兼容所有版本 driver.execute_script("arguments[0].scrollIntoView()", target)
p8_target 元素可见,断言结果区更新
操作步骤:
① 定位长列表内的目标元素 p8_target;
② 调用 ActionChains(driver).scroll_to_element(target).perform() 滚动,或用 execute_script("el.scrollIntoView()");
③ 断言 p8_result 包含「滚到目标」或 target.is_displayed() 为 True。
💡 提示:scroll_to_element(target) 让目标元素滚动到视口“底部可见”位置;scroll_by_amount(dx, dy) 则按指定偏移滚动。
# 练习 8 参考答案 · 滚动 from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains import time driver.get("https://autotest-505.pages.dev/mouse_op_practice.html") target = driver.find_element(By.ID, "p8_target") actions = ActionChains(driver) # 方式 A:Selenium 4.2+ 原生 API actions.scroll_to_element(target).perform() # 方式 B:JS 注入(所有版本通用) driver.execute_script("arguments[0].scrollIntoView()", target) assert "滚到目标" in driver.find_element(By.ID, "p8_result").text