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

Playwright中pageerror与console监听器未捕获问题求助

问题描述

我通过Playwright的Fixture实现了登录逻辑供测试用例调用,但遇到以下问题:

  • 明明通过F12开发者工具能看到页面错误和日志,但page.on("pageerror")和page.on("console")两个监听器完全捕获不到任何内容
  • 怀疑是page变量未正确关联到WebApp对应的页面,但不知道如何修复

测试用例签名:test("Test", async({WebApp,page})


Login.ts(Fixture代码)

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

let userName='XXXXAutoGeneratedUSRFN_1@gmail.com';
let password ='XXXXXXXXXX';
let baseURL = "https://XXXXXXXXXXX/" ;

exports.baseURL = baseURL; // 想把这个变量暴露给调用方,不确定写法是否正确
exports.expect = expect;

exports.test = test.extend({
   WebApp: async ({page}, use) => {
        await page.goto(baseURL);
        // 断言标题包含指定子串
        await expect(page).toHaveTitle(/XXXXXXXX/);

        await page.locator('input:has-text("Login")').click();
        // 确保跳转到登录/注册页面
        await expect(page).toHaveURL(baseURL + 'LoginOrSignUp',{ timeout: (1000 * 1000) });
        
        // 点击Login标签页
        await page.locator('div[role="toolbar"] >> text=Login').click();
        // 输入邮箱
        await page.fill("#logInEmail",`${userName}`);
        // 输入密码
        await page.fill('#loginInPassword', `${password}`);

        await page.locator('#loginSignIn').click();
        await page.waitForURL("https://XXXXXXXXXXX/")

        await use(page)
   },
});

测试用例代码

const {test, expect, baseURL,WebApp} = require("./Login");

test.describe("Describe-Test", ()=>{ 
    test.beforeEach(async ({page}) =>{
        console.log("Before Each fired");
    });

    test.use({ 
        geolocation : {latitude:41.74959, longitude: -88.19903},
        permissions :['geolocation'],
        project: 'Mobile Chrome'
    });
  
    test("Test", async({WebApp,page}) => {
        await test.step("Open Search Page", async () => {
            await WebApp.locator('input:has-text("Get In Line")').click();
            await expect(WebApp).toHaveURL(baseURL + 'XXXXXXXXX');
            await expect(WebApp.locator('button', { hasText: 'Search' })).toBeVisible();
        });

        await test.step("Search for Business", async () => {
            const PAGE_ERRORS:string[] = [];
            let gpsAvailable:boolean = false;

            // 不工作:明明有页面错误,但无任何日志输出
            page.on("pageerror",(exception) => {
                PAGE_ERRORS.push(exception);
                console.log("Page Error Event Fired");
            });
                 
            // 不工作:明明有控制台日志,但未捕获到任何内容
            const CONSOLE_LOG:any[] = [];
            page.on("console",(message) => {
                if(message == "JavaScript: displayMarkersOnGoogleMap Executed")
                {
                  gpsAvailable=true;
                }
                CONSOLE_LOG.push({message, type:message.type()});
            });

            console.log(CONSOLE_LOG);
            await WebApp.locator('#searchByCode').fill(`E28E06B4-6434-44FA-812B-D86E2C061BCE`); //搜索
          
            if(!gpsAvailable)
            {
                console.log("GPS not available, waiting...");
                await WebApp.waitForTimeout(4000); // 此方法正常工作,地理定位需等待
            }
            
            await WebApp.locator('button', { hasText: 'Search' }).click();
            await WebApp.locator('button', { hasText: 'GetInLine' }).click();
            // 断言URL以指定前缀开头
            await expect(WebApp).toHaveURL(new RegExp('^' + baseURL + 'SelectToken'));

            await WebApp.locator("text='Written Exam' >> input[name='Categoryoptions']" ).click();
            // 获取Token
            await Promise.all([
                WebApp.waitForResponse('**/api/Organization/XXXXXXXXX'),
                WebApp.locator('button.btn-success', { hasText: 'GetInLine' }).click(),
            ]);

            console.log(PAGE_ERRORS);
            expect(PAGE_ERRORS.length).toBe(0);
            // 断言成功消息显示
            await expect(WebApp.locator('.alert-success')).toContainText('A new Token');
        });
    }); 
});

问题原因与修复方案

核心问题

测试用例中监听的page是Playwright默认生成的全新页面实例,而你实际操作的WebApp是Fixture中完成登录后的页面实例,二者完全不关联,因此监听器无法捕获到WebApp页面的错误和日志。

修复步骤

1. 将监听器绑定到WebApp对象

把测试用例中所有的page.on替换为WebApp.on,因为所有页面操作都基于WebApp实例:

// 替换原来的page.on为WebApp.on
WebApp.on("pageerror",(exception) => {
    PAGE_ERRORS.push(exception);
    console.log("Page Error Event Fired:", exception);
});

WebApp.on("console",(message) => {
    // 注意:message是ConsoleMessage对象,需用text()方法获取实际日志内容
    const msgText = message.text();
    if(msgText === "JavaScript: displayMarkersOnGoogleMap Executed")
    {
      gpsAvailable=true;
    }
    CONSOLE_LOG.push({text: msgText, type:message.type()});
});

2. 修复控制台消息判断逻辑

原代码中直接用message == "xxx"比较是错误的,message是Playwright的ConsoleMessage对象,必须调用message.text()才能获取字符串形式的日志内容。

3. 优化变量暴露方式(可选)

Fixture中暴露baseURL的方式可以更规范,改用TypeScript导出语法:

// Login.ts中替换原exports代码
export const baseURL = "https://XXXXXXXXXXX/" ;
export { expect } from '@playwright/test';
export const test = test.extend({/*...*/});

4. 移除冗余的page参数(可选)

测试用例中无需同时解构WebApp和page,直接使用WebApp即可,避免混淆。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:47:53