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

Cypress测试中如何显示PDF并继续执行测试?

Cypress旧版本PDF可视化测试优化方案(13.14.2-13.17.0)

重要前置说明

  • 该问题仅存在于旧版Cypress(13.14.2至13.17.0版本),Cypress 14已解决PDF页面加载超时问题,后续将更新正确方案。

需求

本文不涉及PDF解析或网页展示PDF的实现逻辑,核心目标是在Cypress测试过程中显示PDF,提供视觉反馈,方便测试失败(如未找到指定文本)时进行视觉验证。

当前问题

  • 直接用cy.visit访问PDF会报错,因为Cypress默认要求响应的content-type为text/html,而非application/pdf;
  • 通过cy.click点击PDF链接能显示PDF,但会触发超时错误(推测PDF加载未触发网页的page load事件)。尝试修改pageLoadTimeout并捕获fail事件,仍无法阻止测试终止,相关代码如下:
let pdfUrl = ""
cy.get(pdfSelector).as("pdfLink").invoke("attr", "target", "").invoke("attr", "href").then((href) => {
  pdfUrl = href
}).then(() => {
  Cypress.config("pageLoadTimeout", 500)
  Cypress.on("fail", () => {
    cy.request(pdfUrl).then(pdfContent => cy.log("FIXME never happens"))
  })
  cy.get("@pdfLink").click()
  cy.request(pdfUrl).then(pdfContent => cy.log("FIXME never happens"))
})

补充信息

触发PDF的链接由MailDev生成,代码如下:

<a target="" ng-href="foo.pdf" href="foo.pdf">
  <strong class="ng-binding">foo.pdf</strong>
</a>

## 优化实现方案

### 方案1:请求PDF后嵌入页面展示
绕过直接访问PDF的限制,先通过`cy.request`获取PDF内容,再嵌入到当前页面的iframe中,既避免`content-type`不匹配问题,也能触发页面加载事件防止超时:
```javascript
cy.get(pdfSelector).invoke("attr", "href").then(pdfUrl => {
  cy.request({
    url: pdfUrl,
    encoding: "base64"
  }).then(response => {
    const pdfBase64 = `data:application/pdf;base64,${response.body}`
    cy.window().then(win => {
      const iframe = win.document.createElement("iframe")
      iframe.src = pdfBase64
      iframe.style.width = "100%"
      iframe.style.height = "800px"
      win.document.body.appendChild(iframe)
    })
    cy.get("iframe").should("have.attr", "src", pdfBase64)
  })
})

方案2:自定义页面加载检测逻辑

临时修改超时时间,手动检测PDF阅读器是否加载完成(以Chrome内置阅读器为例):

cy.get(pdfSelector).invoke("attr", "href").then(pdfUrl => {
  const originalTimeout = Cypress.config("pageLoadTimeout")
  Cypress.config("pageLoadTimeout", 10000)
  
  cy.get(pdfSelector).click()
  cy.window().then(win => {
    return new Cypress.Promise(resolve => {
      const checkPDFLoaded = setInterval(() => {
        if (win.document.querySelector("embed[type='application/pdf']")) {
          clearInterval(checkPDFLoaded)
          resolve()
        }
      }, 500)
    })
  })
  
  Cypress.config("pageLoadTimeout", originalTimeout)
})

方案3:跳过页面加载等待

使用click的force选项结合窗口验证,直接确认PDF是否打开:

cy.get(pdfSelector).invoke("attr", "href").then(pdfUrl => {
  cy.get(pdfSelector).click({ force: true })
  cy.window().then(win => {
    expect(win.location.href).to.include(pdfUrl)
    cy.wait(2000) // 可选:等待PDF渲染完成
  })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:05:20