文章标题:Python与Playwright:高效操控Handles的自动化探究
文章内容:
嘿,各位好呀,我是六哥!今天来跟大家唠一唠Playwright里处理Handles的办法,面向搞功能测试的还有零基础的小白,我尽量用大白话来举例讲解,让所有人都能听明白,建议大伙先收藏起来,不然后面就找不到啦。😎
一、Handles究竟是啥
在Playwright当中,Handles属于一种特殊的数据结构,它能在Playwright的进程和浏览器环境之间搭建起桥梁,让你可以从Playwright的环境里去访问和操作浏览器内的对象。简单说呢,Handles能让你“抓住”页面上的元素或者JavaScript对象,然后对它们进行操作。
二、为啥需要Handles?
- 跨环境操作:因为Playwright运行在一个进程里,而浏览器里的JavaScript代码运行在另一个进程中,Handles提供了一种机制,能让这两个环境里的对象相互操作。
- 保留对象引用:通过Handles,你能在Playwright中保留对浏览器内对象的引用,就算这些对象在浏览器环境里发生了变化,只要Handles没被销毁,你依旧能通过它们去访问那些对象。
- 延迟执行:使用Handles能延迟执行某些操作,直到特定条件满足为止,比如说等着某个元素出现在页面上。
三、两种主要类型的Handles
1、JSHandle
- 用途:用来引用页面中的任何JavaScript对象。
- 特点:JSHandle能表示任何类型的JavaScript对象,像数组、函数、DOM元素之类的。它提供了一种方式,让你能在Playwright的上下文中去操作这些对象。
- 生命周期:除非页面导航了或者显式调用了
dispose()
方法,不然JSHandle会一直存在,防止对应的JavaScript对象被垃圾回收。
2、ElementHandle
- 用途:专门用来引用页面中的DOM元素,并且提供了额外的方法来对这些元素执行操作或者断言它们的属性。
- 特点:ElementHandle继承自JSHandle,所以具备所有JSHandle的功能。另外,它还提供了一些额外的方法,比如点击、填写文本、获取元素的边界框等,这些方法能直接作用在DOM元素上。
- 生命周期:和JSHandle一样,除非页面导航了或者显式调用了
dispose()
方法,不然ElementHandle会一直存在。
四、实际应用示例
假设我们要在百度页面上做一些操作,就可以用Handles来实现:
1、获取JSHandle示例
示例代码
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
# 获取window对象的JSHandle
js_handle = page.evaluate_handle('window')
# 使用jsHandle进行评估
title = page.evaluate('window => window.document.title', js_handle)
# 断言标题
assert title == "百度一下,你就知道"
print(f"Page Title: {title}")
2、获取ElementHandle示例
示例代码
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
# 获取搜索框的ElementHandle
search_box_handle = page.wait_for_selector('#kw')
# 断言搜索框的宽高
bounding_box = search_box_handle.bounding_box()
print(f"Search Box Bounding Box: {bounding_box}")
# 断言搜索框的maxlength属性
maxlength = search_box_handle.get_attribute('maxlength')
assert maxlength == '255'
browser.close()
3、将Handle作为参数传递
当需要在页面上下文中操作由Playwright创建的对象时,可以把Handle传递给evaluate
方法。
示例代码
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
# 创建新的数组并返回数组的JSHandle
my_array_handle = page.evaluate_handle("() => { return [1]; }")
# 获取数组的长度
length = page.evaluate("array => array.length", my_array_handle)
print(f"Array Length: {length}")
# 向数组添加新元素
page.evaluate("(array, newElement) => array.push(newElement)", [my_array_handle, 2])
# 再次获取数组的长度
new_length = page.evaluate("array => array.length", my_array_handle)
print(f"New Array Length: {new_length}")
# 释放对象
my_array_handle.dispose()
browser.close()
4、使用Locator而非ElementHandle
虽然ElementHandle还是能用的,但Playwright更推荐使用Locator来执行用户动作和断言。这是因为Locator每次都会根据选择器重新定位页面上的元素,保证就算页面状态变了也能正确找到元素。
示例
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
# 使用Locator定位搜索框
search_box_locator = page.locator('#kw')
# 输入搜索词
search_box_locator.fill('Playwright')
# 提交搜索
page.locator('#su').click()
# 验证搜索结果
first_result = page.locator('h3 > a').first
print(first_result.text_content())
browser.close()
写在最后
上面的代码展示了怎么使用Playwright处理Handles的方法。你可以根据自己的需求去调整这些示例,感兴趣的小伙伴可以自己动手试试。要是需要全部源代码,公众号:软件测试君,回复“Playwright学习”就能获取,没引号哦。最后,希望大家都能顺利掌握,一起进步。也欢迎分享给更多有需要的朋友呀!要是有收获,就点个赞吧
相关文章
暂无评论...