How can I select an element by exact text using Cypress?

602 views Asked by At

I have a table with a widget name column, followed by other columns with detail about the widgets.

I have a search function on the page to search for the widget that I want by name. When I search for a widget by name, for example, "abc", the rows returned are "abcde", "aabc", "abc".

My problem arises when I attempt to select the row that I want. Cypress .contains() always returns the first match, but I'd like the exact match.

I can't guarantee what order the rows will be in either. How can I select abc only?

cy.contains(`${widgetName}`)
1

There are 1 answers

0
Debella On

Yes cy.contains() only returns the first element, but you can switch to :contains() pseudo-selector to return all.

See :contains() Selector

Select all elements that contain the specified text.

I don't know why Cypress hasn't got an option for multiple matches in cy.contains() but :contains() works.


Scan all columns

You have flexibility to test all search results values. Here's a general way to scan the rows:

let exactMatchFound = false;

cy.get('table tbody tr')
  .filter(`:contains(${widgetName})`)
  .each($row => {
    const $firstCol = $row.find('td').eq(0);
    if ($firstCol.text() === 'abc') {
      exactMatchFound = true
    }
    // other column tests
  })
  .then(() => {
    expect(exactMatchFound).to.eq(true)
  })

Just the first column

If you just want to verify first column has abc, use :nth-child() Selector

let exactMatchFound = false;

cy.get('table tbody tr td:nth-child(1)')   // extract all 1st column cells
  .each($col1 => {
    if ($col1.text() === 'abc') {
      exactMatchFound = true
    }
  })
  .then(() => {
    expect(exactMatchFound).to.eq(true)
  })

or without looping

cy.get('table tbody tr td:nth-child(1)')   // extract all 1st column cells
  .contains(/^abc$/)                       // one of those has exact text
                                           // - but don't know which row