「自动化测试」playwright 项目开发中,监听网络请求、页面下载、浏览器新标签页等场景通用设计方法

本文探讨了如何通过监听网络请求响应来验证告警详情数据的完整性和下载文件类型的正确性,避免过早断言带来的测试不稳定性。方法包括使用Promise.all结合错误处理以及网络请求拦截技术,同时关注页面事件如下载和新标签页的监听。
摘要由CSDN通过智能技术生成

监听网络请求响应结果

相关需求:验证告警详情数据是否成功展示

问题:由于无法从过数据是否展示来单纯的判断相应是否成功,因为可能会出现部分数据展示,部分数据还在响应的情况

解决方案

方案一:通过判断响应失败时展示的dialog错误弹框来判断是否响应成功(有不稳定因素)
代码如下:

test('验证查看告警详情成功', async ({page}) => {
	// 点击告警数据,打开告警详情
	await page.locator('.el-table__fixed-body-wrapper .el-table__body tr >> nth=0 >> .e2e-warning-detail').click()
    // 断言告警详情打开,并且没有弹出错误提示弹框
    expect('.sf-dialog__wrapper .sf-drawer__header:has-text(告警详情)', '告警详情抽屉不能正确打开').toBeVisible();
    expect('.sfv-notify .notify-msg', '告警详情数据响应失败').toBeHidden();
});

该代码有一个问题 expect('.sfv-notify .notify-msg', '告警详情数据响应失败').toBeHidden();

其中这个判断语句,应该是要在数据响应回来后再进行判断,但是由于不能确定数据到底什么时候响应回来,可能在数据还没响应回来之前,该测试代码已经走到断言阶段了,就会出现明明返回的是失败的 code 而由于测试代码走的比响应快,导致弹框还没出现的时候,测试代码已经走完,并且判定数据响应成功。

而通过加 timeout 的方式,会使得测试变得不稳定,所以开始寻找一种能通过拦截响应结果判定里面 code 内容的方式来实现测试代码。

方案二:通过监听网路请求的响应结果,取出其中的code进行判断是否成功
代码如下:

test('验证查看告警详情成功', async ({page}) => {
    // 点击告警数据,打开告警详情,并监听详情Api请求的响应结果,获取返回的 Response 对象
    const [ Response ] = await Promise.all([
        page.waitForResponse('**/order/v1/alarm_table/alarm_detail?_method=GET'),
        await page.locator('.el-table__fixed-body-wrapper .el-table__body tr >> nth=0 >> .alert-column-name').click()
    ]);
    // 从响应正文的 JSON 中获取 code
    const { code } = await Response.json();
    expect(code, '告警详情数据请求失败').toBe(0);
});

错误的思想

使用 apiRequest 来实现

该方法虽然也能获取到响应结果,但是有一个弊端就是,他不是由我们前端页面发出的请求

而是通过模拟一个类似请求去实现获取响应结果,但是可能页面的接口结果,与我们模拟的请求的结果相反,会造成结果的误差!

监听页面下载内容

需求:想要验证页面下载的文件类型是否为预期类型

实现

对于页面下载文件,我们可以通过 page.waitForEvent('download') 监听页面的download事件去获得一个 download对象然后可以获取到下载文件的,

文件名,路径,页面,网址等,APIDownload

以验证导出告警成功为例,获取到 download对象后,获取其文件名,然后进行断言

// 开启下载事件监听,解构赋值其返回的download对象
const [ download ] = await Promise.all([
    page.waitForEvent('download'),
    await page.locator('.confirm-export-warning-dialog .bootstrap-dialog-footer-buttons button:has-text("确认")').click()
]);

const fileName = download.suggestedFilename();
const fileExt = fileName.match(/(?<=\.)xlsx/)?.[0];
expect(fileExt, '文件拓展名不符合预期xlsx类型').toBe('xlsx');

小坑

const fileExt = fileName.match(/(?<=\.)xlsx/)?.[0];

这里由于匹配失败后为null,而null取[0]会报错,所以需要在前面加上 ?.

监听览器弹窗或新标签页

需求:验证点击按钮,浏览器成功在新标签页打开对应页面

实现

由于该页面跳转打开了一个页面,我们不能直接使用当前页面的 page对象去进行相应的操作

经过查找文档,发现监听页面的 popup 事件可以返回一个新页面的 page对象

代码实现,以验证点击客户设备跳转成功为例

// 监听浏览器打开新窗口或标签页的 popup 事件,并解构赋值其返回的 page 
const [ customerPage ] = await Promise.all([
    page.waitForEvent('popup'),
    page.locator('.custom-list-wrap div[data-index="1"] .btn-customer-list-divice').click()
])

// 等待新页面加载完成
await customerPage.waitForLoadState('domcontentloaded');
// 断言新的页面地址为客户设备
const deviceUrl = customerPage.url();
expect(deviceUrl, '客户资产设备跳转失败').toMatch(/.*\/customer\/.*\/device.*/);
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值