- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
定位器是 Playwright 自动等待和重试能力的核心部分。简而言之,定位器代表了一种随时在页面上查找元素的方法,以下是常用的内置定位器.
按显式和隐式可访问性属性进行定位 语法:page.get_by_role() Dom结构示例1: 示例代码1:
page.get_by_role("button", name="Sign in").click()
说明:按名称为“Sign in”button的角色找到元素。 Dom结构示例2: 示例代码2 。
expect(page.get_by_role("heading", name="Sign up")).to_be_visible()
page.get_by_role("checkbox", name="Subscribe").check()
page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()
说明:
page.get_by_label() 通过关联标签的文本查找表单控件.
通过关联标签的文本查找表单控件 语法:page.get_by_label() Dom结构示例: 示例代码:
page.get_by_label("Password").fill("secret")
语法:page.get_by_placeholder() Dom结构示例: 示例代码:
page.get_by_placeholder("name@example.com").fill("playwright@microsoft.com")
按占位符查找输入 语法:page.get_by_text() Dom结构示例: 示例代码:
# 可以通过元素包含的文本找到该元素
page.get_by_text("Welcome, John")
# 设置完全匹配
page.get_by_text("Welcome, John", exact=True)
# 正则表达式匹配
page.get_by_text(re.compile("welcome, john", re.IGNORECASE))
说明:
通过其文本替代来定位元素(通常是图像),所有图片都应具有描述图像的 alt 属性。可以使用page.get_by_alt_text() 根据替代文本查找图片。 语法:page.get_by_alt_text() Dom结构示例: 示例代码:
page.get_by_alt_text("playwright logo").click()
说明:当元素支持替代文本(如 img 和 area 元素)时,建议使用此定位器 。
按元素的 title 属性查找元素 语法:page.get_by_title() Dom结构示例: 示例代码:
expect(page.get_by_title("Issues count")).to_have_text("25 issues")
说明:当元素具有 title 属性时,建议使用此定位器 7、按测试 ID 查找 根据元素data-testid 属性来定位元素(可以配置其他属性) 语法:page.get_by_title() Dom结构示例: 示例代码:
page.get_by_test_id("directions").click()
默认情况下,page.get_by_test_id() 将根据 data-testid 属性查找元素,但您可以在测试配置中或通过调用 selectors.set_test_id_attribute() 来配置它。 将测试 ID 设置为对测试使用自定义数据属性,示例代码:
playwright.selectors.set_test_id_attribute("data-pw")
Dom结构: 然后像往常一样找到该元素,示例代码如下:
page.get_by_test_id("directions").click()
如果绝对必须使用 CSS 或 XPath 定位器,则可以使用 page.locator() 创建一个定位器,该定位器采用一个选择器来描述如何在页面中查找元素。Playwright 支持 CSS 和 XPath 选择器,如果省略 css= 或 xpath= 前缀,则会自动检测它们。 示例代码:
page.locator("css=button").click()
page.locator("xpath=//button").click()
page.locator("button").click()
page.locator("//button").click()
说明:
Shadow DOM 是 Web Components 技术的一部分,它提供了一种将 HTML 结构、样式和行为封装在一个独立的、封闭的 DOM 中的机制。以下是一个使用 Shadow DOM 的例子,该例子展示了如何创建一个简单的自定义组件,并将内容、样式封装在 Shadow DOM 中。 示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shadow DOM Example</title>
<style>
/* 外部样式,不会影响 Shadow DOM 内部 */
.container {
font-size: 20px;
color: red;
}
</style>
</head>
<body>
<div id="hostElement" class="container">Shadow Host (这里不会显示 Shadow DOM 的内容)</div>
<script>
// 自定义元素定义及 Shadow DOM 创建
class MyCustomElement extends HTMLElement {
constructor() {
super();
// 创建 Shadow Root
const shadowRoot = this.attachShadow({ mode: 'open' });
// Shadow DOM 内部样式和内容
shadowRoot.innerHTML = `
<style>
.shadow-content {
font-size: 16px;
color: blue;
}
</style>
<div class="shadow-content">This is inside the Shadow DOM.</div>
`;
}
}
// 注册自定义元素
customElements.define('my-custom-element', MyCustomElement);
// 将自定义元素添加到文档中
const customElement = document.createElement('my-custom-element');
document.body.appendChild(customElement);
// 注意:在实际应用中,你可能会将自定义元素直接写在 HTML 中,如:<my-custom-element></my-custom-element>
// 而不是通过 JavaScript 动态创建和添加。
</script>
</body>
</html>
dom结构:
首先打开浏览器控制台的设置选项 然后再找到Preference -> Elements,把show user anent shadow dom勾上 这时候我们再来看一下此时的dom元素发生了什么变化 。
我们会发现这些标签内部都大有乾坤,在这些标签下面都多了一个shadow root,在它里面才是这些标签的真实布局.
默认情况下,Playwright 中的所有定位器都使用 Shadow DOM 中的元素。例外情况包括:
要定位,使用page.get_by_text("")或page.locator("", has_text="")都可以,要确保 。
page.goto("http://localhost:8080/shadowDOM.html")
expect(page.get_by_text("This is inside the Shadow DOM.")).to_contain_text("Shadow DOM")
expect(page.locator("div", has_text="This is inside the Shadow DOM.")).to_contain_text("This is inside")
可以使用 locator.filter() 方法按文本过滤定位器。它将在不区分大小写的情况下搜索元素内部的某个特定字符串,可能在后代元素中。 示例代码:
page.get_by_role("listitem").filter(has_text="Product 2").get_by_role(
"button", name="Add to cart"
).click()
#传递正则表达式。
page.get_by_role("listitem").filter(has_text=re.compile("Product 2")).get_by_role(
"button", name="Add to cart"
).click()
expect(page.get_by_role("listitem").filter(has_not_text="Out of stock")).to_have_count(2)
定位器支持仅选择具有或没有与另一个定位器匹配的后代的元素的选项。因此,您可以按任何其他定位器进行过滤,例如 locator.get_by_role()、locator.get_by_test_id()、locator.get_by_text() 等。 示例代码:
page.get_by_role("listitem").filter(
has=page.get_by_role("heading", name="Product 2")
).get_by_role("button", name="Add to cart").click()
断言产品卡,确保只有一个,示例代码如下:
expect(
page.get_by_role("listitem").filter(
has=page.get_by_role("heading", name="Product 2")
)
).to_have_count(1)
过滤定位器必须相对于原始定位器,并且从原始定位器匹配项(而不是文档根节点)开始查询.
通过内部没有匹配的元素进行过滤,示例代码:
expect(
page.get_by_role("listitem").filter(
has_not=page.get_by_role("heading", name="Product 2")
)
).to_have_count(1)
注意,内部定位器是从外部定位器开始匹配的,而不是从文档根目节点开始匹配的.
就先定位元素,再去定位子节点元素,以将搜索范围缩小到页面的特定部分。 示例代码 。
product = page.get_by_role("listitem").filter(has_text="Product 2")
product.get_by_role("button", name="Add to cart").click()
也可以将两个元素定位组合在一起使用,示例代码如下:
save_button = page.get_by_role("button", name="Save")
# ...
dialog = page.get_by_test_id("settings-dialog")
dialog.locator(save_button).click()
方法 locator.and_() 通过匹配其他定位器来缩小现有定位器的范围,可以理解为xpath的and使用方法,都是定位一个元素,示例代码如下:
page.get_by_role("link").and_(page.get_by_text("新闻")).click()
如果您想定位两个或多个元素中的一个,但不知道会是哪一个,请使用 locator.or_() 创建与所有备选项匹配的定位器。示例代码如下:
def test_navigationCnblogs(page: Page):
page.goto("https://www.baidu.com/")
login=page.get_by_role("link").and_(page.get_by_text("登录"))
message=page.get_by_text("短信登录")
expect(message.or_(login).first).to_be_visible()
if (login.is_visible()):
login.click()
message.click()
考虑一个有两个按钮的页面,第一个不可见,第二个可见,这时候就可以进行约束,示例代码如下:
page.locator("button").locator("visible=true").click()
dom结构:
使用 count 断言确保列表有 3 个项目,示例代码如下:
expect(page.get_by_role("listitem")).to_have_count(3)
断言定位器以查找列表中的所有文本,示例代码如下:
expect(page.get_by_role("listitem")).to_have_text(["apple", "banana", "orange"])
使用 page.get_by_text() 方法按文本内容在列表中查找元素,示例代码如下:
page.get_by_text("orange").click()
也可以使用 locator.filter() 查找列表中的特定元素,示例代码如下:
page.get_by_role("listitem").filter(has_text="orange").click()
您有一个相同元素的列表,并且区分它们的唯一方法是顺序,则可以使用 locator.first、locator.last 或 locator.nth() 从列表中选择特定元素.
banana = page.get_by_role("listitem").nth(1)
expect(banana).to_have_text('banana')
当您有具有各种相似性的元素时,使用 locator.filter() 方法选择正确的元素。还可以链接多个筛选器以缩小选择范,就是层级定位,个人感觉。 DOM 结构 示例代码 。
row_locator = page.get_by_role("listitem")
row_locator.filter(has_text="Mary").filter(
has=page.get_by_role("button", name="Say goodbye")
).screenshot(path="screenshot.png")
对列表中的每个元素执行操作,示例代码如下:
for row in page.get_by_role("listitem").all():
print(row.text_content())
rows = page.get_by_role("listitem")
count = rows.count()
for i in range(count):
print(rows.nth(i).text_content())
我觉得这个就是很ES6呀,示例代码如下:
rows = page.get_by_role("listitem")
# 很前端了吧
texts = rows.evaluate_all("list => list.map(element => element.textContent)")
定位元素如果出现定位多个元素,这个就很好用了,可以作为检验是否定位到唯一元素检测,示例代码如下:
print(page.get_by_role("button").count()) #2
最后此篇关于【Playwright+Python】系列教程(五)元素定位的文章就讲到这里了,如果你想了解更多关于【Playwright+Python】系列教程(五)元素定位的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!