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

javascript - Cypress - how to wait for second of two elements to appear? - Stack Overflow

programmeradmin1浏览0评论

I want to wait until the second of two elements to appear before performing an action on it. Currently, I have this:

    cy.get('[data-test="insert-item"]').click();
    cy.get('[data-test="textarea"]').eq(1).type('Hello').type('{enter}');

This currently fails. I'm assuming this is because Cypress is going to collect all the occurrences of textarea, then try to select the second one before it has actually rendered on the page (because of the async request that creates it). If I add cy.wait(2000); in between these two lines it passes.

Is there any way to do this without using cy.wait(2000), so that it specifically waits until the second item has appeared?

I want to wait until the second of two elements to appear before performing an action on it. Currently, I have this:

    cy.get('[data-test="insert-item"]').click();
    cy.get('[data-test="textarea"]').eq(1).type('Hello').type('{enter}');

This currently fails. I'm assuming this is because Cypress is going to collect all the occurrences of textarea, then try to select the second one before it has actually rendered on the page (because of the async request that creates it). If I add cy.wait(2000); in between these two lines it passes.

Is there any way to do this without using cy.wait(2000), so that it specifically waits until the second item has appeared?

Share Improve this question edited Nov 26, 2020 at 9:19 Anatoly 22.9k3 gold badges32 silver badges46 bronze badges asked Nov 21, 2020 at 12:59 JoeTideeJoeTidee 26.2k29 gold badges113 silver badges163 bronze badges 4
  • One way would be to wait till the XHR request associated is executed by using cy.route(), something like cy.server() cy.route('**/posts/**').as('getSomething') cy.wait('@getSomething'). You can find more info on the same here - docs.cypress.io/api/mands/route.html#Syntax – Alapan Das Commented Nov 21, 2020 at 15:24
  • Thanks for the suggestion, but this is just waiting for the XHR response, not the appearance of the second element. – JoeTidee Commented Nov 21, 2020 at 15:41
  • May be you can try either one of them for the appearance of the second element and see if it works - cy.get('[data-test="textarea"]').eq(1).should('be.visible') OR cy.get('[data-test="textarea"]').eq(1).should('exist'). – Alapan Das Commented Nov 21, 2020 at 15:46
  • 1 Thats not going to work either, as Cypress would have already assessed the number of textarea before the second one has appeared. Is there a way to wait a certain amount of time for the condition to be true? – JoeTidee Commented Nov 21, 2020 at 21:26
Add a ment  | 

1 Answer 1

Reset to default 6

You can move the eq() into the selector with :nth(1), which will cause the indexing to be part of the cy.get() retry mechanism

cy.get('[data-test="textarea"]:nth(1)')
  .type('Hello').type('{enter}')

Or you can assert the length of the elements selected before indexing the list.

cy.get('[data-test="textarea"]')
  .should('have.length', 2)
  .eq(1)
  .type('Hello').type('{enter}')

Demo

/// <reference types="@cypress/fiddle" />

const waitForAdd = {
  html: `
    <div id="parent">
      <textarea data-test="textarea">1</textarea>
      <button data-test="insert-item" onclick = "myFunction()"></button>
    </div>
    <script>
      const myFunction = () => {
        setTimeout(() => {
          const parent = document.querySelector('div#parent');
          let ta = document.createElement("textarea");
          ta.setAttribute('data-test', 'textarea');
          parent.appendChild(ta);
        }, 500)
      }
    </script>
  `,
  test: `
    cy.get('[data-test="insert-item"]').click();
    cy.get('[data-test="textarea"]:nth(1)')
      .type('Hello').type('{enter}')
    cy.get('[data-test="textarea"]:nth(1)')
      .invoke('val')
      .should('eq', 'Hello\\n')

    cy.get('[data-test="insert-item"]').click();
    cy.get('[data-test="textarea"]')
      .should('have.length', 3)
      .eq(2)
      .type('Hello again').type('{enter}')
    cy.get('[data-test="textarea"]')
      .eq(2)
      .invoke('val')
      .should('eq', 'Hello again\\n')
`
}
it('tests hello', () => {
  cy.runExample(waitForAdd)
})
发布评论

评论列表(0)

  1. 暂无评论