Reputation: 449
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]')
Upvotes: 1
Views: 1799
Reputation: 853
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.
Upvotes: 4
Reputation: 7164
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)...
Upvotes: 0
Reputation: 32118
The regex that applies is \[id="item\[\d+\].setupCost\]
.
Enclose the regex in forward slashes, not quotes.
cy.get(/\[id="item\[\d+\].setupCost\]/)
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) // ❌
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) // ✅
Upvotes: 6
Reputation: 18618
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)
})
Upvotes: 0