Exploring the power of the cssContainingText locator feature in Protractor

Currently working on a framework utilizing Protractor, I encountered an issue with the cssContainingText locator from the Protractor API. The locator threw an invalidElement exception, which puzzled me.

The structure of the HTML page appears as follows:

<tbody>
    <tr class="row2">
         <td class="action-checkbox">...</td>
         <th class="field-name">
             <a href="some_link">someText</a>
         </th>
         <td class="field-slug">sometext</td>
    </tr>   
    <tr class="row3">
         <td class="action-checkbox">...</td>
         <th class="field-name">
             <a href="some_link">someOtherText</a>
         </th>
         <td class="field-slug">someothertext</td>
    </tr>
    <tr class="row4">...</tr>
         <td class="action-checkbox">...</td>
         <th class="field-name">
             <a href="some_link">someThirdText</a>
         </th>
         <td class="field-slug">somethirdtext</td>
    </tr>

My attempt to use the text someText with the following locator failed:

element(by.cssContainingText('.field-name','someText'));
, throwing an InvalidLocator exception. However, using
element(by.cssContainingText('a','someText'))
works perfectly fine.

After reviewing explanations in this source and examining the Protractor implementation detailed here, it appears that cssContainingText first locates elements using the CSS Selector and then matches the desired text.

It should be correct to use the .field-name class name for the CSS Selector and match the desired string, but this approach fails inexplicably. Any insights on this matter would be appreciated.

Answer №1

If you want to see the code and track it on GitHub, you can start by checking out the API documentation of cssContainingText.

The method used to search for content in clientsidescripts.js is as follows:

var elementText = element.textContent || element.innerText || '';

if (elementText.indexOf(searchText) > -1) {
    matches.push(element);
}

Since the indexOf() function requires an exact match and your th element does not have either innerText or textContent (but your <a> tag does), using the th element will not give you the desired result.

To understand the differences between textContent and innerText, you can refer to this StackOverflow answer and this one as well.

For your specific case:

[textContent]
someText
[/textContent]
[innerText]someText[/innerText]

var properties = ['innerHTML', 'innerText', 'textContent', 'value'];

// Writes to textarea#output and console
function log(obj) {
  console.log(obj);
  var currValue = document.getElementById('output').value;
  document.getElementById('output').value = (currValue ? currValue + '\n' : '') + obj; 
}

// Logs property as [propName]value[/propertyName]
function logProperty(obj, property) {
  var value = obj[property];
  log('[' + property + ']'  +  value + '[/' + property + ']');
}

// Main
log('=============== ' + properties.join(' ') + ' ===============');
for (var i = 0; i < properties.length; i++) {
  logProperty(document.getElementById('test'), properties[i]);
}
<div id="test">
  Warning: This element contains <code>code</code> and <strong>strong language</strong> and <a href="www.google.com">a Google link</a>.
</div>
<textarea id="output" rows="12" cols="80" style="font-family: monospace;"></textarea>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I need help figuring out how to mention an id using a concatenated variable in the jquery appendTo() method

Using jQuery, I am adding HTML code to a div. One part of this code involves referencing a div's ID by concatenating a variable from a loop. $(... + '<div class="recommendations filter" id="recCards-'+ i +'">' + &apo ...

How can items be categorized by their color, size, and design?

