【问题标题】:How do I bypass plaid iframe with Cypress.io?如何使用 Cypress.io 绕过格子 iframe?
【发布时间】:2021-06-07 22:02:54
【问题描述】:

我目前正在执行一些自动化操作,但无法通过 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>

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

【问题讨论】:

    标签: javascript performance testing automation cypress


    【解决方案1】:

    使用Plaid demo page 作为测试应用程序并按照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()
    
    
    })
    

    【讨论】:

    • 您的代码似乎运行良好。但是,我有一个问题,如果我的 iframe 嵌入到我的 webApp 中,主体将来自我的应用程序而不是格子,对吗?我问的原因是我收到以下错误消息:```由于 contentDocument 属性导致超时错误,因为您将有一个空值。
    • 这是一条奇怪的信息 - 您使用的是旧版本的格子呢?要回答这个问题,您需要注意 iframe 中的主体而不是应用主体,这就是为什么我将 iframe->body 保存在别名中,然后使用 cy.get('@iframeBody') 而不仅仅是 cy.get() 重用它会给应用程序主体。
    • 但是您的测试在 .its('0.contentDocument.body') 失败 - iframe id 是否不同(#plaid-link-iframe-1 以外的其他内容)?您可以使用 devtools 检查并找到 iframe 元素,看看 id 是什么。请注意,应用中可能有多个 iframe。
    • 不,它是#plaid-link-iframe-1。这很有趣,因为如果我将这段代码作为一个单独的文件运行,我就能做到这一点。出于同样的原因,我认为这与我的网络应用程序有关
    • 我不明白“将此代码作为单个文件运行”?
    【解决方案2】:
    • 您必须调用您的应用链接
    • 您必须添加以下代码:
    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 安全在我们拥有的当前测试场景中启动,因为如果父源与 iframe 源不同,0.contentDocument.body 将返回 null。这将导致 CORS 安全问题!
    2. 页面加载时间有助于减慢页面加载速度并有更多时间处理事情
    3. 视口将有助于使浏览器窗口像笔记本电脑屏幕一样呈现
    4. 包含 shadow dom 可以更轻松地查找此类元素,而无需在 find() 元素中包含“includeShadowDom”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-12
      • 2022-08-16
      • 1970-01-01
      • 2021-09-23
      • 2018-09-19
      • 2012-05-06
      • 2016-12-29
      相关资源
      最近更新 更多