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

Playwright如何模拟请求延迟/永不响应的测试场景?

问题描述

我需要测试服务在响应延迟或永不响应时的表现,目前采用了如下暴力实现方式:

await page.route(url, () => page.waitForTimeout(1000));

但Playwright文档指出page.waitForTimeout()仅适用于调试场景。我想了解:

  1. 如何让页面请求指定URL时触发超时?
  2. 另一种场景:当页面请求api/items这类接口时,如何在请求未完成前检查页面状态?

测试示例代码如下:

import { test, expect } from '@playwright/test';

test('banner shows in progress message', async ({ page }) => {
  await page.route('**/async-resource.json', () => {
     // 该请求应在测试结束前保持未完成状态
     page.waitForTimeout(1000);
  });

  await page.goto('https://async.page/');
  const banner = page.getByRole('banner');
  await expect(banner).toHaveText('Your data are being prepared!');
});
解决方案

1. 模拟指定URL请求超时或挂起

不要使用page.waitForTimeout(),可以通过以下两种方式实现:

  • 模拟请求永不响应:创建一个永远不resolve的Promise,让请求一直处于挂起状态:
    await page.route('**/async-resource.json', () => new Promise(() => {}));
    
  • 模拟请求超时错误:延迟后拒绝Promise,触发请求超时:
    await page.route('**/async-resource.json', () => 
      new Promise((_, reject) => setTimeout(() => reject(new Error("请求超时")), 1000))
    );
    

2. 在请求未完成前检查页面状态

通过拦截请求后不立即处理(不调用route.continue()或route.fulfill()),即可在请求挂起时检查页面状态。修正后的测试代码如下:

import { test, expect } from '@playwright/test';

test('banner shows in progress message', async ({ page }) => {
  // 拦截请求并保持挂起
  await page.route('**/async-resource.json', (route) => {
    // 不调用任何处理方法,请求会一直处于未完成状态
  });

  await page.goto('https://async.page/');
  
  // 等待请求被拦截(确保页面已发起请求)
  await page.waitForEvent('request', req => req.url().includes('async-resource.json'));

  // 此时请求未完成,检查页面加载状态
  const banner = page.getByRole('banner');
  await expect(banner).toHaveText('Your data are being prepared!');

  // 若后续需要恢复请求,可调用 route.continue()
  // route.continue();
});

如果需要更灵活的控制(比如后续恢复请求),可以将路由实例保存到Promise中:

import { test, expect } from '@playwright/test';

test('banner shows in progress message', async ({ page }) => {
  let holdRoute;
  const requestHeld = new Promise(resolve => {
    page.route('**/async-resource.json', (route) => {
      holdRoute = route;
      resolve();
    });
  });

  await page.goto('https://async.page/');
  await requestHeld; // 等待请求被拦截

  // 检查页面状态
  const banner = page.getByRole('banner');
  await expect(banner).toHaveText('Your data are being prepared!');

  // 可选:恢复请求
  // holdRoute.continue();
});

内容的提问来源于stack exchange,提问作者pbaranski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:45:39