【playwright篇】教程(三)[Locator对象方法详解]

在 Playwright 中,Locator 对象提供了多种方法来帮助你与页面上的元素进行交互。下面是一些常用的方法及其详细的说明。

注意: page.locator() 返回的是一个 Locator 对象,它表示所有匹配选择器的元素集合,而不是单个元素。

  • 不指定 nth() 的情况

    • 如果你直接对 Locator 对象执行操作(如 click()fill() 等),Playwright 会自动作用于 第一个匹配的元素(即索引为 0 的元素)。
    • 这是因为大多数交互方法(如 click())默认针对第一个匹配的元素。
  • 明确指定 nth() 操作其他元素
    • 如果你需要操作非第一个元素,可以使用 nth(index) 方法显式指定索引。

Locator 对象常用方法

动作相关:

1. click()
  • 描述:模拟鼠标点击事件。
  • 参数
    • button (可选): 指定点击哪个鼠标按钮,可以是 'left''right', 或 'middle'
    • click_count (可选): 指定点击次数,默认为 1。
    • delay (可选): 指定两次点击之间的时间间隔(以毫秒为单位)。
    • force (可选): 如果为 True,则强制点击元素,即使元素不可见或被遮挡。
    • no_wait_after (可选): 如果为 True,则不等待任何动作完成之后再执行下一步。
    • position (可选): 指定点击元素的位置,可以是 (x, y) 坐标。
    • timeout (可选): 设置等待元素变得可点击的最大时间(以毫秒为单位)。
2. fill(text)
  • 描述:填写表单字段。
  • 参数
    • text: 要填写的文本。

input输入框输入内容使用 locator.fill("abc")

3. type(text)
  • 描述:模拟键盘输入。
  • 参数
    • text: 要键入的文本。
    • delay (可选): 指定两次按键之间的时间间隔(以毫秒为单位)。
4. press(key)
  • 描述:模拟键盘按键。
  • 参数
    • key: 要按下的键,可以是特殊键如 'Enter''Tab''ArrowUp' 等。
5.press_sequentially()

        在匹配的元素上按下一系列的键(如果它是一个输入元素)。

6. select_option(values)
  • 描述:选择下拉列表中的选项。
  • 参数
    • values: 一个或多个选项的值,可以是字符串或列表。
    • index (可选): 选项的索引。
    • label (可选): 选项的标签。
    • value (可选): 选项的值。
    • timeout (可选): 设置等待元素变得可选择的最大时间(以毫秒为单位)。
7. hover()
  • 描述:模拟鼠标悬停事件。
  • 参数
    • timeout (可选): 设置等待元素变得可悬停的最大时间(以毫秒为单位)。
8. focus()
  • 描述:将焦点设置到元素上。
  • 参数:无
blur()
  • 描述:从元素移除焦点。元素失去焦点
  • 参数:无
10. scroll_into_view_if_needed()
  • 描述:如果需要,滚动页面使元素可见。
  • 参数:无
11.check

        勾选匹配的元素(如果它是一个复选框或单选框)。


12.uncheck

        取消勾选匹配的元素(如果它是一个复选框或单选框)。


13.clear

        清除匹配元素的输入值(如果它是一个输入元素)。


14.dblclick

        双击匹配的元素。

15.drag_to

        将匹配的元素拖动到另一个位置。

16.set_checked

        设置匹配的元素的勾选状态(如果它是一个复选框或单选框)。

17.select option

        选择匹配的元素的一个选项(如果它是一个 select 元素)。

18.select text

        选择匹配的元素的文本(如果它是一个输入元素或 textarea 元素)。

19.set_input_files

        设置匹配的元素的输入文件(如果它是一个文件输入元素)。

20.waitFor() 方法

waitFor({ state: 'detached' })方法可以用于等待元素消失。

例如,`page.locator('#my-id').waitFor({ state: 'detached' })` 会等待直到 id 为 "my-id" 的元素消失。

waitFor({ state: 'hidden' }) 方法可以用于等待元素隐藏。

例如,`page.locator('#my-id').waitFor({ state: 'hidden' })` 会等待直到 id 为 "my-id" 的元素隐藏。

waitFor({ state: 'visible' })` 方法可以用于等待元素显示。

例如,`page.locator('#my-id').waitFor({ state: 'visible' })` 会等待直到 id 为 "my-id" 的元素显示。

waitFor({ state: 'editable' })` 方法可以用于等待元素可编辑。

例如,`page.locator('#my-id').waitFor({ state: 'editable' })` 会等待直到 id 为 "my-id" 的元素可编辑。

