Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getBy* with .should('not.exist') #30

Closed
alexkrolick opened this issue Jan 9, 2019 · 7 comments
Closed

getBy* with .should('not.exist') #30

alexkrolick opened this issue Jan 9, 2019 · 7 comments

Comments

@alexkrolick
Copy link
Contributor

alexkrolick commented Jan 9, 2019

The behavior of cypress-testing-library's getBy queries is a bit different than the cypress built-in .get() method: the built-in will retry should('not.exist') until it times out, but the getBy queries timeout on the query. One workaround is to change to getBy to queryBy, but this requires a little bit of extra dom-testing-library knowledge that can confuse people coming from Cypress, and still doesn't retry.

Alternative

// This doesn't work
cy.getByTestId('my-item').should('not.exist');

// This works for verifying an element isn't present *right now*
cy.queryByTestId('my-item').should('be.null');

// This should retry but does not
cy.queryByTestId('my-item').should('not.exist');

Idea

It might make sense for queryBy* to actually be aliased to getBy* in the cypress context?

EDIT: actually the .should() chain should really trigger a retry of the parent command. Maybe custom commands don't hook into .should correctly?

Related to #23, cypress-io/cypress#3109

@kentcdodds
Copy link
Member

Hmmm... this test as an assertion that an element does not exist and it works (even without the timeout argument. The timeout arg is there because otherwise Cypress will wait a full 4 seconds to make sure the element doesn't appear).

Am I missing something? Probably...

@alexkrolick
Copy link
Contributor Author

alexkrolick commented Jan 10, 2019

it works if the should passes immediately after the query returns, but not if it is present and disappears (eg the query finds the element and cypress goes to call .should() with it - it won't attempt to retry the query itself if that expectation fails)

@kentcdodds
Copy link
Member

Oh right, that makes sense. A workaround would be to wait but that's a terrible workaround. Ok, so there are changes that need to happen in Cypress to allow us to do this then?

@alexkrolick
Copy link
Contributor Author

I'm thinking Cypress should support hooking into the retry mechanism for custom commands. Filed an issue to discuss: cypress-io/cypress#3109

@kentcdodds
Copy link
Member

Super, thanks!

@alexkrolick
Copy link
Contributor Author

alexkrolick commented Jan 10, 2019

It might be theoretically possible to emulate the get behavior more closely by copying some of the implementation from here: https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/cy/commands/querying.coffee, assuming this Commands.addAll method is accessible

The magic appears to be in this implicit "should('exist')" that yields retry control to the next assertion if it is defined https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/cy/commands/querying.coffee#L339-L348

Instead of waitForElement: https://github.com/kentcdodds/cypress-testing-library/blob/master/src/index.js#L24

This action could be dispatched "cy:command:retry"/cy.retry: https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/cy/retries.coffee#L90 EDIT: this might just be for logging; looks like a lot of other retry++ stuff is going on

cc @bahmutov

@kentcdodds
Copy link
Member

I'd be fine if anyone wants to try to make that happen. Then we can switch over to a built-in API when it becomes available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants