'xPath - Why is this exact text selector not working with the data test id?

I have a block of code like so:

<ul class="open-menu">
  <span>
    <li data-testid="menu-item" class="menu-item option">
      <svg>...</svg>
      <div>
        <strong>Text Here</strong>
        <small>...</small>
      </div>
    </li>

    <li data-testid="menu-item" class="menu-item option">
      <svg>...</svg>
      <div>
        <strong>Text</strong>
        <small>...</small>
      </div>
    </li>
  </span>
</ul>

I'm trying to select a menu item based on exact text like so in the dev tools:

$x('.//*[contains(@data-testid, "menu-item") and normalize-space() = "Text"]');

But this doesn't seem to be selecting the element. However, when I do:

$x('.//*[contains(@data-testid, "menu-item")]');

I can see both of the menu items.

UPDATE:

It seems that this works:

$x('.//*[contains(@class, "menu-item") and normalize-space() = "Text"]');

Not sure why using a class in this context works and not a data-testid. How can I get my xpath selector to work with my data-testid?



Solution 1:[1]

data-testid="menu-item" is matching both the outer li elements while text content you are looking for is inside the inner strong element.
So, to locate the outer li element based on it's data-testid attribute value and it's inner strong element text value you can use XPath expression like this:

//*[contains(@data-testid, "menu-item") and .//normalize-space() = "Text"]

Or

.//*[contains(@data-testid, "menu-item") and .//*[normalize-space() = "Text"]]

I have tested, both expressions are working correctly

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 Prophet