自动化测试工具playwright中文文档-------19.评估JavaScript
简介
Playwright 脚本在您的 Playwright 环境中运行。而您的页面脚本(即页面内嵌的JavaScript)则在浏览器页面环境中运行。这两个环境是不相交的,它们在不同的进程中运行在不同的虚拟机上,甚至可能位于不同的计算机上。
page.evaluate()API 可以在网页的上下文中运行一个 JavaScript 函数,并将结果带回到 Playwright 环境。在 evaluate 中,可以使用浏览器全局对象,如 window 和 document。
href = page.evaluate('() => document.location.href')
使用 page.evaluate()
API 在当前页面的上下文中执行了一个箭头函数,该函数返回当前页面的 URL(通过访问 document.location.href
)。然后,这个 URL 字符串被 page.evaluate()
方法返回,并被赋值给变量 href
。
如果结果是一个Promise
,或者如果这个函数是异步的,evaluate
方法会自动等待直到它解决(即完成):
status = page.evaluate("""
async () => { response = await fetch(location.href); // 等待当前页面URL的fetch请求完成 return response.status; // 返回响应的状态码
}
""")
评估参数
Playwright 的评估方法(如 page.evaluate())接受一个可选的单一参数。这个参数可以是可序列化值(Serializable values)和 JSHandle 或 ElementHandle 实例的混合。Handle
实例会自动转换为它们所表示的值。
原始值
page.evaluate('num => num', 42)
传递了一个整数 42
到浏览器上下文中,并在那里被评估函数使用。
数组
page.evaluate('array => array.length', [1, 2, 3])
传递了一个包含三个整数的数组到评估函数中,该函数返回数组的长度 3
对象
page.evaluate('object => object.foo', { 'foo': 'bar' })
传递了一个包含属性 foo
的对象到评估函数中,该函数返回 foo
的值 'bar'
单个句柄
button = page.evaluate_handle('window.button')
page.evaluate('button => button.textContent', button)
首先使用 evaluate_handle
获取一个页面元素的句柄(可能是按钮),然后在 evaluate
方法中使用这个句柄来获取该元素的文本内容。
使用 elementHandle.evaluate
的替代表示法
button.evaluate('(button, from) => button.textContent.substring(from)', 5)
直接在 ElementHandle
实例上调用 evaluate
方法,传入一个函数和额外的参数(在这里是从 5
开始截取文本内容)。
包含多个句柄的对象
button1 = page.evaluate_handle('window.button1')
button2 = page.evaluate_handle('.button2')
page.evaluate("""o => o.button1.textContent + o.button2.textContent""", { 'button1': button1, 'button2': button2 })
传递一个包含两个 ElementHandle
实例的对象到评估函数中,该函数连接这两个元素的文本内容。
对象解构
page.evaluate(""" ({ button1, button2 }) => button1.textContent + button2.textContent""", { 'button1': button1, 'button2': button2 })
使用对象解构来简化对传入对象的访问,注意解构对象的属性名和参数中的属性名必须匹配,并且需要括号。
数组解构
page.evaluate(""" ([b1, b2]) => b1.textContent + b2.textContent""", [button1, button2])
使用数组解构来访问传入的 ElementHandle
数组,可以使用任意名称进行解构。
任意非循环的可序列化和句柄的混合
page.evaluate(""" x => x.button1.textContent + x.list[0].textContent + String(x.foo)""", { 'button1': button1, 'list': [button2], 'foo': None })
可以传递一个包含可序列化值(如 None
,在 JavaScript 中会被转换为 null
)和 ElementHandle
实例的复杂对象到评估函数中。
正确用法(Right)
data = { 'text': 'some data', 'value': 1 }
# 将 |data| 作为参数传递给 evaluate 函数中的箭头函数
result = page.evaluate("""data => { window.myApp.use(data)
}""", data)
page.evaluate()
方法接受两个参数:第一个参数是一个字符串,它定义了要在浏览器上下文中执行的 JavaScript 代码(这里是一个箭头函数),第二个参数是要传递给这个 JavaScript 代码的变量(在这个例子中是 data
字典)。在 JavaScript 代码中,你可以通过箭头函数的参数(在这个例子中是 data
)来访问这个变量。因此,在这个例子中,window.myApp.use(data)
能够正确地接收到从 Python 传递过来的 data
字典,并将其作为参数传递给 window.myApp.use()
方法。
错误用法(Wrong)
data = { 'text': 'some data', 'value': 1 }
result = page.evaluate("""() => { // 这里的 |data| 在网页的 JavaScript 环境中是未定义的。 window.myApp.use(data)
}""")
page.evaluate()
方法的 JavaScript 字符串参数定义了一个不接受任何参数的箭头函数(() => { ... }
)。因此,在这个函数体内,data
变量是未定义的,因为它没有被作为参数传递给箭头函数。当尝试执行 window.myApp.use(data)
时,由于 data
是未定义的,这将导致一个错误(通常是引用错误,即 ReferenceError)。
当你需要在 Playwright 的 page.evaluate()
方法中访问 Python 变量时,你需要确保这些变量作为参数传递给 JavaScript 字符串中定义的函数。这是通过将这些变量作为 page.evaluate()
方法的额外参数来实现的,这些参数随后会在 JavaScript 函数的参数列表中可用。