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

使用Light-Playwright做性能测试遇执行上下文销毁错误,如何获取新页面?

解决Playwright+Lighthouse性能测试中导航导致的执行上下文销毁问题

问题描述

在使用Playwright结合Lighthouse做性能测试时,点击"Find Hotels"按钮触发页面导航后,调用audit方法时报错:

page.evaluate: Execution context was destroyed, most likely because of a navigation

原测试代码如下:

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

test.describe('Top 20 sites', () => {

  test(`Ligthouse User Journey performance test`, async () => {
    test.slow();
    const browser = await playwright['chromium'].launch({
      args: ['--remote-debugging-port=9222'],
    });
    const page = await browser.newPage();
    await page.goto('https://www.google.com');
    await page.getByRole('button', { name: 'Find Hotels' }).click();
    // const context = await browser.newContext();
    // Create a new page in a pristine context.
    const results = await audit(page, 'userFlow')
    await page.close();
    await browser.close();
    // expect(results.lhr.categories.performance.score, `${'https://www.marriott.com/default.mi'} fell below the minimum threshold`).toBeGreaterThanOrEqual(.30);
  });
});

审计方法代码:

export const audit = async (page: Page, reportDir: string) => 
    playAudit({
        page: page,
        config: lighthouseDesktopConfig,
        thresholds: thresholds,
        port: 9222,
        reports: {
          formats: {
            html: true, //defaults to false
          },
          name: `ligthouse-${new Date().toISOString()}`, //defaults to `lighthouse-${new Date().getTime()}`
          directory: `${process.cwd()}/lighthouse/${reportDir}`, //defaults to `${process.cwd()}/lighthouse`
        },
      });

问题原因

点击按钮触发页面导航后,原page对象对应的执行上下文被销毁,此时直接用旧的page实例调用Lighthouse审计,就会触发执行上下文已销毁的错误。

解决方案

场景1:点击后在当前页面导航

如果点击按钮后是在当前页面跳转(未打开新标签),需要同时执行点击操作和等待导航完成,确保页面执行上下文稳定后再启动审计:

修改测试代码中的点击逻辑:

// 同时执行点击和等待导航完成,可按需调整waitUntil参数
await Promise.all([
  page.waitForNavigation({ waitUntil: 'networkidle' }),
  page.getByRole('button', { name: 'Find Hotels' }).click()
]);

场景2:点击后打开新页面/新标签

如果点击按钮后打开了新标签页,需要捕获新创建的页面实例,用新页面执行审计:

// 等待新页面创建,同时执行点击操作
const [newPage] = await Promise.all([
  browser.waitForEvent('page'),
  page.getByRole('button', { name: 'Find Hotels' }).click()
]);

// 等待新页面加载完成
await newPage.waitForLoadState('networkidle');

// 使用新页面执行审计
const results = await audit(newPage, 'userFlow');

// 记得关闭新页面
await newPage.close();

完整修改后的测试代码(当前页面导航场景)

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

test.describe('Top 20 sites', () => {
  test(`Lighthouse User Journey performance test`, async () => {
    test.slow();
    const browser = await playwright['chromium'].launch({
      args: ['--remote-debugging-port=9222'],
    });
    const page = await browser.newPage();
    await page.goto('https://www.google.com');

    // 同步执行点击与导航等待
    await Promise.all([
      page.waitForNavigation({ waitUntil: 'networkidle' }),
      page.getByRole('button', { name: 'Find Hotels' }).click()
    ]);

    // 执行性能审计
    const results = await audit(page, 'userFlow');

    await page.close();
    await browser.close();
    // expect(results.lhr.categories.performance.score, `${'https://www.marriott.com/default.mi'} fell below the minimum threshold`).toBeGreaterThanOrEqual(.30);
  });
});

注意事项

  • waitForNavigation的waitUntil参数可按需调整:
    • 'load':等待页面所有资源加载完成
    • 'domcontentloaded':等待DOM加载完成
    • 'networkidle':等待网络空闲(500ms内没有请求)
  • 如果使用Playwright Test的默认上下文管理,可省略手动launch browser的步骤,通过test.use配置远程调试端口,代码会更简洁。

内容的提问来源于stack exchange,提问作者D.Hodges

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 04:45:07