/* eslint-disable max-lines */
import R from 'ramda';
import {ActionUtil} from './action-util';
import {ElementUtil} from './element-util';
import {Condition} from './condition';
import {WaitCondition} from './wait-condition';
const checkCondition = async (selector, message, condition) =>
await ActionUtil.expectExecutedAction(async () => await WaitCondition.check(message, condition, selector));
const checkPresenceAndCondition = async (selector, condition) => {
const EC = protractor.ExpectedConditions;
const elementFinder = ElementUtil.elementFinder(selector);
return ActionUtil.expectExecutedAction(async () =>
browser.wait(EC.and(EC.presenceOf(elementFinder), condition), global.defaultExpectationTimeout));
};
/**
* Expectations created based on WaitCondition DSL methods.
*/
export class Expectation {
/**
* Checks that attribute of element meets a certain condition.
*
* @param selector
* @param attrName
* @param condition
*/
static attributeCondition(selector, attrName, condition) {
const cond = () => {
const finder = ElementUtil.elementFinder(selector);
return Condition.attributeCondition(attrName, condition)(finder);
};
return checkPresenceAndCondition(selector, cond);
}
/**
* Checks if attribute has expected text.
*
* @param selector
* @param attribute
* @param text
*/
static attributeEquals(selector, attribute, text) {
const elementFinder = ElementUtil.elementFinder(selector);
const textIs = () =>
elementFinder.getAttribute(attribute).then(
(actualText) => R.equals(R.trim(actualText), R.trim(text))
);
return checkPresenceAndCondition(selector, textIs);
}
/**
* Checks that attribute doesn't have specified text.
*
* @param selector
* @param attribute
* @param text
*/
static attributeNotEqual(selector, attribute, text) {
const elementFinder = ElementUtil.elementFinder(selector);
const textIs = () =>
elementFinder.getAttribute(attribute).then(
(actualText) => !R.equals(R.trim(actualText), R.trim(text))
);
return checkPresenceAndCondition(selector, textIs);
}
/**
* Checks that attribute value contains an expected text.
*
* @param selector
* @param attrName
* @param value
*/
static attributeContainsValue(selector, attrName, value) {
const condition = (actualValue) => R.gt(actualValue.indexOf(value), -1);
return Expectation.attributeCondition(selector, attrName, condition);
}
/**
* Checks that attribute does not contain a specified value in a certain text.
*
* @param selector
* @param attrName
* @param value
*/
static attributeDoesntContainValue(selector, attrName, value) {
const condition = (actualValue) => R.equals(actualValue.indexOf(value), -1);
return Expectation.attributeCondition(selector, attrName, condition);
}
/**
* Checks that attribute value is not less than a specified value.
*
* @param selector
* @param attrName
* @param minValue
*/
static attributeValueNotLessThan(selector, attrName, minValue) {
const condition = (actualValue) => R.gte(parseInt(actualValue, 10), minValue);
return Expectation.attributeCondition(selector, attrName, condition);
}
/**
* Checks that attribute value is not more than a specified value.
*
* @param selector
* @param attrName
* @param maxValue
*/
static attributeValueNotMoreThan(selector, attrName, maxValue) {
const condition = (actualText) => R.lte(Math.abs(parseInt(actualText, 10) - maxValue), 1);
return Expectation.attributeCondition(selector, attrName, condition);
}
/**
* Checks that checkbox will be selected/unselected.
*
* @param selector
* @param checked
*/
static checkboxChecked(selector, checked) {
return ActionUtil.expectExecutedAction(() => WaitCondition.checkboxChecked(selector, checked));
}
/**
* Checks if element is clickable.
* @param selector
*/
static clickable(selector) {
return checkCondition(selector, 'for element to be clickable', Condition.clickable);
}
/**
* Checks that provided condition is met. You can use it when no other expectation
* doesn't fit your current needs.
* @param conditionFunction
* @param message
*/
static condition(conditionFunction, message) {
return ActionUtil.expectExecutedAction(() =>
browser.wait(conditionFunction, global.defaultExpectationTimeout, message, global.defaultExpectationTimeout)
);
}
/**
* Checks that number of elements are present.
*
* @param selector
* @param expectedCount
*/
static async count(selector, expectedCount) {
const countIs = () => element.all(By.css(selector)).count().then((count) => R.equals(count, expectedCount));
return Expectation.condition(countIs);
}
/**
* Checks not less than certain number of elements are present.
*
* @param selector
* @param expectedCount
*/
static async countAtLeast(selector, expectedCount) {
const countIs = () =>
element.all(By.css(selector)).count().then((count) => R.gte(count, expectedCount));
return Expectation.condition(countIs);
}
/**
* Checks that date component has an expected value
*
* @param selector
* @param dateValue
* @param defaultDateFormat
*/
static async dateValue(selector, dateValue, defaultDateFormat) {
const expectationFunction = async (dateFormat) =>
await Expectation.attributeEquals(selector, 'value', dateValue.format(dateFormat));
return Expectation.withLocaleDate(expectationFunction, defaultDateFormat);
}
/**
* Checks that element is disabled.
*
* @param selector
*/
static async disabled(selector) {
return ActionUtil.expectExecutedAction(() => WaitCondition.disabled(selector));
}
/**
* Checks that element is in DOM and visible to the user.
*
* @param selector
*/
static async displayed(selector) {
return ActionUtil.expectExecutedAction(() => WaitCondition.displayed(selector));
}
/**
* Checks that it is an empty text for a certain element.
*
* @param selector
*/
static async emptyText(selector) {
return ActionUtil.expectExecutedAction(() => WaitCondition.textEquals(selector, ''));
}
/**
* Checks that element is enabled (opposite to disabled), you can use it to check that
* element is not disabled anymore and you can perform some actions.
*
* @param selector
*/
static enabled(selector) {
return ActionUtil.expectExecutedAction(() => WaitCondition.enabled(selector));
}
/**
* Checks that element has a scrolling.
*
* @param selector
*/
static hasScroll(selector) {
const element = ElementUtil.elementFinder(selector);
expect(element.getSize().then(
(size) =>
Expectation.attributeValueNotLessThan(element, 'scrollHeight', size.height - 10)));
}
/**
* Checks that element doesn't have a scrolling.
*
* @param selector
*/
static hasNoScroll(selector) {
const element = ElementUtil.elementFinder(selector);
expect(element.getSize().then(
(size) =>
Expectation.attributeValueNotMoreThan(element, 'scrollHeight', size.height)));
}
/**
* Checks if element has a certain attribute name.
*
* @param selector
* @param attrName
*/
static hasAttribute(selector, attrName) {
const elementFilter = () => ElementUtil.elementFinder(selector);
const hasAttr = () =>
elementFilter().getAttribute(attrName).then((attrValue) => !R.isNil(attrValue), R.F);
return checkPresenceAndCondition(selector, hasAttr);
}
static hasClassName(selector, className) {
const element = ElementUtil.elementFinder(selector);
return element.getAttribute('class').then((classes) => R.includes(className, classes.split(' ')));
}
/**
* Checks that element doesn't have a certain attribute name.
*
* @param selector
* @param attrName
*/
static hasNoAttribute(selector, attrName) {
const elementFilter = () => ElementUtil.elementFinder(selector);
const hasNoAttr = () =>
elementFilter().getAttribute(attrName).then((attrValue) => R.isNil(attrValue), R.F);
return checkPresenceAndCondition(selector, hasNoAttr);
}
/**
* This function is used with a combination in other function to check a date in a local date format.
*
* @param expectationFunction
* @param defaultDateFormat
*/
static withLocaleDate(expectationFunction, defaultDateFormat = 'MMM D, YYYY') {
return ActionUtil.expectExecutedAction(() =>
browser.executeScript(() =>
navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.userLanguage
).then(() => defaultDateFormat).then((dateFormat) => expectationFunction(dateFormat))
);
}
/**
* Checks that element is not visible to user but can be present in DOM.
*
* @param selector
*/
static notDisplayed(selector) {
return ActionUtil.expectExecutedAction(() => WaitCondition.notDisplayed(selector));
}
/**
* Checks that element is not visible to user and not present in DOM.
*
* @param selector
*/
static notPresent(selector) {
return ActionUtil.expectExecutedAction(() => WaitCondition.notPresent(selector));
}
/**
* Checks that element might be not visible to the user but present in DOM.
*
* @param selector
*/
static present(selector) {
return ActionUtil.expectExecutedAction(() => WaitCondition.present(selector));
}
/**
* Checks that element containing a specified text is present.
*
* @param selector
*/
static presentWithText(selector) {
return ActionUtil.expectExecutedAction(() => WaitCondition.presentWithText(selector));
}
/**
* Checks that element has readonly attribute.
*
* @param selector
*/
static readOnly(selector) {
Expectation.present(selector);
return Expectation.attributeContainsValue(selector, 'readonly', 'true');
}
/**
* Checks that element contains a certain text.
*
* @param selector
* @param text
*/
static textContains(selector, text) {
return ActionUtil.expectExecutedAction(() => WaitCondition.textContains(selector, text));
}
/**
* Checks that element has a certain text.
*
* @param selector
* @param text
*/
static textEquals(selector, text) {
return ActionUtil.expectExecutedAction(() => WaitCondition.textEquals(selector, text));
}
/**
* Checks that element doesn't have a certain text.
*
* @param selector
* @param text
*/
static textNotEqual(selector, text) {
const msg = `for element's text not to be ${text}`;
return checkCondition(selector, msg, Condition.not(Condition.textEquals(text)));
}
/**
* Checks that element doesn't have a certain text.
*
* @param selector
* @param regex
*/
static textMatches(selector, regex) {
const msg = `for element text to be matched by '${regex}'`;
return checkCondition(selector, msg, Condition.textMatches(regex));
}
}
/* eslint-enable max-lines */