waitFor({ state: 'checked' })` 方法可以用于等待元素被选中。

例如,`page.locator('#my-id').waitFor({ state: 'checked' })` 会等待直到 id 为 "my-id" 的元素被选中。

21. evaluate(expression, *args)
  • 描述:在浏览器环境中执行 JavaScript 表达式。
  • 参数
    • expression: JavaScript 表达式。
    • *args: 表达式中使用的参数。
  • 返回值:表达式的结果。

查询相关

1.or_

        创建一个新的 Locator,它匹配满足当前 Locator 或另一个条件的元素。

        # 定位所有链接
        links = page.locator("a")
        
        # 过滤具有文本 "About Us" 或 "Contact Us" 的链接
        about_or_contact_link = links.filter(has_text="About Us").or_(links.filter(has_text="Contact Us"))

2.and_

        创建一个新的 `Locator`,它匹配同时满足当前 `Locator` 和另一个条件的元素。

# 定位所有按钮
buttons = page.locator("button")
        
# 过滤具有文本 "Submit" 并且具有类 "primary" 的按钮
primary_submit_button = buttons.filter(has_text="Submit").filter(where={"class": "primary"})

同时过滤具有特定文本和特定属性值的元素,并使用 and_or_ 方法来组合这些条件:

        # 定位所有链接
        links = page.locator("a")
        
        # 过滤具有文本 "About Us" 并且具有 href 属性值为 "/about" 的链接
        # 或者具有文本 "Contact Us" 并且具有 href 属性值为 "/contact" 的链接
        about_us_link = links.filter(has_text="About Us").filter(where={"href": "/about"})
        contact_us_link = links.filter(has_text="Contact Us").filter(where={"href": "/contact"})
        
        # 使用 or_ 方法组合两个条件
        about_or_contact_link = about_us_link.or_(contact_us_link)
        
        # 检查链接是否存在
        if about_or_contact_link.count() > 0:
            print("At least one of the 'About Us' or 'Contact Us' links exists and has the correct href.")
        else:
            print("Neither 'About Us' nor 'Contact Us' links exist or have incorrect href.")

3.filter(不会具体去查)
1. has_text 参数

功能

根据元素的可见文本内容进行筛选。

  • 支持模糊匹配和精确匹配。

示例代码

# 筛选包含文本 "Submit" 的按钮
filtered_locator = locator.filter(has_text="Submit")

# 精确匹配文本
filtered_locator = locator.filter(has_text="Exact Text", exact=True)

适用场景

  • 需要根据元素的可见文本内容筛选目标元素。

2. has 参数

功能

根据子元素的存在性进行筛选。

  • 传入一个 Locator 对象,表示目标元素必须包含指定的子元素。

示例代码

# 筛选包含子元素 <span> 的 div
filtered_locator = locator.filter(has=page.locator("span"))

适用场景

  • 需要根据子元素的存在性筛选父元素。

3. has_not 参数

功能

根据子元素的不存在性进行筛选。

  • 传入一个 Locator 对象,表示目标元素不能包含指定的子元素。

示例代码

# 筛选不包含子元素 <span> 的 div
filtered_locator = locator.filter(has_not=page.locator("span"))

适用场景

  • 需要排除包含某些子元素的目标元素。

4. 组合使用多个条件

你可以同时使用多个参数来组合筛选条件。

示例代码

# 筛选包含文本 "Submit" 且包含子元素 <span> 的按钮
filtered_locator = locator.filter(
    has_text="Submit",
    has=page.locator("span")
)
5. 总结
参数功能
has_text根据元素的可见文本内容进行筛选(支持模糊匹配和精确匹配)。
has根据是否包含某个子元素进行筛选(传入一个 Locator 对象)。
has_not根据是否不包含某个子元素进行筛选(传入一个 Locator 对象)。

6.注意事项
  1. 模糊匹配 vs 精确匹配

    • 默认情况下,has_text 是模糊匹配。如果需要精确匹配,可以设置 exact=True
  2. 性能影响

    • 使用 filter() 时,Playwright 会在后台重新计算匹配的元素集合,因此可能会对性能产生一定影响。尽量避免不必要的过滤操作。
  3. 调试信息

    • 在调试时,可以先使用 locator.count() 检查筛选结果的数量,确保筛选逻辑正确。

通过灵活使用 filter() 方法,你可以更精确地定位目标元素,从而编写更加健壮和可维护的自动化测试脚本!


4.locator

        创建一个新的 Locator,它匹配满足一个定位器的元素。
        选择器链:page.locator(selector1).locator(selector2),可以链接多个选择器来定位嵌套的元素。

#通过span子元素查找父元素;再通过父元素查找div子元素
div_locator = page.locator('label').filter(has=page.locator("span:text('abc')")).locator("div")

5.highlight

        高亮匹配的元素。

6. is_visible()

  • 描述:检查元素是否可见。
  • 参数:无
  • 返回值:布尔值,如果元素可见返回 True如果不存在或不可见返回 False
  • 这个方法不会等待。
  • 它立即检查当前 DOM 中是否存在这个元素,并且是否可见(不是隐藏的)。
7. is_enabled()
  • 描述:检查元素是否启用。
  • 参数:无
  • 返回值:布尔值,如果元素启用返回 True,否则返回 False
  • 这个方法是等待型的(wait-aware)。
  • Playwright 默认会等最多 30 秒 去查找该元素,并判断它是否启用。
  • 如果在这期间找不到这个元素(比如它还没加载出来,或者压根不存在),最终就会抛出:timeout异常
8. is_hidden()
  • 描述:检查元素是否隐藏。
  • 参数:无
  • 返回值:布尔值,如果元素隐藏返回 True,否则返回 False
9. is_disabled()
  • 描述:检查元素是否禁用。
  • 参数:无
  • 返回值:布尔值,如果元素禁用返回 True,否则返回 False
10.is_checked

        检查匹配的元素是否被勾选(如果它是一个复选框或单选框)。

11.is_editable

        检查匹配的元素是否可编辑。

12. count()
  • 描述:返回匹配选择器的元素数量。
  • 参数:无
  • 返回值:整数,匹配元素的数量。
13. all()
  • 描述:返回所有匹配选择器的元素列表。
  • 参数:无
  • 返回值:元素列表。page.locator().all()
14. nth(index)
  • 描述:选择特定索引的元素。
  • 参数
    • index: 索引值,从 0 开始。
  • 返回值:特定索引的 Locator 对象。
page.locator(locator_str).first()
page.locator(locator_str).last()
15.get_attribute('属性名')

示例

content = locator1.get_attribute('aria-label')

注:如果有此属性,则返回此属性的值;如果无此属性,则返回None

16.inner_text()

inner_text() 方法主要用于获取元素内部的文本内容,对于输入框,它并不直接返回输入框的值。

<div>abc</div>  ---locator.inner_text()  可以获取到内容:abc

17.text_content()

        方法可以用于获取元素的文本内容。

        例如,`page.locator('#my-id').textContent()` 会返回 id 为 "my-id" 的元素的文本内容。

        <div>abc</div>  ----locator.text_content()  可以获取到内容:abc

18.innerHTML()

        方法可以用于获取元素的内部 HTML。

        例如,`page.locator('#my-id').innerHTML()` 会返回 id 为 "my-id" 的元素的内部 HTML。

19.outerHTML()

        方法可以用于获取元素的外部 HTML。

        例如,`page.locator('#my-id').outerHTML()` 会返回 id 为 "my-id" 的元素的外部 HTML。


20.bounding_box()

        返回匹配元素的边界框。

# 如果元素存在,则移动鼠标到元素中心
if bounding_box is not None:
    x = bounding_box['x'] + bounding_box['width'] / 2
    y = bounding_box['y'] + bounding_box['height'] / 2
    # 移动鼠标到元素中心
    page.mouse.move(x, y)
21.input_value()

        获取匹配元素的输入值(如果它是一个输入元素)。要获取输入框的内容,应该使用 locator.input_value() 方法。

适用于: <input>, <textarea> or <select> element 元素类型

其它locator,会提示错误,如下

Locator.input_value: Error: Node is not an <input>, <textarea> or <select> element

22.get_by_alt_text()

         创建一个新的 Locator,它匹配 alt 属性包含指定文本的元素。


23.get_by_label()

        创建一个新的 Locator,它匹配 label 属性包含指定文本的元素。


24.get_by_placeholder()

        创建一个新的 Locator,它匹配 placeholder 属性包含指定文本的元素。


25.get_by_role()

        创建一个新的 Locator,它匹配 role 属性包含指定文本的元素。

# 定位具有 role="menuitem" 且 aria-label 或 aria-labelledby 的值为 "Send" 的元素
div_locator = page.get_by_role("menuitem", name="Send", exact=True)

26.get_by_test_id()

        创建一个新的 Locator,它匹配 data-testid 属性包含指定文本的元素。


27.get_by_text()

        创建一个新的 Locator,它匹配文本包含指定文本的元素。


28.get_by_title()

        创建一个新的 Locator,它匹配 title 属性包含指定文本的元素。

27.all_inner_texts()

        返回所有匹配元素的内部文本。


28.all_text_contents()

        返回所有匹配元素的文本内容。

属性

first: 返回第一个匹配的元素
last: 返回最后一个匹配的元素
page: 返回关联的 Page对象
        # 创建定位器对象
12        elements_locator = page.locator('.myElement')
13        
14        # 获取第一个匹配的元素
15        first_element = elements_locator.first
16        
17        # 获取最后一个匹配的元素
18        last_element = elements_locator.last
19        
20        # 获取关联的 Page 对象
21        associated_page = elements_locator.page
22        
23        # 对第一个元素执行操作
24        first_element.click()
25        
26        # 对最后一个元素执行操作
27        last_element.click()
28        
29        # 使用关联的 Page 对象执行其他操作
30        associated_page.screenshot(path="example.png")
31        

示例代码

下面是一个示例,展示了如何使用 Locator 对象的一些方法:

from playwright.sync_api import sync_playwright

def interact_with_element():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        # 导航到目标网址
        page.goto("https://example.com")
        
        # 创建定位器对象
        element = page.locator('#myElement')
        
        # 对元素执行操作
        element.click()  # 点击元素
        element.fill('Hello')  # 填充文本
        element.type('World')  # 键入文本
        element.press('Enter')  # 模拟按下 Enter 键
        element.select_option(['option1', 'option2'])  # 选择下拉列表中的选项
        element.hover()  # 悬停在元素上
        element.focus()  # 将焦点设置到元素上
        element.blur()  # 从元素移除焦点
        
        # 检查元素状态
        if element.is_visible():
            print("Element is visible.")
        if element.is_enabled():
            print("Element is enabled.")
        if element.is_hidden():
            print("Element is hidden.")
        if element.is_disabled():
            print("Element is disabled.")
        
        # 获取元素数量
        count = element.count()
        print(f"Number of elements: {count}")
        
        # 获取所有匹配的元素
        all_elements = element.all()
        
        # 选择特定索引的元素
        specific_element = element.nth(1)
        
        # 继续执行其他操作...
        
        browser.close()

# 运行测试
interact_with_element()
### 关于 ARIA Label 的正则表达式匹配 ARIA (Accessible Rich Internet Applications) 是一种用于提高网页可访问性的技术标准,`aria-label` 属性为辅助技术提供了额外的信息描述。当涉及到 `aria-label` 或类似的 ARIA 属性时,可以通过正则表达式来验证其值是否符合预期。 #### 正则表达式的定义与匹配逻辑 对于 `(.*?)` 这种模式的理解如下: - 圆括号 `()` 表示捕获组,用来提取匹配的部分。 - 点`.`表示任意单个字符(除了换行符),如果启用了特殊标志,则可能包括换行符。 - 星号`*`表示前面的字符可以重复零次或多次。 - 问号`?`使星号变为懒惰匹配,即尽可能少地匹配字符而不是贪婪地匹配尽可能多的字符[^1]。 因此,`(.*?)` 将会匹配从起始位置到第一个结束条件之间的最短字符串序列。 #### 实际应用中的代码示例 下面是一个 JavaScript 中如何使用该正则表达式去检测并提取 aria-label 值的例子: ```javascript // 给定一段 HTML 字符串 const htmlString = '<button aria-label="点击这里">按钮</button>'; // 创建一个正则表达式实例 const regex = /aria-label="(.*?)"/; // 执行匹配操作 const matchResult = htmlString.match(regex); if (matchResult && matchResult[1]) { console.log('Matched ARIA label:', matchResult[1]); // 输出: Matched ARIA label: 点击这里 } else { console.log('No matching ARIA label found.'); } ``` 上述脚本利用了正则表达式 `/aria-label="(.*?)"/` 来查找具有特定属性名及其对应值的内容,并成功提取出了 `"点击这里"` 这一具体标签说明文字[^2]。 #### 结合 Vue.js 模板语法处理场景 假如是在基于 Vue.js 构建的应用程序里想要动态设定某个控件上的 `aria-label` ,那么就可以借助模板插值功能完成这一需求: ```vue <template> <div> <!-- 动态绑定 aria-label --> <input type="text" :aria-label="dynamicAriaLabel"> </div> </template> <script> export default { data() { return { dynamicAriaLabel: '输入框' }; } }; </script> ``` 在此处我们看到的是通过冒号前缀的方式实现了对自定义特性的赋值过程,在运行期间这些特性会被解析成实际有效的HTML属性[^3]。 #### 利用 Playwright API 对含有 ARIA 标记元素进行交互模拟 假设现在要填充一个带有指定 `aria-label` 提示信息字段的情况,Playwright 可以帮助实现自动化测试目的下的数据录入动作演示如下所示: ```javascript await page.fill('[aria-label="用户名"]', 'testUser'); ``` 这里的 `[aria-label="用户名"]` 即代表了一个 CSS selector 形式的定位方式,专门针对拥有相应 ARIA 特性名称等于给定值得那个唯一 DOM 节点执行后续命令[^4]。 ### 总结 综上所述,无论是简单的文本替换还是复杂的前端框架集成以及后端驱动浏览器行为控制等方面都离不开灵活运用各种工具和技术手段解决问题的能力展现出来。而掌握好基础理论知识加上不断实践积累经验才是成为优秀工程师的关键所在!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值