'How can I user regex in cy.get()?
The application has list of items in a table and items have [id=item[0].setupCost, id=item[1].setupCost, id=item[2].setupCost] etc.
There's a functionality to add items also, so the index keeps on increasing.
I want to get input field regardless of using magic numbers. For eg (cy.get('[id=item[some_regex].setupCost]')
Solution 1:[1]
The regex that applies is \[id="item\[\d+\].setupCost\].
Enclose the regex in forward slashes, not quotes.
cy.get(/\[id="item\[\d+\].setupCost\]/)
But don't use it
This syntax is undocumented - it works (in Cypress v9.5.0) but it only returns one result.
So if you want to count your items, this will fail
cy.get(/\[id="item\[\d+\].setupCost\]/)
.its('length')
.should('eq', 3) // ?
Partial attribute selector
If you want to use partial attribute selectors, this is strongest as it includes .setupCost
Ref Find the element with id that starts with "local-" and ends with "-remote"
cy.get('[id^="item"][id$=".setupCost"]') // use "starts-with" and "ends-with" selectors
This succeeds with the count test
cy.get('[id^="item"][id$=".setupCost"]')
.its('length')
.should('eq', 3) // ?
Solution 2:[2]
You could create a custom Cypress command that would insert the index for you. Below, I'm assuming the id you're referencing is the ID of the element and is a standard CSS selector
Cypress.Commands.add('getItemById', (index) => {
return cy.get(`#item\\[${index}\\].setupCost`)
});
cy.getItemById(0)...
Solution 3:[3]
In case you need another answer:
You can use a regex if you add a jQuery extension.
It works because Cypress uses jQuery internally, and you can modify selector behavior by extending jQuery.
it('finds multiple ids by regex', () => {
const $ = Cypress.$
$.extend(
$.expr[':'], {
idRegex: function(a, i, m) {
const regex = new RegExp(m[3], 'i');
return regex.test(a.getAttribute('id'));
}
}
)
const regex = 'item\\[\\d+\\].setupCost'
cy.get(`input:idRegex(${regex})`)
.its('length')
.should('eq', 3) // ?
})
Put the jQuery extension in /cypress/support/index.js to use it globally.
Note in the regex we have to double-escaped because we pass in a string not a regex.
Solution 4:[4]
Instead of Regex you can use ^ with your selector. This denotes the start of the text. So you can write:
cy.get('[id^="item"]')
Now if you want to access any particular element you can use eq like this:
cy.get('[id^="item"]').eq(0) //gets id=item[0].setupCost
cy.get('[id^="item"]').eq(1) //gets id=item[1].setupCost
If you want to loop over each element you can use each()
cy.get('[id^="item"]').each(($ele) => {
cy.wrap($ele)
})
Solution 5:[5]
You can also apply a regex in a filter
const regex = /item\[\d+\].setupCost/;
cy.get('input')
.then($els => $els.filter((i,el) => {
return el.getAttribute('id').match(regex)
}))
.its('length')
.should('eq', 3)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | kegne |
| Solution 4 | |
| Solution 5 | Seeker |
