如何在percySnapshot截图失败时让Playwright测试用例失败?
如何让Playwright中Percy截图失败时强制终止测试用例
问题描述
我有一个基于Playwright的E2E测试,调用percySnapshot方法进行截图。当该方法因网络请求超时等原因无法生成截图时,控制台会输出错误信息,但测试用例仍会通过。我希望实现截图失败时测试用例强制失败,然而percySnapshot仅返回Promise<void>,且SnapshotOptions中无相关配置项,请问该如何实现?
测试代码
import percySnapshot from '@percy/playwright'; import test from '@playwright/test'; const url = 'my-website.com'; test('Sample screenshot', async ({ page }) => { await page.goto(url); await percySnapshot(page, 'Sample'); });
截图失败时的错误信息
[percy] Encountered an error taking snapshot: Sample [percy] Error: Timed out waiting for network requests to idle. [percy] Detected error for Snapshot: Sample [percy] Failure: Network idle failed [percy] Failure Reason: There are pending network requests even after 30 seconds [percy] Suggestion: Snapshot Error: Timed out waiting for network requests to idle. Try increasing PERCY_NETWORK_IDLE_WAIT_TIMEOUT or Contact support for resolution. [percy] Refer to the below Doc Links for the same [percy] * https://www.browserstack.com/docs/percy/common-issue/common-errors/network-idle-timeout
相关类型定义
// percySnapshot 类型 export default function percySnapshot( page: Playwright.Page, name: string, options?: SnapshotOptions ): Promise<void>; // SnapshotOptions 类型 interface CommonSnapshotOptions { widths?: number[]; scope?: string; minHeight?: number; percyCSS?: string; enableJavaScript?: boolean; cliEnableJavascript?: boolean; disableShadowDOM?: boolean; domTransformation?: string; enableLayout?: boolean; sync?: boolean; responsiveSnapshotCapture?: boolean; testCase?: string; labels?: string; reshuffleInvalidTags?: boolean; devicePixelRatio?: number; scopeOptions?: ScopeOptions; } export interface SnapshotOptions extends CommonSnapshotOptions { discovery?: DiscoveryOptions; }
解决方案
由于@percy/playwright的percySnapshot方法默认不会在截图失败时抛出异常,我们可以通过监听Percy核心模块的错误事件来捕获截图失败信息,进而主动抛出异常让Playwright测试用例失败。
方法1:在测试用例中直接监听错误事件
import percySnapshot from '@percy/playwright'; import test from '@playwright/test'; import percy from '@percy/core'; const url = 'my-website.com'; test('Sample screenshot', async ({ page }) => { await page.goto(url); let percyError; // 定义错误处理函数,匹配截图相关错误 const handlePercyError = (error) => { if (error.message.includes('Encountered an error taking snapshot') || error.message.includes('Snapshot')) { percyError = error; } }; // 监听Percy的error事件 percy.on('error', handlePercyError); try { await percySnapshot(page, 'Sample'); // 若捕获到截图错误,主动抛出异常终止测试 if (percyError) { throw new Error(`Percy截图失败: ${percyError.message}`); } } finally { // 测试结束后移除事件监听,避免影响其他用例 percy.off('error', handlePercyError); } });
方法2:封装带错误处理的截图函数
如果多个测试用例都需要这个逻辑,可以封装一个通用函数:
// utils/percy.js import percySnapshot from '@percy/playwright'; import percy from '@percy/core'; export async function percySnapshotOnFail(page, name, options) { let percyError; const handleError = (error) => { // 精准匹配当前截图名称的错误 if (error.message.includes(`taking snapshot: ${name}`)) { percyError = error; } }; percy.on('error', handleError); await percySnapshot(page, name, options); percy.off('error', handleError); if (percyError) { throw new Error(`截图 "${name}" 失败: ${percyError.message}`); } }
在测试中使用封装后的函数:
import { percySnapshotOnFail } from './utils/percy'; import test from '@playwright/test'; const url = 'my-website.com'; test('Sample screenshot', async ({ page }) => { await page.goto(url); await percySnapshotOnFail(page, 'Sample'); });
注意事项
- 确保项目已安装
@percy/core依赖(安装@percy/playwright时通常会自动附带)。 - 错误匹配逻辑可根据实际输出的错误信息调整,确保精准捕获截图相关的失败。
内容的提问来源于stack exchange,提问作者Piotr Kwiatkowski
相关产品推荐
相关产品推荐

