了解Protractor中的cssContainingText定位器功能

时间:2017-05-31 19:06:01

标签: javascript selenium protractor e2e-testing

我目前正在使用Protractor创建框架。我试图使用Protractor API提供的cssContainingText定位器。但是,定位器未能给出invalidElement异常,这对我来说似乎很奇怪。

页面的HTML看起来像这样

     <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>

我尝试使用以下定位器

来使用文本someText

element(by.cssContainingText('.field-name','someText'));,奇怪地给出InvalidLocator例外。当我使用以下定位器element(by.cssContainingText('a','someText'))时,代码完全正常。

根据我对here给出的解释以及给定here的Protractor实现的理解,cssContainingText首先使用CSS Selector定位所有元素,然后匹配所需的文本。

因此,对CSS选择器使用.field-name类名称然后匹配所需的字符串似乎完全没问题。然而,这失败了,我无法理解。对此的输入会有所帮助。

1 个答案:

答案 0 :(得分:2)

您可以从API documentation of cssContainingText开始查看并关注GitHub中的代码。

归结为在clientsidescripts.js中搜索内容的方式:

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

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

由于indexOf()需要完全匹配且您的th元素既没有innerText也没有textContent(您的<a>代码已经拥有),所以您不需要&#39; t使用th元素获得结果。

至于textContentinnerText之间的差异,请让我参考this answer in SOto this one as well

对于你的情况:

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

&#13;
&#13;
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]);
}
&#13;
<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>
&#13;
&#13;
&#13;