You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 11:27:20