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
相关产品推荐
相关产品推荐

