我正在开发一个项目,为基于 Drupal 的工具创建自动化测试。
我使用了赛普拉斯论坛上提供的解决方案:https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress
我观察到的一件有趣的事情是,前端使用了两种类型的 iframe。有些文档位于 contentDocument 对象内,而视频播放器 iframe 的文档对象位于 contentWindow 对象内。
我不得不编写两个函数来分别处理它们:
Cypress.Commands.add('getIframeBody', (locator) => {
cy.wait(1000)
return cy.get(`iframe${locator}`)
.its('0.contentDocument.body').should('not.be.empty')
.then(cy.wrap)
})
Cypress.Commands.add('getVideoPlayerBody', () => {
return cy.get('[title="Video Player"]')
.then(($iframe => {
const $body = $iframe[0].contentWindow.document.body
return cy.wrap($body)
}))
})
我正在寻找为什么会这样的解释,这只是一种开发风格还是实际上有一个目的/原因。
我不是专家,但
contentWindow
和 contentDocument
是 <iframe>
相当于 window
和 document
,正如您从命名中所期望的那样。
Window接口代表一个包含DOM文档的窗口; document 属性指向该窗口中加载的 DOM 文档
为了方便起见,
<iframe>
元素具有 contentWindow
和 contentDocument
这两个属性,但严格来说,层次结构如 MDN 链接中所述:
iframe.contentWindow.contentDocument.body
its('0...
中的“0”只是展开 jQuery 结果以获取原始 <iframe>
元素。
关于测试中的用法,我发现这取决于加载的复杂程度。
有时您需要先等待
contentWindow
,有时则需要 contentDocument
,具体取决于执行内容加载的脚本。
当通过 HTTP 获取实际内容时,您可能会看到初始静态“内容正在加载
message, which changes refreshes the
contentWindow”。