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

Chrome无头模式下Protractor测试新标签页加载异常排查

无头Chrome下PDF测试失败?这几个坑得踩对!

嘿,我之前也碰到过一模一样的问题!正常模式下跑好好的,无头模式就掉链子,核心原因是无头Chrome对PDF的默认处理逻辑和正常模式完全不同,再加上你的测试代码里有几个不够健壮的地方,才导致了这个问题。

先回顾下你的场景:点击打印生成PDF新标签页,切换后检查URL,正常模式稳,无头模式下URL一直没加载,测试卡壳。

问题到底出在哪?

  • 无头模式默认不加载PDF预览:正常Chrome会自动渲染PDF,但无头模式默认只是打开空白标签页,不会触发PDF的加载/渲染流程,所以你切换过去后URL根本不会更新。
  • 硬编码sleep太不靠谱:browser.sleep(18000)完全靠碰运气,无头模式下资源加载时序和正常模式不一样,哪怕等18秒也可能赶不上,而且如果加载快了还浪费时间。
  • 窗口切换逻辑有风险:handles[1]不一定是新打开的标签页,如果之前有其他残留的标签页,你切换的窗口根本不对。
  • 没有显式等待页面就绪:切换窗口后直接拿URL,此时页面可能还处于初始化状态,自然拿不到目标URL。

一步步解决问题

1. 给无头Chrome加PDF支持参数

启动Chrome时必须加特定参数,让它在无头模式下能处理PDF:

// 你的Chrome配置需要改成这样
const chromeOptions = {
  args: [
    '--headless=new', // 新版Chrome推荐用这个,旧版用--headless
    '--disable-gpu',
    '--print-to-pdf', // 关键:启用PDF打印/预览支持
    '--no-sandbox',
    '--disable-dev-shm-usage',
    '--enable-features=NetworkService,NetworkServiceInProcess'
  ]
};

// 把配置传入浏览器构建器
const browser = await webdriver.Builder()
  .forBrowser('chrome')
  .setChromeOptions(chromeOptions)
  .build();

如果是Chrome 112以下版本,把--headless=new换成--headless,再加--disable-web-security辅助解决资源加载问题

2. 把硬编码sleep换成显式等待

永远不要用固定时长的sleep!改用Protractor的ExpectedConditions等待URL加载完成:

const EC = protractor.ExpectedConditions;
// 等待URL包含目标路径,超时时间20秒
await browser.wait(EC.urlContains(mUrl), 20000, 'PDF页面超过20秒仍未加载');

如果PDF页面有可见的元素(比如预览容器),也可以等待元素出现:

await browser.wait(EC.presenceOf(element(by.css('embed[src*=".pdf"]'))), 20000);

3. 优化窗口切换逻辑,精准找到新标签页

之前用handles[1]太草率,应该对比切换前后的窗口handle,精准定位新打开的标签页:

// 点击打印前先保存原窗口的handle
const originalHandle = await browser.getWindowHandle();
await mTherapyReportView.btnPrintform.click();

// 等待新窗口出现,最多等10秒
await browser.wait(async () => {
  const handles = await browser.getAllWindowHandles();
  return handles.length > 1;
}, 10000, '新标签页10秒内未打开');

// 找到和原窗口不同的那个handle,就是新标签页
const handles = await browser.getAllWindowHandles();
const newHandle = handles.find(handle => handle !== originalHandle);
await browser.switchTo().window(newHandle);

4. 给关闭标签页加容错处理

万一关闭标签页出错,也要确保切回原窗口,避免整个测试套件中断:

try {
  await browser.close();
} catch (err) {
  console.warn('关闭PDF标签页时出错了:', err);
} finally {
  // 不管怎样都切回原窗口
  await browser.switchTo().window(originalHandle);
}

优化后的完整测试代码

it("should open document as PDF-file in new browser-tab", async () => { 
  const mUrl = "TherapyReportForm/Export"; 
  // 保存原窗口handle
  const originalHandle = await browser.getWindowHandle();

  // 点击打印按钮
  await mTherapyReportView.btnPrintform.click();

  // 等待新窗口出现并切换过去
  await browser.wait(async () => {
    const handles = await browser.getAllWindowHandles();
    return handles.length > 1;
  }, 10000, '新标签页未在指定时间内打开');
  
  const handles = await browser.getAllWindowHandles();
  const newHandle = handles.find(handle => handle !== originalHandle);
  await browser.switchTo().window(newHandle);

  // 显式等待URL加载完成
  const EC = protractor.ExpectedConditions;
  await browser.wait(EC.urlContains(mUrl), 20000, 'PDF页面URL未在指定时间内匹配');
  expect(await browser.getCurrentUrl()).toContain(mUrl);

  // 关闭新标签页并切回原窗口,加容错
  try {
    await browser.close();
  } catch (err) {
    console.warn('关闭PDF标签页失败:', err);
  } finally {
    await browser.switchTo().window(originalHandle);
  }
});

内容的提问来源于stack exchange,提问作者Jan and RESTless

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 10:27:37