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

Commit 88a1e58

Browse files
Damiyajuliemr
authored andcommitted
Feat(clientSideScripts): Add by.buttonText, by.partialButtonText
Adds client side JS implementations of by.buttonText and by.partialButtonText, enabling element lookup based on innerText. Closes #452
1 parent 2a3a886 commit 88a1e58

File tree

5 files changed

+136
-3
lines changed

5 files changed

+136
-3
lines changed

docs/api.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ are available:
147147
`Protractor.By.className` function( )
148148

149149
:
150-
`Protractor.By.linkText` function( )
150+
`Protractor.By.linkText` function( )
151151

152152
:
153-
`Protractor.By.partialLinkText` function( )
153+
`Protractor.By.partialLinkText` function( )
154154

155155
:
156156
`Protractor.By.js` function( )
@@ -179,6 +179,11 @@ are available:
179179
[**P**](https://github.com/angular/protractor/blob/92e0fdf07ad775878feba9f16be8fba1015e3753/lib/locators.js#L138) :
180180
`Protractor.By.repeater` function( )
181181

182+
:
183+
`Protractor.By.buttonText` function( )
184+
185+
:
186+
`Protractor.By.partialButtonText` function( )
182187

183188

184189
WebElements

lib/clientsidescripts.js

+60-1
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ clientSideScripts.findInputs = function() {
342342
};
343343

344344
/**
345-
* Find a elements by model name.
345+
* Find elements by model name.
346346
*
347347
* arguments[0] {Element} The scope of the search.
348348
* arguments[1] {string} The model name.
@@ -363,6 +363,65 @@ clientSideScripts.findByModel = function() {
363363
};
364364

365365
/**
366+
* Find buttons by textual content.
367+
*
368+
* arguments[0] {Element} The scope of the search.
369+
* arguments[1] {string} The exact text to match.
370+
*
371+
* @return {Array.<Element>} The matching elements.
372+
*/
373+
clientSideScripts.findByButtonText = function() {
374+
var using = arguments[0] || document;
375+
var searchText = arguments[1];
376+
var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
377+
var matches = [];
378+
for (var i = 0; i < elements.length; ++i) {
379+
var element = elements[i];
380+
var elementText;
381+
if (element.tagName.toLowerCase() == "button") {
382+
elementText = element.innerText || element.textContent;
383+
} else {
384+
elementText = element.value;
385+
}
386+
if (elementText === searchText) {
387+
matches.push(element);
388+
}
389+
}
390+
391+
return matches;
392+
};
393+
394+
/**
395+
* Find buttons by textual content.
396+
*
397+
* arguments[0] {Element} The scope of the search.
398+
* arguments[1] {string} The exact text to match.
399+
*
400+
* @return {Array.<Element>} The matching elements.
401+
*/
402+
clientSideScripts.findByPartialButtonText = function() {
403+
var using = arguments[0] || document;
404+
var searchText = arguments[1];
405+
var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
406+
var matches = [];
407+
for (var i = 0; i < elements.length; ++i) {
408+
var element = elements[i];
409+
var elementText;
410+
if (element.tagName.toLowerCase() == "button") {
411+
elementText = element.innerText || element.textContent;
412+
} else {
413+
elementText = element.value;
414+
}
415+
if (elementText.indexOf(searchText) > -1) {
416+
matches.push(element);
417+
}
418+
}
419+
420+
return matches;
421+
};
422+
423+
424+
/**
366425
* Find multiple select elements by model name.
367426
*
368427
* arguments[0] {Element} The scope of the search.

lib/locators.js

+31
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,37 @@ ProtractorBy.prototype.model = function(model) {
120120
};
121121
};
122122

123+
/**
124+
* Usage:
125+
* <button>Save</button>
126+
* element(by.buttonText("Save"));
127+
*/
128+
ProtractorBy.prototype.buttonText = function(searchText) {
129+
return {
130+
findElementsOverride: function(driver, using) {
131+
return driver.findElements(
132+
webdriver.By.js(clientSideScripts.findByButtonText), using, searchText);
133+
},
134+
message: 'by.buttonText("' + searchText + '")'
135+
};
136+
};
137+
138+
/**
139+
* Usage:
140+
* <button>Save my file</button>
141+
* element(by.partialButtonText("Save"));
142+
*/
143+
ProtractorBy.prototype.partialButtonText = function(searchText) {
144+
return {
145+
findElementsOverride: function(driver, using) {
146+
return driver.findElements(
147+
webdriver.By.js(clientSideScripts.findByPartialButtonText), using, searchText);
148+
},
149+
message: 'by.partialButtonText("' + searchText + '")'
150+
};
151+
};
152+
153+
123154
/**
124155
* @DEPRECATED - use 'model' instead.
125156
* Usage:

spec/basic/findelements_spec.js

+29
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,35 @@ describe('locators', function() {
129129
});
130130
});
131131

132+
describe('by partial button text', function() {
133+
it('should find multiple buttons containing "text"', function() {
134+
element.all(by.partialButtonText('text')).then(function(arr) {
135+
expect(arr.length).toEqual(4);
136+
expect(arr[0].getAttribute('id')).toBe('exacttext');
137+
expect(arr[1].getAttribute('id')).toBe('otherbutton');
138+
expect(arr[2].getAttribute('id')).toBe('submitbutton');
139+
expect(arr[3].getAttribute('id')).toBe('inputbutton');
140+
});
141+
});
142+
});
143+
144+
describe('by button text', function() {
145+
it('should find two button containing "Exact text"', function() {
146+
element.all(by.buttonText('Exact text')).then(function(arr) {
147+
expect(arr.length).toEqual(2);
148+
expect(arr[0].getAttribute('id')).toBe('exacttext');
149+
expect(arr[1].getAttribute('id')).toBe('submitbutton');
150+
});
151+
});
152+
153+
it('should not find any buttons containing "text"', function() {
154+
element.all(by.buttonText('text')).then(function(arr) {
155+
expect(arr.length).toEqual(0);
156+
})
157+
});
158+
159+
});
160+
132161
describe('by repeater', function() {
133162
beforeEach(function() {
134163
browser.get('index.html#/repeater');

testapp/form/form.html

+9
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,12 @@ <h4>Drag and Drop</h4>
6060
<h4>Alert trigger</h4>
6161
<button id="alertbutton" ng-click="doAlert()">Open Alert</button>
6262
</div>
63+
64+
<div>
65+
<h4>Buttons</h4>
66+
<button id="exacttext">Exact text</button>
67+
<button id="otherbutton">Partial button text</button>
68+
<button id="trapbutton">No match</button>
69+
<input type="submit" value="Exact text" id="submitbutton"/>
70+
<input type="button" value="Hello text" id="inputbutton"/>
71+
</div>

0 commit comments

Comments
 (0)