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

如何让TestCafe在断言失败时自动上报页面HTML?

当然可以实现这个需求!TestCafe提供了几种方案来在断言失败时自动捕获页面HTML,不管失败原因是什么,刚好能解决你遇到的这种“只知道选择器找不到,但不知道当前页面到底是什么”的排查痛点。

方案一:全局配置(无需修改现有断言)

这种方式最省心,无需修改你已经写好的任何测试代码,只要在TestCafe的运行配置里添加一个失败回调,就能捕获所有测试失败时的页面HTML。

如果你是用编程式方式运行TestCafe(比如自己写Node脚本启动测试),可以利用TestCafe Runner的onTestFailed事件:

const createTestCafe = require('testcafe');
const fs = require('fs');
let testcafe = null;

createTestCafe('localhost', 1337, 1338)
    .then(tc => {
        testcafe = tc;
        const runner = testcafe.createRunner();

        return runner
            .src(['./tests/**/*.js']) // 你的测试文件路径
            .browsers('chrome') // 指定测试浏览器
            .onTestFailed(async (testInfo, error, args) => {
                // 获取当前测试会话的浏览器连接,抓取页面完整HTML
                const { browserConnection } = args;
                const pageFullHtml = await browserConnection.driverClient.execute(
                    () => document.documentElement.outerHTML
                );

                // 将HTML保存到本地文件,方便后续查看
                const fileName = `failed-test-${testInfo.name.replace(/\s+/g, '-')}-${Date.now()}.html`;
                fs.writeFileSync(fileName, pageFullHtml);
                console.log(`测试失败,页面HTML已保存到: ${fileName}`);
            })
            .run();
    })
    .then(failedCount => {
        console.log(`测试完成,共失败 ${failedCount} 个用例`);
        testcafe.close();
    })
    .catch(err => {
        console.error('运行测试出错:', err);
        testcafe.close();
    });

如果你习惯用命令行运行TestCafe,可以把上述逻辑封装成自定义报告器,不过编程式的方式更直接可控。

方案二:单个断言增强(按需修改)

如果不想全局捕获,只想针对特定断言添加HTML上报,或者暂时无法修改全局运行配置,可以包装一个自定义的断言函数,在断言失败时自动抓取HTML:

import { t, Selector } from 'testcafe';

// 自定义带HTML上报的断言函数
async function assertWithHtmlCheck(assertionAction, failMsg = '断言失败') {
    try {
        await assertionAction();
    } catch (error) {
        // 抓取当前页面的完整HTML
        const pageHtml = await t.eval(() => document.documentElement.outerHTML);
        
        // 输出错误信息和HTML(可替换成上报到你的测试平台)
        console.error(`❌ ${failMsg}: ${error.message}`);
        console.error('当前页面HTML:', pageHtml);
        
        // 重新抛出错误,保证测试结果的正确性
        throw error;
    }
}

// 使用示例
test('验证Foo按钮存在', async t => {
    // 把原来的断言放进assertWithHtmlCheck里即可
    await assertWithHtmlCheck(async () => {
        await t.expect(Selector('button').withText('Foo').exists).ok();
    }, '页面中未找到文本为"Foo"的按钮');
});

这个方式的好处是可以精准控制哪些断言需要触发HTML上报,不会产生冗余的文件或日志。

补充说明

不管用哪种方式,抓取到的HTML都是测试失败瞬间的页面完整内容,你可以直接打开保存的HTML文件,就能看到当时页面的真实状态——比如是不是跳转到了错误的页面,或者按钮被隐藏、文本被修改了,这些信息能帮你快速定位问题,而不用只对着“选择器找不到元素”的提示猜原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:15:55