鞍山市网站建设_网站建设公司_虚拟主机_seo优化
2026/1/7 21:28:00 网站建设 项目流程

关注 霍格沃兹测试学院公众号,回复「资料」, 领取人工智能测试开发技术合集

作为现代自动化测试的重要工具,Playwright的截图和录屏功能远比表面看上去强大。我在多个实际项目中深入使用这些功能后,发现了许多官方文档未详述的技巧和最佳实践,今天就来分享这些经验。

一、基础截图功能:不只是page.screenshot()
大多数开发者都熟悉基础截图,但细节决定成败:

const { chromium } = require('playwright');

(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();

// 基础全屏截图
await page.goto('https://example.com');
await page.screenshot({ path: 'screenshot.png' });

// 推荐:添加等待确保页面稳定
await page.waitForLoadState('networkidle'); // 等待网络空闲
await page.waitForSelector('#main-content'); // 等待关键元素
await page.screenshot({
path: 'stable-screenshot.png',
fullPage: false, // 默认只截可视区域
animations: 'disabled'// 禁用动画,避免截图模糊
});

await browser.close();
})();
关键点:直接截图常遇到元素未加载或动画干扰的问题。我习惯在截图前至少等待networkidle状态,对于动态内容多的页面,还会添加额外的等待条件。

二、精准元素截图:定位的艺术
精确截图特定元素是调试和测试的关键:

// 获取元素并截图
const element = await page.$('#login-form');
await element.screenshot({
path: 'login-form.png',
// 添加边框便于识别
style: 'border: 2px solid #f00;'
});

// 多个相同元素处理
const buttons = await page.$$('button.submit-btn');
for (let i = 0; i < buttons.length; i++) {
await buttons[i].screenshot({
path: button-${i}.png,
// 设置内边距,让截图更美观
padding: { top: 5, right: 5, bottom: 5, left: 5 }
});
}

// 处理动态内容:等待元素特定状态
await page.waitForSelector('.notification', {
state: 'visible',
timeout: 5000
});
const notification = await page.$('.notification');
await notification.screenshot({ path: 'notification.png' });
经验之谈:元素截图常因定位问题失败。我总使用try-catch包装截图操作,并添加重试逻辑。对于绝对定位或fixed定位的元素,可能需要调整视口位置才能正确截图。

Playwright mcp技术学习交流群
伙伴们,对AI测试、大模型评测、质量保障感兴趣吗?我们建了一个 「Playwright mcp技术学习交流群」,专门用来探讨相关技术、分享资料、互通有无。无论你是正在实践还是好奇探索,都欢迎扫码加入,一起抱团成长!期待与你交流!👇

image

三、全页面滚动截图:处理长页面的挑战
// 基础全页面截图
await page.screenshot({
path: 'fullpage.png',
fullPage: true,
// 关键:设置高质量截图
quality: 100, // 仅限png,jpeg需要调整quality
type: 'png' // png支持透明背景
});

// 处理懒加载页面的技巧
asyncfunction screenshotLazyLoadPage(page, scrollDelay = 300) {
// 先获取页面总高度
const bodyHeight = await page.evaluate(() =>document.body.scrollHeight);
const viewportHeight = page.viewportSize().height;

// 逐步滚动并触发懒加载
for (let scrollTop = 0; scrollTop < bodyHeight; scrollTop += viewportHeight) {
await page.evaluate((scrollTop) => {
window.scrollTo(0, scrollTop);
}, scrollTop);

// 等待可能的懒加载
await page.waitForTimeout(scrollDelay);

}

// 回到顶部后截图
await page.evaluate(() =>window.scrollTo(0, 0));
returnawait page.screenshot({ path: 'lazy-loaded-fullpage.png', fullPage: true });
}
踩坑提醒:全页截图时,fixed定位的导航栏或页脚会在每屏重复出现。如果不需要这些重复元素,可以通过注入CSS临时隐藏:await page.addStyleTag({ content: 'header { display: none !important; }' })

四、视口控制与多分辨率测试
// 测试不同设备截图
const devices = [
{ name: 'iPhone 12', viewport: { width: 390, height: 844 } },
{ name: 'iPad', viewport: { width: 768, height: 1024 } },
{ name: 'Desktop', viewport: { width: 1920, height: 1080 } }
];

