cypress-pipe
cypress-pipe copied to clipboard
Chaining cy.pipe is dangerous when yield element is removed
Hello,
I am using your library for some time now and I wanted to share about the fact that chaining cy.pipe
is bringing some flakiness too.
In your tests, I see that you are testing that if you chain cy.pipe
multiple time, the yield element is correctly transferred and the delayed child elements are correctly appended.
I think this is not really representing the reality when we are using a frontend framework that is removing adding dom element dynamically. As you can see on my branch, I am simulating that the yielding element is removed and recreated. In this use case, the test failed.
This is happening a lot when you want for example to access a table
, then the first row
then a cell
, ... if the first row is removed and recreated by the framework because of many reasons, your test is flaky.
I know it can be solved by chaining JQuery utils inside a unique cy.pipe()
but I feel the syntax is harder to read.
I was thinking about having a pipe
function that allows providing a list of functions instead of only one like this:
const getFirst = $el => $el.find('#first')
const getSecond = $el => $el.find('#second')
const getThird = $el => $el.find('#third')
const getFourth = $el => $el.find('#fourth')
const getFifth = $el => $el.find('#fifth')
const getText = $el => $el.text()
cy.get('body')
.pipe(getFirst, getSecond, getThird, getFourth, getFifth, getText).should('equal', 'foobar')
Then the entire list can be retried instead of chaining pipe. Having multiple pipe should be avoided IMO
What do you think?
For the moment, I created a small function like:
function $elPipe(...jQueryFns) {
return ($startingEl) => jQueryFns.reduce(($el, jQueryFn) => jQueryFn($el), $startingEl);
}
So in the test of my branch:
// THIS DOES NOT WORK
// cy.get('body')
// .pipe(getFirst)
// .pipe(getSecond) // Will resolve after a delay
// .pipe(getThird) // Will resolve after a delay
// .pipe(getFourth) // Will resolve after a delay
// .pipe(getFifth) // Will resolve after a delay
// .pipe(getText)
// .should('equal', 'foobar')
// THIS WORKS !
const getFifthText = $elPipe(getFirst, getSecond, getThird, getFourth, getFifth, getText);
cy.get('body').pipe(getFifthText).should('equal', 'foobar')