How to use an XPath or CSS selector to look for a substring in Nightwatch testing
Asked 07 September, 2021
Viewed 1.5K times
  • 56
Votes

I'm having to do Nightwatch testing on the following element:

<textarea id="xxxxxxxx-971-condition" 
   type="text" placeholder="Enter condition" 
   required="required" aria-required="true" class="form-control">

This is basically easy, except that i've found out the "-971-" is more or less a random 3-digit number since the textarea can show up multiple times on the page. I cannot simply look for "starts-with('xxxxxxxx-')" because there are lots of other form fields that share that prefix. I cannot use "ends-with('-condition')" more or less for the same reason. I need to combine the two. But how? Here's what I've tried, first starting with the simple case:

browser
  .useXpath() // every selector now must be xpath
  .assert.visible("//textarea[ends-with(@id,'-condition')]") FAILS!
  .assert.visible("//textarea[@id[ends-with(text(),'-condition')]]") FAILS!
  .assert.visible("//textarea[@id=[ends-with(text(),'-condition')]]") FAILS!
  .assert.visible("//textarea[contains(@id, starts-with(text(),'xxxxxxxx-') and ends-with(text(),'-condition'))]") FAILS!
  .assert.visible("//textarea[contains(@id, starts-with(text(),'xxxxxxxx-'))]") FAILS!
  .assert.visible("//textarea[contains(@id, ends-with(text(),'-condition'))]") FAILS!
  .assert.visible("//id[contains(., ends-with(text(),'-condition'))]") FAILS!
  .assert.visible("//textarea[@id[contains(., ends-with(text(),'-condition'))]]") FAILS!
  .assert.visible("//textarea[@id[contains(., starts-with(text(),'xxxxxxxx-'))]]") FAILS!

  .useCss() // we're back to CSS now
  .assert.visible("textarea[id^='xxxxxxxx-']")  <==== THIS WORKS!!!!
  .assert.visible("textarea[id$='-condition']")  <==== THIS WORKS!!!!
  .assert.visible("textarea[id^='xxxxxxxx-' and id$='-condition']") <==== together this does NOT work

Since the test runs for quite some time before it get to this section, I have had lots of time to google. Also you will notice that I'm having much more luck using CSS Selectors (but am unable to combine them to the effect I require).

Anyone have a suggestion?

1 Answer