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

feat(locators): Add By.exactBinding locator #812

Merged
merged 1 commit into from
May 17, 2014
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
15 changes: 12 additions & 3 deletions lib/clientsidescripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,30 @@ clientSideScripts.waitForAngular = function(selector, callback) {
* Find a list of elements in the page by their angular binding.
*
* @param {string} binding The binding, e.g. {{cat.name}}.
* @param {boolean} exactMatch Whether the binding needs to be matched exactly
* @param {Element} using The scope of the search.
*
* @return {Array.<Element>} The elements containing the binding.
*/
clientSideScripts.findBindings = function(binding, using) {
clientSideScripts.findBindings = function(binding, exactMatch, using) {
using = using || document;
var bindings = using.getElementsByClassName('ng-binding');
var matches = [];
for (var i = 0; i < bindings.length; ++i) {
var dataBinding = angular.element(bindings[i]).data('$binding');
if(dataBinding) {
var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[i]);
if (exactMatch) {
var matcher = new RegExp('([^a-zA-Z\d]|$)' + binding + '([^a-zA-Z\d]|^)');
if (matcher.test(bindingName)) {

Choose a reason for hiding this comment

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

There seems to be an issue regarding the regex. When running npm testI get the error:
lib/clientsidescripts.js: line 54, col 45, Bad or unnecessary escaping.

I think it should be changed to:
new RegExp('([^a-zA-Z\\d]|$)' + binding + '([^a-zA-Z\\d]|^)');

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for letting me know. Currently the code works fine with the Regex object, but fails jshint. I'll make that change.

matches.push(bindings[i]);
}
} else {
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[i]);
}
}

}
}
return matches; /* Return the whole array for webdriver.findElements. */
Expand Down
22 changes: 21 additions & 1 deletion lib/locators.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,32 @@ ProtractorBy.prototype.binding = function(bindingDescriptor) {
findElementsOverride: function(driver, using) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findBindings,
bindingDescriptor, using));
bindingDescriptor, false, using));
},
message: 'by.binding("' + bindingDescriptor + '")'
};
};

/**
* Find an element by exact binding.
*
* @alias by.exactBinding()
* Same as by.binding() except this does not allow for partial matches
*
* @param {string} bindingDescriptor
* @return {{findElementsOverride: findElementsOverride, message: string}}
*/
ProtractorBy.prototype.exactBinding = function(bindingDescriptor) {
return {
findElementsOverride: function(driver, using) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findBindings,
bindingDescriptor, true, using));
},
message: 'by.exactBinding("' + bindingDescriptor + '")'
};
};

/**
* @deprecated Use 'model' instead.
*
Expand Down
12 changes: 12 additions & 0 deletions spec/basic/findelements_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ describe('locators', function() {
expect(greeting.getText()).toEqual('Hiya');
});

it('should find exact match by exactBinding', function() {
var greeting = element(by.exactBinding('greeting'));

expect(greeting.getText()).toEqual('Hiya');
});

it('should not find partial match by exactBinding', function() {
var greeting = element(by.exactBinding('greet'));

expect(greeting.isPresent()).toBe(false);
});

it('should find an element by binding with ng-bind attribute',
function() {
var name = element(by.binding('username'));
Expand Down