简体   繁体   中英

How to check if element is never visible in Cypress e2e testing?

Is there any way to assert that an element is never visible at any point when routing within Cypress?

I have a server-rendered web app that is sometimes showing a "loading" state when it shouldn't. So when I navigate between pages, a "loading" indicator is showing for a few seconds and then disappearing.

I know that Cypress's assertions will sometimes "wait", but in this case it's causing my assertion to fail because the loading indicator goes away and that makes the test think that it has passed.

I'm using these two assertions:

cy.get('[data-test="loading"]').should('not.exist');

cy.get('[data-test="loading"]').should('not.be.visible');

But both of them are passing because the loading indicator goes away.

I've checked through all the documentation but there doesn't seem to be some kind of method for checking that an element is never visible. Is there some method I'm missing or some hack to test this a different way?

I might be crazy, and i have not tested this yet, but I wanted to throw this out there

I assume you are testing that there should NEVER be a loading indicator and it is waiting the default 4 seconds and the indicator goes away, and thus your test pass. So below I set the wait to zero, so it does not wait. I am also confused as to why you don't fix the actual code so you don't see the indicator if you are not supposed to. Perhaps you don't have access to the code..

cy.get('[data-test="loading"]',{ timeout: 0 }).should('not.exist');

cy.get('[data-test="loading"]',{ timeout: 0 }).should('not.be.visible');

Cypress has a lite version of jQuery, so we can watch for changes to the parent of the element that should not exist.

@Maccurt's tests are applied whenever a change occurs.

You want to keep watch firing to a minimum, so find the immediate (or nearest) parent of tested element.

Note this covers exists tests, but should not be necessary for visible tests if the element is present all the time but is just not visible.


In this example a button is added to body .
The first test watches for a span (which is never added so the test succeeds).
The 2nd test watches for the button and fails.

describe('watching for an element to not appear', () => {

  const watchAndTest = function(parentSelector, assert) {
    Cypress.$(parentSelector).bind('DOMNodeInserted', function(event) {
      assert()
    });
  }

  it('should succeed because "span" does not exist', () => {
    const parentSelector = 'body'
    const watchForSelector = 'span'
    watchAndTest(parentSelector, 
      () => {
        // Place your 'assert' code here
        cy.get(`${parentSelector} ${watchForSelector}`,{ timeout: 0 })
          .should('not.exist');
      }
    )

    // Place your 'act' code here
    cy.get(parentSelector).then(parent => {
      var newElement = document.createElement('button');
      parent[0].appendChild(newElement)
    })
    Cypress.$(parentSelector).unbind('DOMNodeInserted')
  })

  it('should fail because "button" exists', () => {
    const parentSelector = 'body'
    const watchForSelector = 'button'
    watchAndTest(parentSelector, 
      () => {
        // Place your 'assert' code here
        cy.get(`${parentSelector} ${watchForSelector}`,{ timeout: 0 })
          .should('not.exist');
      }
    )

    // Place your 'act' code here
    cy.get(parentSelector).then(parent => {
      var newElement = document.createElement('button');
      parent[0].appendChild(newElement)
    })
    Cypress.$(parentSelector).unbind('DOMNodeInserted')
  })

})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM