我在使用 Playwright 时遇到了一个问题,它截取了错误页面的屏幕截图。当通过 target="_blank"
链接打开新页面时,它不会截取最新页面,而是截取旧页面的屏幕截图。
我的应用程序的业务逻辑主要包含在一个 while 循环中,而且我没有使用 Playwright 进行测试。我尝试了两种方法来解决这个问题,但效果都不尽如人意。
方法 1:监听页面事件
我尝试监听上下文中的页面事件,并将新页面替换为当前页面。以下是代码:
let page = await context.newPage();
context.on("page", async (newPage) => {
await newPage.waitForLoadState();
page = newPage;
});
然而,这种方法似乎并不奏效,而且我也没有收到任何错误信息。
方法 2:从上下文中获取最新页面
我还尝试使用 context.pages()
从上下文中获取最新页面,然后将最新页面传递给 takeScreenshot
函数。以下是代码:
pages = await context.pages();
currentPage = pages[pages.length - 1];
const screenshot = await takeScreenshot(currentPage);
不幸的是,这种方法也行不通。
预期结果:
I want Playwright to takeScreenshot(currentPage).
我希望 Playwright 始终对最近打开的页面进行截图。有人能帮我解决这个问题吗?
代码片段:
以下是我的代码简化版本:
try {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
let page = await context.newPage();
await page.goto("https://somewebsite.com");
// let pages = context.pages();
// let currentPage = page;
while (/* 一些逻辑 */) {
try {
//...
const screenshot = await takeScreenshot(page);
//...
/// 一些逻辑
// ...
// context.on("page", async (newPage) => {
// await newPage.waitForLoadState();
// page = newPage
// });
// context.waitForEvent('page')
} catch (error) {
console.log(error);
}
}
catch (error) {
console.error("err:", error);
}
遇到的问题是,当点击带有 target="_blank"
的链接时,Playwright 不会自动将焦点切换到新页面。因此,需要手动告诉 Playwright 切换到新页面。
以下是可以尝试的解决方案:
方法 1:使用 page.waitForEvent('popup')
监听弹出窗口
try {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
let page = await context.newPage();
await page.goto("https://somewebsite.com");
while (/* 一些逻辑 */) {
try {
//...
// 点击打开新页面的链接之前,监听 'popup' 事件
const [newPage] = await Promise.all([
context.waitForEvent('popup'),
page.click('a[target="_blank"]') // 用的链接选择器替换
]);
// 将 page 变量更新为新页面
page = newPage;
// 等待新页面加载完成
await page.waitForLoadState();
// 现在可以对新页面进行截图
const screenshot = await page.screenshot();
//...
} catch (error) {
console.log(error);
}
}
} catch (error) {
console.error("err:", error);
}
方法 2:使用 context.pages()
查找新页面
try {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
let page = await context.newPage();
await page.goto("https://somewebsite.com");
while (/* 一些逻辑 */) {
try {
//...
// 获取当前页面数量
const initialPageCount = context.pages().length;
// 点击打开新页面的链接
await page.click('a[target="_blank"]'); // 用的链接选择器替换
// 等待新页面打开
await context.waitForEvent('page');
// 获取所有页面并找到新页面
const pages = context.pages();
const newPage = pages.find(p => !pages.slice(0, initialPageCount).includes(p));
// 将 page 变量更新为新页面
page = newPage;
// 等待新页面加载完成
await page.waitForLoadState();
// 现在可以对新页面进行截图
const screenshot = await page.screenshot();
//...
} catch (error) {
console.log(error);
}
}
} catch (error) {
console.error("err:", error);
}
这两种方法都可以解决遇到的问题。选择哪种方法取决于的个人偏好和具体情况。
一些额外的建议:
- 确保在截图之前等待新页面完全加载。
- 使用浏览器的开发者工具检查页面结构和链接选择器,以确保代码正确地定位到目标链接。
- 可以使用
console.log(page.url())
打印当前页面的 URL,以便调试代码并确保 Playwright 正确地切换页面。