前言
在进行软件测试,比如针对一个电商网站,你是否遇到过这些问题?
- 动态加载的商品列表:部分商品因缺货、促销结束或未登录状态被隐藏。
- 悬浮显示的促销标签:仅当用户鼠标悬停时才会展示优惠信息。
- 广告弹窗干扰:某些弹窗可能遮挡核心功能,但测试时需要确保主流程不受影响。
这些场景的共同点是:页面元素可能存在于DOM中,但用户实际不可见, 比如设置CSS属性(display: none
、visibility: hidden
)。传统测试方法需要手动判断元素可见性,遍历或预先这对具体对象进行分支判断,比较复杂。
Playwright 最新版本提供了一个简化方法
在最新更新的 Playwright V1.5.1 版本更新中,针对locator.filter()
方法新增了visible
选项,可以极大简化这部分操作。(目前针对node.js有此更新,Python语言尚未支持)
其核心作用是:
仅筛选页面上用户实际可见的元素,自动忽略因CSS(如display: none
)或布局原因隐藏的元素。
技术原理:
Playwright通过计算元素的布局边界、透明度、层叠上下文等属性,判断元素是否在视口内且对用户可见。这与真实用户视角完全一致,避免因操作隐藏元素导致测试失败。
场景实战:过滤可见商品
假设我们测试一个中文电商平台的**“限时秒杀”页面**,其HTML结构如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<!DOCTYPE html>
<html>
<head>
<title>限时秒杀</title>
</head>
<body>
<div class="seckill-list">
<!-- 可见商品 -->
<div data-testid="product-item" class="product">
<h3>【爆款】无线蓝牙耳机</h3>
<p class="price">促销价: ¥199</p>
<button>立即抢购</button>
</div>
<div data-testid="product-item" class="product">
<h3>智能手环</h3>
<p class="price">促销价: ¥299</p>
<button>立即抢购</button>
</div>
<!-- 隐藏商品(已抢光或未开始) -->
<div data-testid="product-item" class="product" style="display: none;">
<h3>家用投影仪</h3>
<p class="price">促销价: ¥899</p>
<button>已售罄</button>
</div>
<div data-testid="product-item" class="product" style="opacity: 0;">
<h3>空气炸锅</h3>
<p class="price">促销价: ¥399</p>
<button>未开始</button>
</div>
</div>
</body>
</html>
|
需求场景
用户访问“限时秒杀”页面时,仅展示可抢购的商品(前两项),隐藏已售罄或未开始的商品。我们需要验证:
- 页面中用户可见的商品数量是否正确。
- “立即抢购”按钮仅对可见商品生效。
新旧方案对比
旧方法:手动遍历+可见性检查
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 旧方案示例
import { test, expect } from '@playwright/test';
test('验证可见商品数量', async ({ page }) => {
await page.goto('https://mall.example.com/seckill');
const allProducts = await page.getByTestId('product-item').all();
let visibleCount = 0;
for (const product of allProducts) {
if (await product.isVisible()) {
visibleCount++;
}
}
expect(visibleCount).toBe(2); // 断言可见商品为2个
});
|
痛点:
- 需要手动遍历所有元素,代码冗余。
- 若商品数量动态变化(如分页加载),维护成本高。
新方案:一行代码过滤可见元素
1
2
3
4
5
6
7
8
9
10
|
// 新方案示例
import { test, expect } from '@playwright/test';
test('验证可见商品数量', async ({ page }) => {
await page.goto('https://mall.example.com/seckill');
const visibleProducts = page.getByTestId('product-item').filter({ visible: true });
// 断言可见商品数量为2
await expect(visibleProducts).toHaveCount(2);
// 断言所有可见商品均可点击“立即抢购”
await expect(visibleProducts.getByText('立即抢购')).toHaveCount(2);
});
|
优势:
- 代码简洁:无需循环,直接通过链式调用过滤。
- 实时匹配:自动响应页面动态变化(如AJAX加载新商品)。
- 精准断言:结合Playwright的软断言(Soft Assertions),可同时验证多个条件。
扩展应用:电商测试中的常见场景
场景1:验证悬浮显示的促销标签
某些商品的“限时折扣”标签仅在鼠标悬停时显示。通过visible: true
可确保仅操作实际可见的元素:
1
2
3
4
5
|
// 鼠标悬停后,验证促销标签可见
const productCard = page.getByTestId('product-card').filter({ visible: true }).first();
await productCard.hover();
const discountTag = productCard.getByText('限时5折');
await expect(discountTag).toBeVisible();
|
场景2:过滤弹窗干扰
若页面存在广告弹窗,可通过visible: true
跳过隐藏的弹窗元素:
1
2
3
4
5
|
// 关闭可见的弹窗(忽略已隐藏的)
const activePopup = page.getByTestId('popup').filter({ visible: true });
if (await activePopup.isVisible()) {
await activePopup.getByText('关闭').click();
}
|
结语
通过这个 Playwright
更新的实用功能,可以较大简化我们在进行自动化测试时编写的复杂度,也可以看到,作为势头正劲的新一代web测试工具,Playwright的不断升级优化还是很贴合实际且社区活跃,值得重点关注!
秋草也推出了一个 基于Pytest+Playwright的自动化框架实战课程,有兴趣的同学可关注: