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

Commit

Permalink
feat(findElements): $ & $$ shortcuts.
Browse files Browse the repository at this point in the history
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')
  • Loading branch information
Jeremy Morony & Tommy Fisher authored and juliemr committed Oct 8, 2013
1 parent e34a4ab commit c025ddb
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 49 deletions.
50 changes: 50 additions & 0 deletions lib/protractor.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ Protractor.prototype.wrapWebElement = function(element) {
var originalFindElements = element.findElements;
var originalIsElementPresent = element.isElementPresent;

/**
* Shortcut for querying the document directly with css.
*
* @param {string} selector a css selector
* @see webdriver.WebElement.findElement
* @return {!webdriver.WebElement}
*/
element.$ = function(selector) {
var locator = protractor.By.css(selector);
return this.findElement(locator);
}

/**
* @see webdriver.WebElement.findElement
* @return {!webdriver.WebElement}
Expand All @@ -163,6 +175,19 @@ Protractor.prototype.wrapWebElement = function(element) {
return thisPtor.wrapWebElement(found);
};

/**
* Shortcut for querying the document directly with css.
*
* @param {string} selector a css selector
* @see webdriver.WebElement.findElements
* @return {!webdriver.promise.Promise} A promise that will be resolved to an
* array of the located {@link webdriver.WebElement}s.
*/
element.$$ = function(selector) {
var locator = protractor.By.css(selector);
return this.findElements(locator);
}

/**
* @see webdriver.WebElement.findElements
* @return {!webdriver.promise.Promise} A promise that will be resolved to an
Expand Down Expand Up @@ -222,6 +247,18 @@ Protractor.prototype.wrapWebElement = function(element) {
return element;
};

/**
* Shortcut for querying the document directly with css.
*
* @param {string} selector a css selector
* @see webdriver.WebDriver.findElement
* @return {!webdriver.WebElement}
*/
Protractor.prototype.$ = function(selector) {
var locator = protractor.By.css(selector);
return this.findElement(locator);
};

/**
* Waits for Angular to finish rendering before searching for elements.
* @see webdriver.WebDriver.findElement
Expand All @@ -240,6 +277,19 @@ Protractor.prototype.findElement = function(locator, varArgs) {
return this.wrapWebElement(found);
};

/**
* Shortcut for querying the document directly with css.
*
* @param {string} selector a css selector
* @see webdriver.WebDriver.findElements
* @return {!webdriver.promise.Promise} A promise that will be resolved to an
* array of the located {@link webdriver.WebElement}s.
*/
Protractor.prototype.$$ = function(selector) {
var locator = protractor.By.css(selector);
return this.findElements(locator);
};

/**
* Waits for Angular to finish rendering before searching for elements.
* @see webdriver.WebDriver.findElements
Expand Down
166 changes: 117 additions & 49 deletions spec/findelements_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,24 +278,120 @@ describe('finding elements', function() {
// Make sure it works with a promise expectation.
expect(element.evaluate('planet.radius')).toEqual(1516);
});
});

describe('finding an element by css', function() {
beforeEach(function() {
ptor.get('app/index.html#/bindings');
});

describe('via the driver', function() {
it('should return the same results as web driver', function() {
ptor.findElement(protractor.By.css('.planet-info')).getText().then(function(textFromLongForm) {
var textFromShortcut = ptor.$('.planet-info').getText();
expect(textFromShortcut).toEqual(textFromLongForm);
});
});
});

describe('via a web element', function() {
var select;

beforeEach(function() {
select = ptor.findElement(protractor.By.css('select'));
});

it('should return the same results as web driver', function() {
select.findElement(protractor.By.css('option[value="4"]')).getText().then(function(textFromLongForm) {
var textFromShortcut = select.$('option[value="4"]').getText();
expect(textFromShortcut).toEqual(textFromLongForm);
});
});
});
});

describe('finding elements by css', function() {
beforeEach(function() {
ptor.get('app/index.html#/bindings');
});

describe('via the driver', function() {
it('should return the same results as web driver', function() {
ptor.findElements(protractor.By.css('option')).then(function(optionsFromLongForm) {
ptor.$$('option').then(function(optionsFromShortcut) {
expect(optionsFromShortcut.length).toEqual(optionsFromLongForm.length);

optionsFromLongForm.forEach(function(option, i) {
option.getText().then(function(textFromLongForm) {
expect(optionsFromShortcut[i].getText()).toEqual(textFromLongForm);
});
});
});
});
});
});

describe('via a web element', function() {
var select;

beforeEach(function() {
select = ptor.findElement(protractor.By.css('select'));
});

describe('when wrapping all elements', function() {
describe('when querying using a locator that specifies an override', function() {
it('should return the same results as web driver', function() {
select.findElements(protractor.By.css('option')).then(function(optionsFromLongForm) {
select.$$('option').then(function(optionsFromShortcut) {
expect(optionsFromShortcut.length).toEqual(optionsFromLongForm.length);

optionsFromLongForm.forEach(function(option, i) {
option.getText().then(function(textFromLongForm) {
expect(optionsFromShortcut[i].getText()).toEqual(textFromLongForm);
});
});
});
});
});
});
});

describe('wrapping web driver elements', function() {
var verifyMethodsAdded = function(result) {
expect(typeof result.evaluate).toBe('function');
expect(typeof result.$).toBe('function');
expect(typeof result.$$).toBe('function');
}

beforeEach(function() {
ptor.get('app/index.html#/bindings');
});

describe('when found via #findElement', function() {
describe('when using a locator that specifies an override', function() {
it('should wrap the result', function() {
ptor.findElement(protractor.By.binding('planet.name')).then(verifyMethodsAdded);
});
});

describe('when using a locator that does not specify an override', function() {
it('should wrap the result', function() {
ptor.findElement(protractor.By.css('option[value="4"]')).then(verifyMethodsAdded);
});
});
});

describe('when found via #findElements', function() {
describe('when using a locator that specifies an override', function() {
it('should wrap the results', function() {
ptor.findElements(protractor.By.binding('planet.name')).then(function(elements) {
for (var i = 0; i < elements.length; i++) {
expect(typeof elements[i].evaluate).toBe('function');
}
ptor.findElements(protractor.By.binding('planet.name')).then(function(results) {
results.forEach(verifyMethodsAdded);
});
});
});

describe('when querying using a locator that does not specify an override', function() {
describe('when using a locator that does not specify an override', function() {
it('should wrap the results', function() {
ptor.findElements(protractor.By.css('option[value="4"]')).then(function(elements) {
for (var i = 0; i < elements.length; i++) {
expect(typeof elements[i].evaluate).toBe('function');
}
ptor.findElements(protractor.By.css('option[value="4"]')).then(function(results) {
results.forEach(verifyMethodsAdded);
});
});
});
Expand All @@ -308,61 +404,33 @@ describe('finding elements', function() {
info = ptor.findElement(protractor.By.css('.planet-info'));
});

describe('when querying for a single element', function() {
describe('when ng using a locator that specifies an override', function() {
var planetName;

beforeEach(function() {
planetName = info.findElement(protractor.By.binding('planet.name'));
});

describe('when found via #findElement', function() {
describe('when using a locator that specifies an override', function() {
it('should wrap the result', function() {
expect(typeof planetName.evaluate).toBe("function")
info.findElement(protractor.By.binding('planet.name')).then(verifyMethodsAdded);
});
});

describe('when querying using a locator that does not specify an override', function() {
var moons;

beforeEach(function() {
moons = info.findElement(protractor.By.css('div:last-child'));
});

describe('when using a locator that does not specify an override', function() {
it('should wrap the result', function() {
expect(typeof moons.evaluate).toBe("function")
info.findElement(protractor.By.css('div:last-child')).then(verifyMethodsAdded);
});
});
});

describe('when querying for many elements', function() {
describe('when using a locator that specifies an override', function() {
var planetName;

beforeEach(function() {
planetName = info.findElements(protractor.By.binding('planet.name'));
});

it('should wrap the result', function() {
planetName.then(function(result) {
for (var i = 0; i < result.length; ++i) {
expect(typeof result[i].evaluate).toBe("function");
}
info.findElements(protractor.By.binding('planet.name')).then(function(results) {
results.forEach(verifyMethodsAdded);
});
});
});

describe('when querying using a locator that does not specify an override', function() {
var moons;

beforeEach(function() {
moons = info.findElements(protractor.By.css('div:last-child'));
});

describe('when using a locator that does not specify an override', function() {
it('should wrap the result', function() {
moons.then(function(result) {
for (var i = 0; i < result.length; ++i) {
expect(typeof result[i].evaluate).toBe("function");
}
info.findElements(protractor.By.css('div:last-child')).then(function(results) {
results.forEach(verifyMethodsAdded);
});
});
});
Expand Down

0 comments on commit c025ddb

Please sign in to comment.