Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

feat(locators): Add support for regex in cssContainingText #4532

Merged
merged 3 commits into from
Nov 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions lib/clientsidescripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -676,20 +676,28 @@ functions.findByPartialButtonText = function(searchText, using) {
* Find elements by css selector and textual content.
*
* @param {string} cssSelector The css selector to match.
* @param {string} searchText The exact text to match.
* @param {string} searchText The exact text to match or a serialized regex.
* @param {Element} using The scope of the search.
*
* @return {Array.<Element>} An array of matching elements.
*/
functions.findByCssContainingText = function(cssSelector, searchText, using) {
using = using || document;

if (searchText.indexOf('__REGEXP__') === 0) {
var match = searchText.split('__REGEXP__')[1].match(/\/(.*)\/(.*)?/);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure enough whether this match method works well here

Would you mind adding another test that using a regex with no regex flags, we can be more convinced of this change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, will do

searchText = new RegExp(match[1], match[2] || '');
}
var elements = using.querySelectorAll(cssSelector);
var matches = [];
for (var i = 0; i < elements.length; ++i) {
var element = elements[i];
var elementText = element.textContent || element.innerText || '';
if (elementText.indexOf(searchText) > -1) {
var elementMatches = searchText instanceof RegExp ?
searchText.test(elementText) :
elementText.indexOf(searchText) > -1;

if (elementMatches) {
matches.push(element);
}
}
Expand Down
5 changes: 3 additions & 2 deletions lib/locators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,11 @@ export class ProtractorBy extends WebdriverBy {
* var dog = element(by.cssContainingText('.pet', 'Dog'));
*
* @param {string} cssSelector css selector
* @param {string} searchString text search
* @param {string|RegExp} searchString text search
* @returns {ProtractorLocator} location strategy
*/
cssContainingText(cssSelector: string, searchText: string): ProtractorLocator {
cssContainingText(cssSelector: string, searchText: string|RegExp): ProtractorLocator {
searchText = (searchText instanceof RegExp) ? '__REGEXP__' + searchText.toString() : searchText;
return {
findElementsOverride: (driver: WebDriver, using: WebElement, rootSelector: string):
wdpromise.Promise<WebElement[]> => {
Expand Down
20 changes: 20 additions & 0 deletions spec/basic/locators_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,26 @@ describe('locators', function() {
expect(element(by.cssContainingText('#transformedtext div', 'capitalize'))
.getAttribute('id')).toBe('textcapitalize');
});

it('should find elements with a regex', function() {
element.all(by.cssContainingText('#transformedtext div', /(upper|lower)case/i))
.then(function(found) {
expect(found.length).toEqual(2);
expect(found[0].getText()).toBe('UPPERCASE');
expect(found[1].getText()).toBe('lowercase');
});
});

it('should find elements with a regex with no flags', function() {
// this test matches the non-transformed text.
// the text is actually transformed with css,
// so you can't match the Node innerText or textContent.
element.all(by.cssContainingText('#transformedtext div', /Uppercase/))
.then(function(found) {
expect(found.length).toEqual(1);
expect(found[0].getText()).toBe('UPPERCASE');
});
});
});

describe('by options', function() {
Expand Down