如何使用 Cypress.io 绕过格子 iframe?

How do I bypass plaid iframe with Cypress.io?

我目前正在做一些自动化,但我无法克服 Plaid iframe。这是它在我的应用程序内部的样子:

这是如何在我的应用程序内部设置的:

<div class="PaneActions PaneActions--no-padding-top"><button
        class="TextButton TextButton--is-action TextButton--is-threads-treatment TextButton--no-margin">
        <p class="FinePrint FinePrint--is-threads-treatment">By selecting “Continue” you agree to the <u>Plaid End User
                Privacy Policy</u></p>
    </button><button
        class="Touchable-module_resetButtonOrLink__hwe7O Touchable-module_block__WBbZm Touchable-module_wide__EYer3 Button-module_button__1yqRw Button-module_large__1nbMn Button-module_centered__3BGqS"
        id="aut-continue-button" type="button" role="button"><span class="Button-module_flex__2To5J"><span
                class="Button-module_text__38wV0">Continue</span></span></button></div>

我正在获取父元素和子元素,我正在查看文本和许多其他选项,但我无法测试该产品。有没有人以前用过格子呢?

使用 Plaid demo page as a test app and following the steps in Working with iframes in Cypress,我成功地获得了一个持续工作的测试。

从博客中,我使用此序列来确保 iframe 主体已完全加载

iframe -> body -> should.not.be.empty

页面首先加载占位符,同时等待 GET 请求完成,因此仅获取加载的 iframe 主体是不够的。

占位符

<p>iframe placeholder for https://cdn.plaid.com/link/v2/stable/link.html?isLinkInitialize=true&origin=https%3A%2F%2Fplaid.com&token=link-sandbox-170bce6a-fe90-44a4-8b8a-54064fbc8032&uniqueId=1&version=2.0.917</p>

我们需要等待“继续”按钮,这需要一些时间才能显示,所以请给它一个较长的超时时间。

使用.contains('button', 'Continue', { timeout: 10000 })实际上返回了两个按钮,虽然只有一个可见。

我将按钮选择器更改为使用一个 id,并且一切正常。

测试

cy.visit('https://plaid.com/demo/?countryCode=US&language=en&product=transactions');

cy.contains('button', 'Launch Demo').click()

cy.get('iframe#plaid-link-iframe-1', { timeout: 30000 }).then(iframe => {

  cy.wrap(iframe)                   // from Cypress blog ref above
  .its('0.contentDocument.body')
  .should('not.be.empty')           // ensure the iframe body is loaded
  .as('iframeBody')                 // save for further commands within iframe.body

  //.contains('button', 'Continue', { timeout: 10000 })     // returns 2 buttons!

  .find('button#aut-continue-button', { timeout: 10000 })   // this is the best selector

  .click()

  cy.get('@iframeBody')
    .contains('h1', 'Select your bank')  // confirm the result of the click()


})
  • 您必须为您的应用调用 link
  • 您必须添加以下代码:
describe('Plad Testing', () => {

    it('Request Loan', () => {


        //cy.find('Button-module_large__1nbMn', [0], { timeout: 10000 }).click()

        cy.visit('https://plaid.com/demo/?countryCode=US&language=en&product=transactions');

        cy.contains('button', 'Launch Demo').click()

        cy.get('iframe#plaid-link-iframe-1', { timeout: 30000 }).then(iframe => {

            let plaid = cy.wrap(iframe)
            plaid                   // from Cypress blog ref above
                .its('0.contentDocument.body')
                .should('not.be.empty')           // ensure the iframe body is loaded
                .as('iframeBody')                 // save for further commands within iframe.body

                //.contains('button', 'Continue', { timeout: 10000 })     // returns 2 buttons!

                .find('button#aut-continue-button', { timeout: 10000 })   // this is the best selector

                .click()

            let plaid_choose_bank = cy.get('@iframeBody')
            plaid_choose_bank
                .contains('h1', 'Select your bank')  // confirm the result of the click()
                .xpath('/html/body/reach-portal/div[3]/div/div/div/div/div/div/div[2]/div[2]/div[2]/div/ul/li[1]/button/div/div[2]/p[1]').click()
            let plaid_bank_username = cy.get('@iframeBody')
            plaid_bank_username
                .find('input[name="username"]').type('user_good', { delay: 100 })
            let plaid_bank_password = cy.get('@iframeBody')
            plaid_bank_password
                .find('input[name="password"]').type('pass_good', { delay: 100 })
            let plaid_bank_button = cy.get('@iframeBody')
            plaid_bank_button
                .find('button#aut-submit-button').click()


        })

    })

})

您可能会发现找不到 iFrame 的主体。要解决这个问题,我们需要在 Cypress.json 文件中添加一些配置:

{

"chromeWebSecurity": false,
"pageLoadTimeout": 300000,
"viewportWidth": 1536,
"viewportHeight": 960,
"includeShadowDom": true,

}

  1. Chrome 网络安全性将阻止任何 CORS 安全性在我们当前的测试场景中启动,因为如果父级 0.contentDocument.body 将 return null origin 与 iframe origin 不同。这将导致 CORS 安全问题!
  2. 页面加载时间将有助于减慢页面加载速度并有更多时间处理事情
  3. Viewport 将有助于使浏览器window像笔记本电脑屏幕一样呈现
  4. 包含影子 dom 可以更轻松地查找此类元素,而无需在 find() 元素中包含“includeShadowDom”。