[{ boxNoFrom: 1, boxs: [{…}], color: "ESPRESSO", size: "2X", style: "ZIP UP" { boxNoFrom: 13, boxs: [{…}], color: "ESPRESSO", size: "2X", style: "ZIP UP" }, { boxNoFrom: ...

Iterate through a intricate array of JavaScript objects to extract their values

Looking for ways to extract total calorie and nutrition information from a large document displaying the nutritional data of a simulated recipe. Please review the codesandbox json file first. The objective is to capture the total calories and nutritive c ...

How to execute a function *after* another function has finished running in Javascript upon page load?

I am currently using scrollsaver.js to maintain scroll positions of elements after postback. However, I have encountered difficulties in resetting the scroll position when needed. Specifically, when paging through a list, I want the scroll position to res ...

Error message: Unable to access property 'string' as it is undefined | React.PropTypes | LayoutPropTypes.js

Recently, I deleted and reinstalled my node_modules folder, and now I'm encountering a perplexing issue in the LayoutPropTypes.js file. Within node_modules/react-native/Libraries/StyleSheet/LayoutPropTypes.js, I'm noticing that the variable var ...

Error: The function `map` cannot be applied to this.props.comments

I am new to coding in React and have been trying to create a comment box. However, I keep encountering errors such as TypeError: this.props.comments.map is not a function and Uncaught TypeError: comments.concat is not a function. I am feeling lost and conf ...

Implement varying styles in React components

In my React project, I am attempting to create a unique progress bar with custom styling. Specifically, I have a dynamically calculated percentage that I want to assign as the width of a div element. Initially, I tried achieving this using Tailwind CSS: &l ...

Error: The script is unable to access the property "div" because it is undefined

I keep encountering this issue "Cannot read property 'div' of undefined" This is the snippet in question function validateData(){ for(let j = 0; j < 13; j++){ if(dataArr[j].data.textContent === resultSet[j].result.div. ...

Guide to obtaining ngPrime autocomplete text when the button is clicked within Angular 6

I am currently utilizing the ngPrime autocomplete feature to retrieve data from a service. My goal is to capture the text entered in the autocomplete field whenever a button is clicked. I attempted to access the value using getElementById.value within th ...

What is the most effective method for generating dial images through programming?

Currently, I am in the process of creating a website that makes use of variously sized and styled dials to indicate progress. The filled portion of the dial represents how close an item is to being 100% complete. I am seeking a universal solution that wil ...

fresh map from Google: Coordinates LatLng may not be a number, but my hunch tells me it is

Seeking Assistance with this Issue - For example, the initial location data appears as: "Object Lat: -36.768498 Lng: 174.75895" However, an error is indicating that the latitude is not recognized as a number. Rather than making adjustments without clea ...

Webpack is failing to load the logo PNG image file

Is there a way to make the logo png file visible on the webpage? I have been encountering issues with loading the image while other elements like HTML, css, and fonts are loading properly when the web pack is started. List of Error Messages: Refused to a ...

ESLint and Prettier are butting heads when trying to run their commands consecutively

My package.json file includes two commands: "format": "prettier --write \"{src,{tests,mocks}}/**/*.{js,ts,vue}\"", "lint": "eslint . -c .eslintrc.js --rulesdir eslint-internal-rules/ --ext .ts,.js,.vue ...

Parsing JSON data with new line characters

What is the reason behind being unable to parse a json with a \n character in javascript? JSON.parse('{"x": "\n"}') Surprisingly, when you use JSON.parse(JSON.stringify({"x" : "\n"})), it works perfectly fine. indicates that {" ...

retrieving the selected checkbox value

My challenge is to extract the values of dynamically changing checked checkBoxes on my webpage. For example: while ($row=myqli_fetch_array($result)){ echo"<div>"; echo"<select id=\"course\" onchange=getCheckBox()> <opt ...

The addListener method in Google Maps iterates n times for a specific number of repetitions

When looking at the code below, the GetPropBasedOnRadius(); method loops for a certain number of times. I want to call that method only when the dragging event is completed. However, I am unsure how to do this. Any assistance on this matter would be great ...

Angularjs does not seem to be rendering content placed within curly braces

I'm working on setting up a page with Angular, and I'm facing an issue with displaying JSON data received from the server. Here is the code snippet: HTML <body ng-app="App"> <nav class="navbar navbar-dark bg-inverse navbar-fixed-top"& ...

Ways to identify whether the ajax error is due to Access-Control-Allow-Origin restriction or if the file is genuinely absent

My question pertains to customizing error messages for Access-Control-Allow-Origin issues and outdated URLs. I want to display specific messages to the user based on different types of errors that may occur. Currently, my code looks like this: $.ajax( { ...

How can you gradually fade out the bottom edge of a rendered component until it is re-rendered?

Currently, I am developing a reviews microservice for an e-commerce platform using react and react-bootstrap. My goal is to showcase 5 reviews initially, followed by a button to expand and reveal more reviews. In order to achieve this, I envision the botto ...

Issue with Selenium WebDriver in Opera browser: Not able to retrieve message from renderer

I'm currently facing an issue while attempting to run my Java Selenium tests using Opera browser (version 31). I have the latest versions of Selenium Webdriver (2.47.1) and OperaChromiumDriver (0.2.2) installed. I've experimented with two diffe ...