/*global browser, element */
/*jshint expr:true */
'use strict';
var expect = require('chai').use(require('chai-as-promised')).expect;
/**
* @method element
* @memberof Component.prototype
* @returns {ElementFinder} Returns the {@link http://www.protractortest.org/#/api?view=ElementFinder|ElementFinder} for this component
*/
exports.element = function() {
var parent = this.$.parent;
if (parent instanceof this.constructor) {
return parent.element().element(this.$.locator);
}
return element(this.$.locator);
};
/**
* Retrieves the text from an element and passes the value to the provided callback function
*
* @method text
* @memberof Component.prototype
*
* @example
* expect(component.text()).toMatch(/hello world/ig);
*/
exports.text = function() {
return this.element().getText();
};
/**
* Enters a value into an input field
*
* @method enter
* @memberof Component.prototype
* @param {String} value
*/
exports.enter = function(value) {
this.element().sendKeys(value);
};
/**
* Retrieves or enters a value into an input field
*
* @method value
* @memberof Component.prototype
* @param {String} value
*/
exports.value = function(value) {
if (typeof value === 'undefined') {
return this.element().getAttribute('value');
}
this.enter(value);
};
/**
* Checks that all children are visible.
* For a component without children, use isVisible()
*
* @method isFullyDisplayed
* @memberof Component.prototype
*/
exports.isFullyDisplayed = function() {
var i;
this.isVisible();
if (this.components) {
for (i = this.components.length - 1; i >= 0; i--) {
this[this.components[i]].isFullyDisplayed();
}
}
};
/**
* Performs an angular expectation testing whether this element contains any text
*
* @method containsText
* @memberof Component.prototype
*/
exports.containsText = function() {
expect(this.text()).to.eventually.match(/[a-zA-Z0-9]+/);
};
/**
* Performs an angular expectation testing whether this element is not empty
*
* @method isNotEmpty
* @memberof Component.prototype
*/
exports.isNotEmpty = function() {
// TODO: - whitespace and newlines will return true. Add a flag in future to allow/disallow
expect(this.element().getInnerHtml()).to.eventually.not.be.empty;
};
/**
* Performs an angular expectation testing whether this element's text matches the given
* string or regular expression
*
* @method matches
* @memberof Component.prototype
* @param {RegExp} match
*
* @example
* component.matches(/hello world/);
*/
exports.matches = function(match) {
expect(this.text()).to.eventually.match(match);
};
/**
* Performs an expectation testing whether this component is visible
*
* @method isVisible
* @memberof Component.prototype
*/
exports.isVisible = function() {
expect(this.element().isDisplayed()).to.eventually.be.true;
};
/**
* Performs an expectation testing whether component is hidden on page
*
* @method isHidden
* @memberof Component.prototype
*/
exports.isHidden = function() {
expect(this.element().isDisplayed()).to.eventually.be.false;
};
/**
* Performs an expectation testing whether component is not in document
*
* @method isNotPresent
* @memberof Component.prototype
*/
exports.isNotPresent = function() {
expect(this.element().isPresent()).to.eventually.be.false;
};
/**
* Clicks on the element using the custom angular.anchor dsl
*
* @method click
* @memberof Component.prototype
*/
exports.click = function() {
this.element().click();
};
/**
* Simulates keypress of given keycode
*
* @method keypress
* @memberof Component.prototype
* @param {Number} keyCode
*/
exports.keypress = function(keyCode) {
this.element().keypress(keyCode);
};
/**
* Gives focus to the component
*
* @method focus
* @memberof Component.prototype
*/
exports.focus = function() {
this.element().click();
};
/**
* Simulates browser drag and drop
*
* @method dragTo
* @memberof Component.prototype
* @param {Number} x
* @param {Number} y
*/
exports.dragTo = function(x, y) {
browser.actions().
dragAndDrop(this.element(), {x: x, y: y}).
perform();
};
/**
* Tests this component for having the 'active' class
*
* @method isActive
* @memberof Component.prototype
*/
exports.isActive = function() {
expect(this.element().getAttribute('class')).to.eventually.match(/active/);
};
/**
* Tests this component for having the 'selected' class
*
* @method isSelected
* @memberof Component.prototype
*/
exports.isSelected = function() {
expect(this.element().isSelected()).to.eventually.be.true;
};
/**
* Tests that this component does not have a 'selected' class
*
* @method isNotSelected
* @memberof Component.prototype
*/
exports.isNotSelected = function() {
expect(this.element().isSelected()).to.eventually.be.false;
};
/**
* Tests this component for having the 'disabled' class
*
* @method isDisabled
* @memberof Component.prototype
*/
exports.isDisabled = function() {
expect(this.element().isEnabled()).to.eventually.be.false;
};
/**
* Tests this component for not having the 'disabled' class
*
* @method isEnabled
* @memberof Component.prototype
*/
exports.isEnabled = function() {
expect(this.element().isEnabled()).to.eventually.be.true;
};
/**
* Tests this component for having the '_blank' href target
*
* @method opensNewWindow
* @memberof Component.prototype
*/
exports.opensNewWindow = function() {
expect(this.element().getAttribute('target')).to.eventually.match(/_blank/);
};
/**
* @method count
* @memberof Component.prototype
*/
exports.count = function() {
var parent = this.$.parent;
if (parent instanceof this.constructor) {
return parent.element().all(this.$.locator).count();
}
return element.all(this.$.locator).count();
};
/**
* @method expectCount
* @memberof Component.prototype
* @return {{greaterThan: Function, lessThan: Function, toBe: Function}}
*
* @example <pre>
* component.expectCount().greaterThan(3);
* component.expectCount().lessThan(7);
* component.expectCount().toBe(2);
* </pre>
*/
exports.expectCount = function() {
var count = this.count();
return {
greaterThan: function(cnt) {
expect(count).to.eventually.be.above(cnt);
},
lessThan: function(cnt) {
expect(count).to.eventually.be.at.least(cnt);
},
toBe: function(cnt) {
expect(count).to.eventually.equal(cnt);
},
};
};
/**
* Creates an iterator for all the elements matching this component's locator and accepts a
* function of that component type
*
* @method all
* @memberof Component.prototype
* @param {Function} method
* @param {Function} then - callback function
*
* @example
* component.all(function(element) { element.click(); });
*/
exports.all = function(method, then) {
var parent = this.$.parent;
var all;
then = then || function() {};
if (parent instanceof this.constructor) {
all = parent.element().all(this.$.locator);
} else {
all = element.all(this.$.locator);
}
all.each(function(element) {
method(element);
});
then();
};
/**
* Return the nth element matching this component's locator
*
* @method nth
* @memberof Component.prototype
* @param {Number} number
*
* @example
* component.nth(3).isDisplayed();
*/
exports.nth = function(number) {
var parent = this.$.parent;
if (parent instanceof this.constructor) {
return parent.element().all(this.$.locator).get(number);
}
return element.all(this.$.locator).get(number);
};