最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I bypass plaid iframe with Cypress.io? - Stack Overflow

programmeradmin1浏览0评论

I'm currently doing some automation, and I'm having trouble getting over the Plaid iframe. This how it looks inside of my app:

This how is setup inside of my app:

<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>

I'm getting the parent and the child elements, I'm looking by the text, and many other options and I'm unable to test this product. Does anyone has been working with plaid before?

I'm currently doing some automation, and I'm having trouble getting over the Plaid iframe. This how it looks inside of my app:

This how is setup inside of my app:

<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>

I'm getting the parent and the child elements, I'm looking by the text, and many other options and I'm unable to test this product. Does anyone has been working with plaid before?

Share Improve this question asked Mar 10, 2021 at 0:26 HvaandresHvaandres 1,0155 gold badges22 silver badges47 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

Using the Plaid demo page as a test app and following the steps in Working with iframes in Cypress, I managed to get a consistently working test.

From the blog, I used this sequence to ensure the iframe body has fully loaded

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

The page loads a placeholder first while is waits for a GET request to plete, so just getting a loaded iframe body is not sufficient.

placeholder

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

We need to wait for the "Continue" button, which takes a bit of time to show so give it a long timeout.

Using .contains('button', 'Continue', { timeout: 10000 }) actually returned two button, although there is only one visible.

I changed the button selector to use an id and all works consistently.

The test

cy.visit('https://plaid./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 mands 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()


})
  • You will have to do the call for your app link
  • You will have to add the following code:
describe('Plad Testing', () => {

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


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

        cy.visit('https://plaid./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 mands 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()


        })

    })

})

It could be possible that you get that you are not able to find the body of your iFrame. To solve this issue, we will need to add some configuration to the Cypress.json file:

{

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

}

  1. Chrome web security will prevent any CORS security from fire-up inside of the current test scenario that we have since you will have that 0.contentDocument.body will return null if the parent origin is different from the iframe origin. This will cause the CORS security issue!
  2. Page load time will help to slow loading the pages and have more time to process things
  3. Viewport will help to make the browser window render like a laptop screen
  4. Include shadow dom will make it easier to look for this type of element without including the "includeShadowDom" inside of your find() elements.

All of the other answers here use *.plaid. as the origin, which is why contentDocument is not null.

If you are testing this in the real world, you will be running a cross-origin iframe which causes contentDocument to be null a per the MDN page

Cypress is in the process of adding official iframe support, but until then you can use cypress-iframe which just worked for me out of the box.

My test

 it.only('users should be able to import holdings from their broker', () => {
    cy.visit('/portfolios/created');

    cy.findByText('Import from broker').click();

    cy.frameLoaded();

    cy.iframe().findByText('Continue').click();
  });
发布评论

评论列表(0)

  1. 暂无评论