0

Most of my existing codebase uses a 'id' only in few places 'data-testId' attribute present. tried this code

import { configure } from '@testing-library/cypress';

configure({ testIdAttribute: ['data-testId','id'] });

But, still its not working.

Is there any way to use 'id' value in any of the testing-library functions.

My HTML code is something like:

<div class="some random class name" id="userprofile-open" role="button">SB</div>

I want click that element with this code:

cy.findByTestId("userprofile-open", { timeout: 120000 }).click();
juliomalves
  • 42,130
  • 20
  • 150
  • 146
imBollaveni
  • 99
  • 1
  • 13
  • 1
    Pls elaborate - you want to change the properties on the elements or to be able to select them? Would be helpful if you share an HTML code of such element= – Rosen Mihaylov May 26 '21 at 12:05
  • my HTML code is something like:
    SB
    Then , I want click that element with below code: cy.findByTestId("userprofile-open", { timeout: 120000 }).click();
    – imBollaveni May 26 '21 at 12:08
  • 1
    Good that information is better - for further questions - you need to include such things if you want people to help you. We cant help if we cant see the problem and the code. Also you can edit your question to include it. – Rosen Mihaylov May 26 '21 at 12:20

2 Answers2

1

I don't think you can configure testing-library with an array of ids, ref API configuration,

import { configure } from '@testing-library/cypress'
configure({ testIdAttribute: 'id' })

But even this fails. Instead you have to use the Cypress command to change the attribute name (only one name is allowed).

cy.configureCypressTestingLibrary({ testIdAttribute: 'id' })

To use either/or attribute name you can change the attribute name on the fly, wrapping it in a custom command (based on Custom Queries)

Cypress.Commands.add('findByTestIdOrId', (idToFind) => {
  
  let result;

  const { queryHelpers } = require('@testing-library/dom');
  let queryAllByTestId = queryHelpers.queryAllByAttribute.bind(null, 'data-testId');

  result = queryAllByTestId(Cypress.$('body')[0], idToFind)
  if (result.length) return result;

  queryAllByTestId = queryHelpers.queryAllByAttribute.bind(null, 'id');
  result = queryAllByTestId(Cypress.$('body')[0], idToFind);
  if (result.length) return result;

  throw `Unable to find an element by: [data-test-id="${idToFind}"] or [id="${idToFind}"]`

})

cy.findByTestIdOrId('my-id')
  .should('have.attr', 'id', 'my-id')  
// passes and logs "expected <div#my-id> to have attribute id with the value my-id"

Note this custom command works only for synchronous DOM.


If you need to have Cypress retry and search for either/or attribute, don't use testing-library in the custom command.

Instead use Cypress .should() to enable retry

Cypress.Commands.add('findByTestIdOrId', (selector, idToFind) => {
  cy.get(selector)
    .should('satisfy', $els => {
      const attrs = [...$els].reduce((acc, el) => {
        const id = el.id || el.getAttribute('data-test-id')  // either/or attribute
        if (id) {
          acc.push(id)
        }
        return acc
      }, [])
      return attrs.some(attr => attr === idToFind); // retries when false
    })
    .first();                                       // may be more than one
})

cy.findByTestIdOrId('div', 'my-id')
  .should('have.attr', 'id', 'my-id')  
// passes and logs "expected <div#my-id> to have attribute id with the value my-id"
0

The usual cypress way - which has an inherent check on the element visibility and existence as well as included retries for a period of time is using cy.get()

If you want to select element using property like data-id you need this sintax: cy.get('[propertyName="propertyValue"]')

If you want select an element by CSS selector you just pass CSS selector like this: cy.get('#id')

Rosen Mihaylov
  • 1,363
  • 2
  • 10
  • yes I know cy.get(#id) works. But, to maintain the uniform locating mechanism across the framework we want use Cypress Testing Library methods only(like findByRole, findByText, etc...) Refer: https://testing-library.com/docs/cypress-testing-library/intro – imBollaveni May 26 '21 at 12:29
  • I only found this git repo with examples. May be it will help you. https://github.com/testing-library/cypress-testing-library/blob/main/cypress/integration/find.spec.js I haven`t used that library – Rosen Mihaylov May 26 '21 at 12:39