for (const device of devices) {
await page.setViewportSize(device.viewport);
await page.waitForTimeout(1000); // 让布局重新计算

await page.screenshot({
path: screenshot-${device.name}.png,
// 针对移动端优化
scale: device.name.includes('iPhone') ? 'css' : 'device'
});
}

// 截图特定区域(视口部分区域)
await page.screenshot({
path: 'viewport-area.png',
clip: {
x: 100,
y: 100,
width: 800,
height: 600
}
});
五、录屏功能:不仅仅是录制
Playwright的录屏功能在排查偶现问题时特别有用:

const { chromium } = require('playwright');
const fs = require('fs');

(async () => {
const browser = await chromium.launch();
const context = await browser.newContext({
// 启用录屏
recordVideo: {
dir: 'videos/',
size: { width: 1280, height: 720 }
}
});

const page = await context.newPage();

// 开始录制
await page.goto('https://example.com');

// 执行一些操作
await page.click('#login');
await page.fill('#username', 'testuser');
await page.fill('#password', 'password123');
await page.click('#submit');

// 等待重要操作完成
await page.waitForNavigation();

// 关闭context会自动保存视频
await context.close();

// 获取视频路径
const videoPath = await page.video().path();
console.log(视频已保存到: ${videoPath});

await browser.close();
})();
六、高级技巧与实战经验

  1. 截图对比测试
    const PixelDiff = require('pixel-diff');

asyncfunction compareScreenshots(page, baselinePath, diffPath) {
const currentPath = 'current.png';
await page.screenshot({ path: currentPath });

const diff = new PixelDiff({
imageAPath: baselinePath,
imageBPath: currentPath,
imageOutputPath: diffPath,
threshold: 0.1, // 允许的差异阈值
});

const result = await diff.run();
return result.differences < result.threshold; // 是否通过
}
2. 截图失败自动重试
async function robustScreenshot(page, options, maxRetries = 3) {
let lastError;

for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
await page.waitForTimeout(500 * attempt); // 递增等待
returnawait page.screenshot(options);
} catch (error) {
lastError = error;
console.log(截图尝试 ${attempt} 失败: ${error.message});

  if (attempt === maxRetries) {// 最后尝试:调整视口大小await page.setViewportSize({ width: 1280, height: 800 });await page.waitForTimeout(1000);returnawait page.screenshot(options);}
}

}

throw lastError;
}
3. 优化录屏文件大小
const context = await browser.newContext({
recordVideo: {
dir: 'videos/',
size: { width: 1280, height: 720 },
// 降低帧率减少文件大小
fps: 15,
}
});

// 只录制关键测试部分
await page.startRecording({ path: 'critical-path.webm' });
// ...关键操作
await page.stopRecording();
七、性能考量与最佳实践
内存管理:长时间运行截图任务时,定期清理缓存:

await page.evaluate(() => {
if (window.gc) window.gc(); // 仅限Chrome
});
并行处理:同时运行多个截图任务时,限制并发数避免内存溢出。

存储优化:

使用JPEG格式减小文件大小:{ type: 'jpeg', quality: 80 }
定期清理旧的截图和视频文件
考虑将文件上传到云存储
错误处理完整示例:

async function safeCapture(page, url, outputPath) {
try {
await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForSelector('body', { state: 'attached' });

// 检查页面是否正常加载
const pageTitle = await page.title();
if (!pageTitle || pageTitle.includes('Error')) {thrownewError(`页面加载异常: ${pageTitle}`);
}returnawait page.screenshot({ path: outputPath });

} catch (error) {
// 保存错误状态截图
const errorPath = outputPath.replace('.png', '-error.png');
await page.screenshot({ path: errorPath });

console.error(`截图失败 ${url}:`, error);
throw error;

}
}
结语
Playwright的截图和录屏功能看似简单,但在实际项目中需要综合考虑性能、稳定性和可维护性。我建议根据具体场景选择合适的策略:对于CI/CD环境,优先考虑速度和稳定性;对于调试和演示,则侧重功能的完整性和易用性。

最重要的是,建立适合自己项目的截图规范,包括命名规则、存储结构和比对机制,这样才能让这些功能真正提升开发效率,而不是成为维护负担。记住,好的工具使用习惯往往比工具本身更重要。

推荐学习
自动化智能体与测试用例生成课程,限时免费,机会难得。扫码报名,参与直播,希望您在这场课程中收获满满,开启智能自动化测试的新篇章!

image

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询