Selenium4Web自动化4-鼠标键盘模拟操作
一、 Web 元素交互
参考官方文档:https://www.selenium.dev/zh-cn/documentation/webdriver/elements/interactions/
用于操纵表单的高级指令集.
仅有五种基本命令可用于元素的操作:
- 点击 (适用于任何元素)
- 发送键位 (仅适用于文本字段和内容可编辑元素)
- 清除 (仅适用于文本字段和内容可编辑元素)
- 提交 (仅适用于表单元素)
- 选择 (参见 选择列表元素)
这些方法的设计目的是尽量模拟用户体验, 所以, 与 Actions接口 不同, 在指定制定操作之前, 会尝试执行两件事.
1.如果它确定元素在视窗之外, 则会将元素滚动到视图中, 特别是将元素底部与视窗底部对齐.
2.确保元素在执行操作之前是可交互的 . 这可能意味着滚动不成功, 或者该元素没有以其他方式显示.确定某个元素是否显示在页面上太难了 无法直接在webdriver规范中定义, 因此Selenium发送一个带有JavaScript原子的执行命令, 检查是否有可能阻止该元素显示. 如果确定某个元素不在视窗中, 不显示, 不可 键盘交互, 或不可 指针交互, 则返回一个元素不可交互 错误.
点击
元素点击命令 执行在 元素中央. 如果元素中央由于某些原因被 遮挡 , Selenium将返回一个 元素点击中断 错误.
driver.find_element(By.NAME, "q").click()
发送键位
元素发送键位命令 将录入提供的键位到 可编辑的 元素. 通常, 这意味着元素是具有 文本 类型的表单的输入元素或具有 内容可编辑 属性的元素. 如果不可编辑, 则返回 无效元素状态 错误.
WebDriver支持的按键列表:
https://www.w3.org/TR/webdriver/#keyboard-actions
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Enter "webdriver" text and perform "ENTER" keyboard action
driver.find_element(By.NAME, "q").send_keys("webdriver" + Keys.ENTER)
清除
元素清除命令 重置元素的内容. 这要求元素 可编辑, 且 可重置. 通常, 这意味着元素是具有 文本 类型的表单的输入元素或具有 内容可编辑 属性的元素. 如果不满足这些条件, 将返回 无效元素状态 错误.
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Store 'SearchInput' element
SearchInput = driver.find_element(By.NAME, "q")
SearchInput.send_keys("selenium")
# Clears the entered text
SearchInput.clear()
提交
在Selenium 4中, 不再通过单独的端点以及脚本执行的方法来实现. 因此, 建议不要使用此方法, 而是单击相应的表单提交按钮.
二、 使用选择列表元素
与其他元素相比,选择列表具有特殊的行为.
选择元素可能需要大量样板代码(boilerplate code)才能自动化. 为了减少这种情况并使您的测试更简洁, 在Selenium的support包中有一个 Select 类. 要使用它,您将需要以下导入语句:
from selenium.webdriver.support.select import Select
然后,参考 select元素,基于WebElement创建一个Select对象。
select_element = driver.find_element(By.ID,'selectElementID')
select_object = Select(select_element)
Select对象现在将为您提供一系列命令,使您可以与 select元素进行交互. 首先,有多种方法可以从 select 元素中选择一个选项
<select>
<option value=value1>Bread</option>
<option value=value2 selected>Milk</option>
<option value=value3>Cheese</option>
</select>
有三种方法可以从上述元素中选择第一个选项:
# Select an <option> based upon the <select> element's internal index
# 选项索引
select_object.select_by_index(1)
# Select an <option> based upon its value attribute
# 选项value属性值
select_object.select_by_value('value1')
# Select an <option> based upon its text
# 选项文本
select_object.select_by_visible_text('Bread')
然后,您可以检视所有被选择的选项:
# Return a list[WebElement] of options that have been selected
# 检查所有被选择的选项
all_selected_options = select_object.all_selected_options
# Return a WebElement referencing the first selection option found by walking down the DOM
# 返回列表中第一个被选择的选项
first_selected_option = select_object.first_selected_option
或者可能只对 select 元素包含哪些 option 元素感兴趣:
# Return a list[WebElement] of options that the <select> element contains
# 返回列表的所有选项
all_available_options = select_object.options
如果要取消选择任何元素,现在有四个方法(仅适用于多选列表):
# Deselect an <option> based upon the <select> element's internal index
# 选项索引
select_object.deselect_by_index(1)
# Deselect an <option> based upon its value attribute
# 选项value属性值
select_object.deselect_by_value('value1')
# Deselect an <option> based upon its text
# 选项文本
select_object.deselect_by_visible_text('Bread')
# Deselect all selected <option> elements
# 取消所有被选择的选项
select_object.deselect_all()
最后,一些 select 元素允许选择多个选项. 可以通过使用以下命令确定您的 select 元素是否允许多选:
does_this_allow_multiple_selections = select_object.is_multiple
三、Action接口
用于向 Web 浏览器提供虚拟化设备输入操作的低级接口.
除了刚刚讲过的Web元素交互之外, Actions 接口 还提供了对指定输入设备 可以执行的确切操作的精细控制. Selenium为3种输入源提供了接口: 键盘设备的键输入, 鼠标, 笔或触摸设备的输入, 以及滚轮设备的滚轮输入 (在Selenium 4.2中引入). Selenium允许您构建分配给特定输入的独立操作命令, 会将他们链接在一起, 并调用关联的执行方法以一次执行它们.
Actions 接口官方文档
https://w3c.github.io/webdriver/#dfn-actions
Action构造器
在从遗留JSON Wire协议迁移到 新的W3C WebDriver协议的过程中, 低级的操作构建块变得特别详细. 它非常强大, 但每个输入设备都有多种使用方法, 如果您需要管理多个设备, 则负责确保他们之间的同步正确.
值得庆幸的是, 不需要学习如何直接使用低级命令, 因为要执行的几乎所有操作, 都已提供了相应的简便方法, 这些方法可以组合较低级别的命令. 请分别参阅下面相应的键盘, 鼠标, 笔 和滚轮 小节.
暂停
指针移动和滚轮滚动 允许用户设置操作的持续时间, 有时只需要在操作之间等待一下, 即可正常工作.
clickable = driver.find_element(By.ID, "clickable")
ActionChains(driver)\
.move_to_element(clickable)\
.pause(1)\
.click_and_hold()\
.pause(1)\
.send_keys("abc")\
.perform()
释放所有Actions
需要注意的重要一点是, 驱动程序会记住整个会话中所有输入项的状态. 即使创建actions类的新实例, 按下的键和指针的位置 也将处于以前执行的操作离开它们的任何状态.
有一种特殊的方法来释放所有当前按下的键和指针按钮. 此方法在每种语言中的实现方式不同, 因为它不会使用perform方法执行.
ActionBuilder(driver).clear_actions()
四、Keyboard actions(键盘事件)
用于与网页交互的任何关键输入设备的表示。
只有两个操作可以用键盘完成:按下一个键和释放一个按下的键。除了支持ASCII字符之外,每个键盘键都有一个表示,可以按下或释放指定的序列。
Keys(键)
除了由常规unicode表示的键之外,还将unicode值分配给其他键盘键,以便与Selenium一起使用。每种语言都有自己的方法来引用这些键;
完整的列表链接:
https://www.w3.org/TR/webdriver/#keyboard-actions
from selenium.webdriver.common.keys import Keys
Key down (按下键位)
ActionChains(driver)\
.key_down(Keys.SHIFT)\
.send_keys("abc")\
.perform()
Key up (松开键位)
ActionChains(driver)\
.key_down(Keys.SHIFT)\
.send_keys("a")\
.key_up(Keys.SHIFT)\
.send_keys("b")\
.perform()
Send keys (发送按键信息)
这是Actions API中的一个方便的方法,它将keyDown和keyUp命令组合在一个操作中。执行此命令与使用元素方法略有不同,但主要用于需要在其他操作中间输入多个字符的情况。
Active Element (活性元素)
活性元素,也就是当前所在的元素,比如例子中的输入框
ActionChains(driver)\
.send_keys("abc")\
.perform()
Designated Element (指定的元素)
text_input = driver.find_element(By.ID, "textInput")
ActionChains(driver)\
.send_keys_to_element(text_input, "abc")\
.perform()
Copy and Paste (复制和粘贴)
下面是一个使用上述所有方法来执行复制/粘贴操作的示例。注意,此操作使用的键将根据是否是Mac OS而有所不同。这段代码将以以下文本结束:SeleniumSelenium!
cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL
ActionChains(driver)\
.send_keys("Selenium!")\
.send_keys(Keys.ARROW_LEFT)\
.key_down(Keys.SHIFT)\
.send_keys(Keys.ARROW_UP)\
.key_up(Keys.SHIFT)\
.key_down(cmd_ctrl)\
.send_keys("xvv")\
.key_up(cmd_ctrl)\
.perform()
五、Mouse actions(鼠标事件)
用于与网页交互的任何指针设备的表示形式。
只有3个动作可以用鼠标完成:按下一个按钮,释放一个被按下的按钮,移动鼠标。Selenium提供了最常见的方式组合这些操作的方便方法。
Click and hold (点击并按住不放)
此方法结合了将鼠标移动到元素中心与按下鼠标左键。这对于聚焦特定元素很有用
clickable = driver.find_element(By.ID, "clickable")
ActionChains(driver)\
.click_and_hold(clickable)\
.perform()
Click and release (点击然后松开)
此方法将移动到元素中心与按下和释放鼠标左键结合在一起。这也被称为“点击”
clickable = driver.find_element(By.ID, "click")
ActionChains(driver)\
.click(clickable)\
.perform()
Alternate Button Clicks (交替点击按钮)
一个鼠标共有5个定义按钮:
- 0 — Left Button (the default) 左键(默认)
- 1 — Middle Button (currently unsupported) 中键(目前不支持)
- 2 — Right Button 右键
- 3 — X1 (Back) Button (后退)按钮
- 4 — X2 (Forward) Button (前进)按钮
Context Click (单击右键)
这种方法结合了移动到元素中心与按下并释放鼠标右键(按钮2)
clickable = driver.find_element(By.ID, "clickable")
ActionChains(driver)\
.context_click(clickable)\
.perform()
Back Click (点击后退)
按下并释放鼠标按钮3
action = ActionBuilder(driver)
action.pointer_action.pointer_down(MouseButton.BACK)
action.pointer_action.pointer_up(MouseButton.BACK)
action.perform()
普通鼠标没有前进和后退按钮,代码会报错,
AttributeError: type object 'MouseButton' has no attribute 'BACK'
游戏鼠标有,左侧还有2个按键的那种
Forward Click (点击前进)
按下和释放鼠标按钮4
action = ActionBuilder(driver)
action.pointer_action.pointer_down(MouseButton.FORWARD)
action.pointer_action.pointer_up(MouseButton.FORWARD)
action.perform()
Double click (双击)
此方法将移动到元素中心与两次按下并释放鼠标左键结合在一起
clickable = driver.find_element(By.ID, "clickable")
ActionChains(driver)\
.double_click(clickable)\
.perform()
Move to element (移动到元素)
此方法将鼠标移动到元素的视图内中心点。这也被称为“悬停”。注意元素必须在视窗中,否则命令会出错。
hoverable = driver.find_element(By.ID, "hover")
ActionChains(driver)\
.move_to_element(hoverable)\
.perform()
Move by offset (按偏移量移动)
这些方法首先将鼠标移动到指定的原点,然后移动提供的偏移量中的像素数。请注意,鼠标的位置必须在视口中,否则命令将出错。
Offset from Element (Top Left Origin) 从元素偏移(左上原点)
此方法将鼠标移动到元素的视图中心点,然后尝试移动到元素的左上角,然后移动提供的偏移量。
这将在 Selenium 4.3 中作为一个选项被删除,并且仅支持从元素中心的偏移。从 Selenium 4.2 开始,这是 Ruby、.NET 和 Python 的默认行为,以便向后兼容之前的 Selenium 版本。当元素不完全位于视窗内时,此方法无法正常工作。
mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
ActionChains(driver)\
.move_to_element_with_offset(mouse_tracker, 8, 0)\
.perform()
Offset from Element (Center Origin) 从元素偏移(中心原点)
此方法移动到元素的视图中心点,然后将鼠标移动到提供的偏移量
这是自 Selenium 4.0 起的 Java 中的默认行为,自 Selenium 4.3 起将成为其余语言的默认行为。
**在 Selenium 4.3 中推出**
JAVA 版本
WebElement tracker = driver.findElement(By.id("mouse-tracker"));
new Actions(driver)
.moveToElement(tracker, 8, 0)
.perform();
Offset from Viewport 从视窗偏移
此方法将鼠标从当前视口的左上角移动提供的偏移量。
action = ActionBuilder(driver)
action.pointer_action.move_to_location(8, 0)
action.perform()
Offset from Current Pointer Location 从当前指针位置偏移
此方法将鼠标从其当前位置移动用户提供的偏移量。如果鼠标之前没有移动过,该位置将位于视窗的左上角。请注意,滚动页面时指针位置不会改变。
请注意,第一个参数 X 指定当为正时向右移动,而第二个参数 Y 指定当为正时向下移动。所以moveByOffset(30, -10)从当前鼠标位置向右移动 30 和向上 10。
ActionChains(driver)\
.move_by_offset( 13, 15)\
.perform()
Drag and Drop on Element 在元素上拖放
该方法首先在源元素上单击并按住,移动到目标元素的位置,然后释放鼠标。
draggable = driver.find_element(By.ID, "draggable")
droppable = driver.find_element(By.ID, "droppable")
ActionChains(driver)\
.drag_and_drop(draggable, droppable)\
.perform()
Drag and Drop by Offset 按偏移量拖放
此方法首先在源元素上执行单击并按住,移动到给定的偏移量,然后释放鼠标。
draggable = driver.find_element(By.ID, "draggable")
start = draggable.location
finish = driver.find_element(By.ID, "droppable").location
ActionChains(driver)\
.drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y'])\
.perform()
六、Pen actions(笔操作)
一种用于与网页交互的触控笔类型的指针输入的表示。
PS:这块内容,目前没找到合适的应用场景,稍作了解即可
Chromium Only
仅支持谷歌浏览器,上面这个链接网址展示的是官方测试用例结果集,其中
test_touch_pointer_properties 用例说明 Pen actions 只有谷歌可以成功
Pen 是一种指针输入类型,其行为与鼠标的大部分行为相同,但也可以具有触控笔独有的事件属性。此外,虽然鼠标有 5 个按钮,但笔有 3 个等效的按钮状态:
0 — Touch Contact(默认值;相当于左键单击)
2 — Barrel Button 桶形按钮(相当于右键单击)
5 — Eraser Button 橡皮擦按钮(驱动程序目前不支持)
Using a Pen 使用笔
Selenium v4.2
该代码要求Selenium 4.2以上版本
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2)\
.pointer_up()
action.perform()
Adding Pointer Event Attributes 添加指针事件属性
Selenium v4.2
该代码要求Selenium 4.2以上版本
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
.pointer_up(0)
action.perform()
七、滚轮
Scroll wheel actions 滚轮动作
用于与网页交互的滚轮输入设备的表示。
Selenium v4.2
Chromium Only
Selenium V4.2以上版本,仅支持谷歌浏览器
在页面上滚动有 5 种场景
Scroll to element 滚动到元素
这是最常见的情况。与传统的单击和发送键方法不同,动作类不会自动将目标元素滚动到视图中,因此如果元素不在视窗内,则需要使用此方法。
此方法将 Web 元素作为唯一参数。
无论元素是在当前视图屏幕的上方还是下方,视窗都会滚动,因此元素的底部位于屏幕的底部。
iframe = driver.find_element(By.TAG_NAME, "iframe")
ActionChains(driver)\
.scroll_to_element(iframe)\
.perform()
Scroll by given amount 按给定数值滚动
这是第二个最常见的滚动场景。传入一个 delta x 和一个 delta y 值来确定向右和向下滚动多少。负值分别代表左和上。
footer = driver.find_element(By.TAG_NAME, "footer")
delta_y = footer.rect['y']
ActionChains(driver)\
.scroll_by_amount(0, delta_y)\
.perform()
PS:这个rect,就是显示元素在浏览器页面中的坐标位置,具体值,可以在开发者工具里,查看元素右侧的Properties信息中的:offsetTop (高) 和 offsetWidth (宽)
Scroll from an element by a given amount 基于元素按给定数值滚动
这种情况实际上是上述两种方法的组合。
要执行此操作,请使用“Scroll From”方法,该方法需要 3 个参数。第一个表示起始点,我们将其指定为元素,后两个是 delta x 和 delta y 值。
如果元素超出视窗,它将滚动到屏幕底部,然后页面将滚动提供的 delta x 和 delta y 值。
iframe = driver.find_element(By.TAG_NAME, "iframe")
scroll_origin = ScrollOrigin.from_element(iframe)
ActionChains(driver)\
.scroll_from_origin(scroll_origin, 0, 200)\
.perform()
Scroll from an element with an offset 基于元素按偏移量滚动
当您只需要滚动屏幕的一部分并且它在视窗之外时使用此方案。或者在视窗内并且必须滚动的屏幕部分是距特定元素的已知偏移量。
这里再次使用了“Scroll From”方法,除了指定元素外,还指定了一个偏移量来表示滚动的原点。偏移量是从提供的元素的中心计算的。
如果元素在视窗之外,首先会滚动到屏幕底部,然后通过将偏移量添加到元素中心的坐标来确定滚动的原点,最后页面将按提供的 delta x 和 delta y 值滚动。
请注意,如果距元素中心的偏移量落在视窗之外,则会导致异常。
footer = driver.find_element(By.TAG_NAME, "footer")
scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
ActionChains(driver)\
.scroll_from_origin(scroll_origin, 0, 200)\
.perform()
Scroll from a offset of origin (element) by given amount
基于原点(或元素)的偏移量按给点数值滚动
当只需要滚动屏幕的一部分并且它已经在视窗内时,使用最后一个场景。
这再次使用“Scroll From”方法,但指定的是视窗而不是元素。从当前视窗的左上角指定偏移量。确定原点后,页面将按提供的 delta x 和 delta y 值滚动。
请注意,如果从视窗左上角的偏移量落在屏幕之外,则会导致异常。
ActionChains(driver)\
.scroll_from_origin(scroll_origin, 0, 200)\
.perform()
本文来自博客园,作者:测试老宅男扶摇,转载请注明原文链接:https://www.cnblogs.com/cekailsf/p/16800979.html