I am currently in process of creating a framework using Protractor. I was trying to use cssContainingText
locator given by the Protractor API. However, the locator failed giving an invalidElement
exception, which seemed wierd to me.
The HTML of the page looks like this
<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>
I was trying to use the text someText
using the following locator-
element(by.cssContainingText('.field-name','someText'));
, which weirdly gives an InvalidLocator
exception. When I use the following locator element(by.cssContainingText('a','someText'))
, the code works perfectly fine.
As per what I understand from the explanation given here, and the Protractor implementation given here, the cssContainingText
first locates all the elements using the CSS Selector and then matches the required text.
So, it seems perfectly fine to me to use the .field-name
class name for the CSS Selector and then match the desired string. However, this fails, which I am not able to understand. Inputs on this would be helpful.
I am currently in process of creating a framework using Protractor. I was trying to use cssContainingText
locator given by the Protractor API. However, the locator failed giving an invalidElement
exception, which seemed wierd to me.
The HTML of the page looks like this
<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>
I was trying to use the text someText
using the following locator-
element(by.cssContainingText('.field-name','someText'));
, which weirdly gives an InvalidLocator
exception. When I use the following locator element(by.cssContainingText('a','someText'))
, the code works perfectly fine.
As per what I understand from the explanation given here, and the Protractor implementation given here, the cssContainingText
first locates all the elements using the CSS Selector and then matches the required text.
So, it seems perfectly fine to me to use the .field-name
class name for the CSS Selector and then match the desired string. However, this fails, which I am not able to understand. Inputs on this would be helpful.
-
Does it fail on all browsers? Or is there a specific browser? When I use the sourcecode from Protractor and inject in in this page and that look for
findByCssContainingText('.post-taglist', 'javascript')
it works, so it's strange that it's failing for you – wswebcreation Commented Jun 1, 2017 at 4:21 - Yes, it fails on all browsers. I have tried with Chrome Dev build 60+ and latest FF. And yes, I am too, wierded out, because I expected the locator to work – demouser123 Commented Jun 1, 2017 at 6:44
-
Try this in your dev console in Chrome.
window.document.querySelectorAll('.field-name')[0].textContent
orwindow.document.querySelectorAll('.field-name')[0].innerText
. This is weird because I cannot reproduce this either when trying it out here: angular.github.io/protractor-cookbook/ng1/calculator when querying for'.ng-scope'
or'.ng-binding'
– craig Commented Jun 2, 2017 at 2:22
1 Answer
Reset to default 3You can view and follow the code in GitHub, starting from the API documentation of cssContainingText.
It es down to this way of search for content in clientsidescripts.js
:
var elementText = element.textContent || element.innerText || '';
if (elementText.indexOf(searchText) > -1) {
matches.push(element);
}
As indexOf()
requires an exact match and your th
element has neither innerText
nor textContent
(your <a>
tag has), you don't get a result by using the th
element.
As for differences between textContent
and innerText
let me refer to this answer in SO and to this one as well.
For your 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.">a Google link</a>.
</div>
<textarea id="output" rows="12" cols="80" style="font-family: monospace;"></textarea>