cypress: Using .within() in custom commands/functions to return an inner DOM element found in .within() results in unexpected behavior
Current behavior
This command worked in 5.3, but in 5.4 when I chain a .type() command to it. It throws and error
Command:
Cypress.Commands.add('firstCellSearchFilter', () => {
cy.get('.ag-header-row-floating-filter').within(() => {
cy.get('.ag-header-cell')
.first()
.within(() => {
cy.get('.ag-text-field-input')
})
})
})
Error:
cy.type() can only be called on a single element. Your subject contained 3 elements.
Foo.firstCellSearchFilter().type('bar') fails because Foo.firstCellSearchFilter() returns ALL of the cy.get('.ag-text-field-input') elements. Its like the scope of cy.get('.ag-header-cell').first().within() gets reset or ignored
Desired behavior
I would expect the command to scope to the single input element, like it did in 5.3
Versions
Cypress: 5.4 Mac Mojave Chrome 86
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 4
- Comments: 25 (15 by maintainers)
Another example of unexpected behavior from https://github.com/cypress-io/cypress/issues/9064
@sainthkh I do agree that this is working as documented, but I think it may be helpful to think about how to provide the wanted behavior here. People want to traverse within some DOM and return the inner DOM element they’ve found, so that they can return it to be chained as a command/function.
So, either we can provide an example of how they can do this or we change the behavior of
.within()Maybe the scope of
.within()could change if there is areturnstatement, similar to how what is yielded from.then()changes based on thereturnstatement. (This is just me thinking out loud, I haven’t discussed this with the team).5.4.0
5.5.0
@sainthkh After discussing this with the team, we are most concerned about there being consistency among all of the commands and how they work. So,
.then()should work similarly to how.within()or.should()or any other command that accepts a function that includes other cypress comannds within it.So, we’d like to not see new rules made up specifically for
.within()- and make sure the logic matches more closely to how the other commands work.It is absolutely a bug. If its not then what is the point of within()? the within() is supposed to narrow the search scope. The BUG is the when you attach cy.get to an element that is being found in the within() is attaches the action, type() or click() to the element that was found at the top level within() scope instead of the element found in the within() scope.
referring to my original comment
So you’re telling me that the intended behavior of
Foo.firstCellSearchFilter().type()is to type or click on ‘ag-header-row-floating-filter’ (the outer scope) and not ag-text-field-input?This worked in 5.3 and broke in 5.4
It’s the intended behavior. Before 5.4,
cy.withinwas permanently narrowing scope for the following commands and it’s fixed in #8699.Here’re the workarounds: