Search code examples
filtercypresscontains

Cypress: is there a way to use filter with a regex?


Click here to view the html

With the html above, I need to get the 3rd mfc-tree-item based on the mfc-text-type text of the second mfc-tree-item, in other words, I need to click on the mfc-tree-item[data-qa-id='fma-tree-nav-headcount-planning-component'] that is within the mfc-tree-item[data-qa-id='fma-tree-nav-scenario'] which mfc-text-type's text equal to "Baseline" (contains is not enough). So I was thinking I could use a regex with ^ at the beginning and $ at the end of Baseline, but not sure if that's even supported. Any idea?

scenarioName = 'Baseline'
cy.get('mfc-tree-item[data-qa-id="fma-tree-nav-scenario"]')
  .filter(':contains("^"' + scenarioName + '"$", "g")')
  .find(mfc-tree-item[data-qa-id='fma-tree-nav-headcount-planning-component'])

Solution

  • To use a regex with text from a variable, you would need to build it with a RexExp object.

    const scenarioName = 'Baseline'
    const regex = new RegExp(scenarioName)
    cy.contains('mfc-tree-item[data-qa-id="fma-tree-nav-scenario"]', regex)
      .find('mfc-tree-item[data-qa-id="fma-tree-nav-headcount-planning-component"]')
      .should('have.attr', 'icon-color', 'Moonstone')
    

    But you can't use ^ and $ to denote beginning and end of string, because the text of the top element includes all the text of it's children plus white-space and new lines (text nodes).

    You could try strengthening the regex, but it would be time consuming and give you a fragile test.

    Instead, try going directly to the element with the text, which allows a strong regex, and traverse up the tree to it's ancestor

    const scenarioName = 'Baseline'
    const regex2 = new RegExp(`^${scenarioName}$`)
    cy.contains('mfc-text-type', regex2)
      .parents('mfc-tree-item[data-qa-id="fma-tree-nav-scenario"]')
      .find('mfc-tree-item[data-qa-id="fma-tree-nav-headcount-planning-component"]')
      .should('have.attr', 'icon-color', 'Moonstone')