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

Commit c025ddb

Browse files
Jeremy Morony & Tommy Fisherjuliemr
Jeremy Morony & Tommy Fisher
authored andcommitted
feat(findElements): $ & $$ shortcuts.
Introducing the $ shortcut method for finding a single element by css without having to call protractor.By.css. Additionally $$ for finding all elements by css. Examples: - ptor.$('.some .selector') - ptor.$$('.some .selector')
1 parent e34a4ab commit c025ddb

File tree

2 files changed

+167
-49
lines changed

2 files changed

+167
-49
lines changed

lib/protractor.js

+50
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ Protractor.prototype.wrapWebElement = function(element) {
146146
var originalFindElements = element.findElements;
147147
var originalIsElementPresent = element.isElementPresent;
148148

149+
/**
150+
* Shortcut for querying the document directly with css.
151+
*
152+
* @param {string} selector a css selector
153+
* @see webdriver.WebElement.findElement
154+
* @return {!webdriver.WebElement}
155+
*/
156+
element.$ = function(selector) {
157+
var locator = protractor.By.css(selector);
158+
return this.findElement(locator);
159+
}
160+
149161
/**
150162
* @see webdriver.WebElement.findElement
151163
* @return {!webdriver.WebElement}
@@ -163,6 +175,19 @@ Protractor.prototype.wrapWebElement = function(element) {
163175
return thisPtor.wrapWebElement(found);
164176
};
165177

178+
/**
179+
* Shortcut for querying the document directly with css.
180+
*
181+
* @param {string} selector a css selector
182+
* @see webdriver.WebElement.findElements
183+
* @return {!webdriver.promise.Promise} A promise that will be resolved to an
184+
* array of the located {@link webdriver.WebElement}s.
185+
*/
186+
element.$$ = function(selector) {
187+
var locator = protractor.By.css(selector);
188+
return this.findElements(locator);
189+
}
190+
166191
/**
167192
* @see webdriver.WebElement.findElements
168193
* @return {!webdriver.promise.Promise} A promise that will be resolved to an
@@ -222,6 +247,18 @@ Protractor.prototype.wrapWebElement = function(element) {
222247
return element;
223248
};
224249

250+
/**
251+
* Shortcut for querying the document directly with css.
252+
*
253+
* @param {string} selector a css selector
254+
* @see webdriver.WebDriver.findElement
255+
* @return {!webdriver.WebElement}
256+
*/
257+
Protractor.prototype.$ = function(selector) {
258+
var locator = protractor.By.css(selector);
259+
return this.findElement(locator);
260+
};
261+
225262
/**
226263
* Waits for Angular to finish rendering before searching for elements.
227264
* @see webdriver.WebDriver.findElement
@@ -240,6 +277,19 @@ Protractor.prototype.findElement = function(locator, varArgs) {
240277
return this.wrapWebElement(found);
241278
};
242279

280+
/**
281+
* Shortcut for querying the document directly with css.
282+
*
283+
* @param {string} selector a css selector
284+
* @see webdriver.WebDriver.findElements
285+
* @return {!webdriver.promise.Promise} A promise that will be resolved to an
286+
* array of the located {@link webdriver.WebElement}s.
287+
*/
288+
Protractor.prototype.$$ = function(selector) {
289+
var locator = protractor.By.css(selector);
290+
return this.findElements(locator);
291+
};
292+
243293
/**
244294
* Waits for Angular to finish rendering before searching for elements.
245295
* @see webdriver.WebDriver.findElements

spec/findelements_spec.js

+117-49
Original file line numberDiff line numberDiff line change
@@ -278,24 +278,120 @@ describe('finding elements', function() {
278278
// Make sure it works with a promise expectation.
279279
expect(element.evaluate('planet.radius')).toEqual(1516);
280280
});
281+
});
282+
283+
describe('finding an element by css', function() {
284+
beforeEach(function() {
285+
ptor.get('app/index.html#/bindings');
286+
});
287+
288+
describe('via the driver', function() {
289+
it('should return the same results as web driver', function() {
290+
ptor.findElement(protractor.By.css('.planet-info')).getText().then(function(textFromLongForm) {
291+
var textFromShortcut = ptor.$('.planet-info').getText();
292+
expect(textFromShortcut).toEqual(textFromLongForm);
293+
});
294+
});
295+
});
296+
297+
describe('via a web element', function() {
298+
var select;
299+
300+
beforeEach(function() {
301+
select = ptor.findElement(protractor.By.css('select'));
302+
});
303+
304+
it('should return the same results as web driver', function() {
305+
select.findElement(protractor.By.css('option[value="4"]')).getText().then(function(textFromLongForm) {
306+
var textFromShortcut = select.$('option[value="4"]').getText();
307+
expect(textFromShortcut).toEqual(textFromLongForm);
308+
});
309+
});
310+
});
311+
});
312+
313+
describe('finding elements by css', function() {
314+
beforeEach(function() {
315+
ptor.get('app/index.html#/bindings');
316+
});
317+
318+
describe('via the driver', function() {
319+
it('should return the same results as web driver', function() {
320+
ptor.findElements(protractor.By.css('option')).then(function(optionsFromLongForm) {
321+
ptor.$$('option').then(function(optionsFromShortcut) {
322+
expect(optionsFromShortcut.length).toEqual(optionsFromLongForm.length);
323+
324+
optionsFromLongForm.forEach(function(option, i) {
325+
option.getText().then(function(textFromLongForm) {
326+
expect(optionsFromShortcut[i].getText()).toEqual(textFromLongForm);
327+
});
328+
});
329+
});
330+
});
331+
});
332+
});
333+
334+
describe('via a web element', function() {
335+
var select;
336+
337+
beforeEach(function() {
338+
select = ptor.findElement(protractor.By.css('select'));
339+
});
281340

282-
describe('when wrapping all elements', function() {
283-
describe('when querying using a locator that specifies an override', function() {
341+
it('should return the same results as web driver', function() {
342+
select.findElements(protractor.By.css('option')).then(function(optionsFromLongForm) {
343+
select.$$('option').then(function(optionsFromShortcut) {
344+
expect(optionsFromShortcut.length).toEqual(optionsFromLongForm.length);
345+
346+
optionsFromLongForm.forEach(function(option, i) {
347+
option.getText().then(function(textFromLongForm) {
348+
expect(optionsFromShortcut[i].getText()).toEqual(textFromLongForm);
349+
});
350+
});
351+
});
352+
});
353+
});
354+
});
355+
});
356+
357+
describe('wrapping web driver elements', function() {
358+
var verifyMethodsAdded = function(result) {
359+
expect(typeof result.evaluate).toBe('function');
360+
expect(typeof result.$).toBe('function');
361+
expect(typeof result.$$).toBe('function');
362+
}
363+
364+
beforeEach(function() {
365+
ptor.get('app/index.html#/bindings');
366+
});
367+
368+
describe('when found via #findElement', function() {
369+
describe('when using a locator that specifies an override', function() {
370+
it('should wrap the result', function() {
371+
ptor.findElement(protractor.By.binding('planet.name')).then(verifyMethodsAdded);
372+
});
373+
});
374+
375+
describe('when using a locator that does not specify an override', function() {
376+
it('should wrap the result', function() {
377+
ptor.findElement(protractor.By.css('option[value="4"]')).then(verifyMethodsAdded);
378+
});
379+
});
380+
});
381+
382+
describe('when found via #findElements', function() {
383+
describe('when using a locator that specifies an override', function() {
284384
it('should wrap the results', function() {
285-
ptor.findElements(protractor.By.binding('planet.name')).then(function(elements) {
286-
for (var i = 0; i < elements.length; i++) {
287-
expect(typeof elements[i].evaluate).toBe('function');
288-
}
385+
ptor.findElements(protractor.By.binding('planet.name')).then(function(results) {
386+
results.forEach(verifyMethodsAdded);
289387
});
290388
});
291389
});
292390

293-
describe('when querying using a locator that does not specify an override', function() {
391+
describe('when using a locator that does not specify an override', function() {
294392
it('should wrap the results', function() {
295-
ptor.findElements(protractor.By.css('option[value="4"]')).then(function(elements) {
296-
for (var i = 0; i < elements.length; i++) {
297-
expect(typeof elements[i].evaluate).toBe('function');
298-
}
393+
ptor.findElements(protractor.By.css('option[value="4"]')).then(function(results) {
394+
results.forEach(verifyMethodsAdded);
299395
});
300396
});
301397
});
@@ -308,61 +404,33 @@ describe('finding elements', function() {
308404
info = ptor.findElement(protractor.By.css('.planet-info'));
309405
});
310406

311-
describe('when querying for a single element', function() {
312-
describe('when ng using a locator that specifies an override', function() {
313-
var planetName;
314-
315-
beforeEach(function() {
316-
planetName = info.findElement(protractor.By.binding('planet.name'));
317-
});
318-
407+
describe('when found via #findElement', function() {
408+
describe('when using a locator that specifies an override', function() {
319409
it('should wrap the result', function() {
320-
expect(typeof planetName.evaluate).toBe("function")
410+
info.findElement(protractor.By.binding('planet.name')).then(verifyMethodsAdded);
321411
});
322412
});
323413

324-
describe('when querying using a locator that does not specify an override', function() {
325-
var moons;
326-
327-
beforeEach(function() {
328-
moons = info.findElement(protractor.By.css('div:last-child'));
329-
});
330-
414+
describe('when using a locator that does not specify an override', function() {
331415
it('should wrap the result', function() {
332-
expect(typeof moons.evaluate).toBe("function")
416+
info.findElement(protractor.By.css('div:last-child')).then(verifyMethodsAdded);
333417
});
334418
});
335419
});
336420

337421
describe('when querying for many elements', function() {
338422
describe('when using a locator that specifies an override', function() {
339-
var planetName;
340-
341-
beforeEach(function() {
342-
planetName = info.findElements(protractor.By.binding('planet.name'));
343-
});
344-
345423
it('should wrap the result', function() {
346-
planetName.then(function(result) {
347-
for (var i = 0; i < result.length; ++i) {
348-
expect(typeof result[i].evaluate).toBe("function");
349-
}
424+
info.findElements(protractor.By.binding('planet.name')).then(function(results) {
425+
results.forEach(verifyMethodsAdded);
350426
});
351427
});
352428
});
353429

354-
describe('when querying using a locator that does not specify an override', function() {
355-
var moons;
356-
357-
beforeEach(function() {
358-
moons = info.findElements(protractor.By.css('div:last-child'));
359-
});
360-
430+
describe('when using a locator that does not specify an override', function() {
361431
it('should wrap the result', function() {
362-
moons.then(function(result) {
363-
for (var i = 0; i < result.length; ++i) {
364-
expect(typeof result[i].evaluate).toBe("function");
365-
}
432+
info.findElements(protractor.By.css('div:last-child')).then(function(results) {
433+
results.forEach(verifyMethodsAdded);
366434
});
367435
});
368436
});

0 commit comments

Comments
 (0)