skutter
Version:
Skutter: Opinionated BDD Browser based test framework
334 lines (333 loc) • 15 kB
JavaScript
;
const Lazy = require("lazy.js");
const verbosity_level_aware_logger_1 = require("../framework/services/verbosity-level-aware-logger");
const className = "HtmlActions";
class HtmlActions {
static checkSpecified(className, functionName, parameterName, parameterValue, allowBlankString = false) {
if (parameterValue === "" && allowBlankString) {
return;
}
if (!parameterValue) {
let error = new Error(`[${className}].[${functionName}] Parameter '${parameterName}' is not specified.`);
Error.captureStackTrace(error, HtmlActions.checkSpecified);
throw error;
}
}
static getCurrentContext(context) {
const methodName = "getCurrentContext";
HtmlActions.checkSpecified(className, methodName, "context", context);
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.diag(`[${className}].[${methodName}] entered.`);
if (!context.inspectionStack) {
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.diag(`[${className}].[${methodName}] Using browser for context.`);
return context.browser.element(by.tagName("body"));
}
else {
let stackItem = context.inspectionStack.topItem;
if (!stackItem) {
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.diag(`[${className}].[${methodName}] Using browser for context.`);
return context.browser.element(by.tagName("body"));
}
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.diag(`[${className}].[${methodName}] Using stack for context.`);
return stackItem.element;
}
}
static getElementDirect(elementRoot, selector, throwIfNotFound = false) {
const methodName = "getElementDirect";
HtmlActions.checkSpecified(className, methodName, "elementRoot", elementRoot);
HtmlActions.checkSpecified(className, methodName, "selector", selector);
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.diag(`[${className}].[${methodName}] entered.`);
let element = null;
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.info(`[${className}].[${methodName}] attempting findElement for "${selector}"`);
if (element === null) {
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.diag(`[${className}].[${methodName}] brand new element.`);
try {
element = elementRoot.element(selector);
}
catch (exception) {
if (throwIfNotFound) {
throw new Error(`[${className}].[${methodName}] element not found.`);
}
}
}
else {
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.diag(`[${className}].[${methodName}] Previously selected element.`);
if (!element.element) {
throw new Error(`[${className}].[${methodName}] findElement not a function on element.`);
}
try {
element = element.element(selector);
}
catch (exception) {
if (throwIfNotFound) {
throw new Error(`[${className}].[${methodName}] element not found.`);
}
}
}
if (throwIfNotFound) {
if (!element) {
throw new Error(`[${className}].[${methodName}] element not found.`);
}
}
let promise = new Promise((resolve, reject) => {
if (element) {
element.isPresent().then((isPresentResult) => {
if (isPresentResult) {
verbosity_level_aware_logger_1.VerbosityLevelAwareConsoleLog.diag(`[${className}].[${methodName}] returning element.`);
resolve(element);
}
else {
if (throwIfNotFound) {
if (elementRoot.getOuterHtml) {
elementRoot.getOuterHtml()
.then(function getOuterHtmlSuccess(innerHtml) {
reject(`[${className}].[${methodName}] element not present on page. ` + innerHtml.substring(0, 1000));
}, function getOuterHtmlFailure(error) {
reject(`[${className}].[${methodName}] element not present on page. Cannot give additional context. ` + error);
});
}
else {
reject(`[${className}].[${methodName}] element not present on page.`);
}
}
else {
reject(`[${className}].[${methodName}] Rejecting - element not present on page.`);
}
}
});
}
else {
reject(`[${className}].[${methodName}] Rejecting - element not present on page.`);
}
});
return promise;
}
static getElement(context, selector, throwIfNotFound = false) {
const methodName = "getElement";
HtmlActions.checkSpecified(className, methodName, "context", context);
HtmlActions.checkSpecified(className, methodName, "selector", selector);
let targetContext = HtmlActions.getCurrentContext(context);
return HtmlActions.getElementDirect(targetContext, selector, throwIfNotFound);
}
static getParent(element) {
const methodName = "getParent";
HtmlActions.checkSpecified(className, methodName, "element", element);
if (!element.element) {
throw new Error(`[${className}].[${methodName}] element.element not set.`);
}
let promise = new Promise((resolve, reject) => {
let selector = by.xpath("..");
let parent = element.element(selector);
if (!parent) {
throw new Error(`[${className}].[${methodName}] parent element not found.`);
}
resolve(parent);
});
return promise;
}
static getElements(context, selector) {
const methodName = "getElements";
HtmlActions.checkSpecified(className, methodName, "context", context);
HtmlActions.checkSpecified(className, methodName, "selector", selector);
console.log(`[${className}].[${methodName}] attempting findElements for ${selector}"`);
let targetContext = HtmlActions.getCurrentContext(context);
let elements = targetContext.all(selector);
console.log(`[${className}].[${methodName}] returning elements.`);
let promise = new Promise((resolve, reject) => {
elements
.then((itemsArray) => {
resolve(itemsArray);
});
});
return promise;
}
static getChildElements(parentElement, selector) {
const methodName = "getChildElements";
HtmlActions.checkSpecified(className, methodName, "parentElement", parentElement);
HtmlActions.checkSpecified(className, methodName, "selector", selector);
console.log(`[${className}].[${methodName}] attempting findElements for ${selector}"`);
let elements = parentElement.all(selector);
console.log(`[${className}].[${methodName}] returning elements.`);
let promise = new Promise((resolve, reject) => {
elements
.then((items) => {
resolve(items);
});
});
return promise;
}
static click(element) {
const methodName = "click";
HtmlActions.checkSpecified(className, methodName, "element", element);
if (!element.click) {
throw new Error(`[${className}].[${methodName}] element does not have a click function.`);
}
let promise = new Promise((resolve, reject) => {
console.log(`[${className}].[${methodName}] Clicking.`);
element.click()
.then(() => {
resolve();
});
});
return promise;
}
static typeText(element, text) {
const methodName = "typeText";
HtmlActions.checkSpecified(className, methodName, "element", element);
HtmlActions.checkSpecified(className, methodName, "text", text);
let promise = new Promise((resolve, reject) => {
console.log(`[${className}].[${methodName}] Tap, Tap, Tap *Ding!*.`);
element.sendKeys(text)
.then(() => {
resolve();
});
});
return promise;
}
static pressKey(element, key) {
const methodName = "pressKey";
HtmlActions.checkSpecified(className, methodName, "element", element);
HtmlActions.checkSpecified(className, methodName, "key", key);
let convertedKey = protractor.Key.NULL;
switch (key) {
case "enter":
convertedKey = protractor.Key.ENTER;
break;
case "tab":
convertedKey = protractor.Key.TAB;
break;
case "backspace":
convertedKey = protractor.Key.BACK_SPACE;
break;
case "delete":
convertedKey = protractor.Key.DELETE;
break;
case "left arrow":
convertedKey = protractor.Key.ARROW_LEFT;
break;
case "right arrow":
convertedKey = protractor.Key.ARROW_RIGHT;
break;
case "up arrow":
convertedKey = protractor.Key.ARROW_UP;
break;
case "down arrow":
convertedKey = protractor.Key.ARROW_DOWN;
break;
case "escape":
convertedKey = protractor.Key.ESCAPE;
break;
default:
throw new Error(`[HtmlActions].[pressKey] unknown key: ${key}`);
}
let promise = new Promise((resolve, reject) => {
console.log(`[${className}].[${methodName}] *Press*.`);
element.sendKeys(convertedKey)
.then(() => {
resolve();
});
});
return promise;
}
static selectOption(selectElement, text, allowBlankText = false) {
const methodName = "selectOption";
HtmlActions.checkSpecified(className, methodName, "selectElement", selectElement);
HtmlActions.checkSpecified(className, methodName, "text", text, allowBlankText);
let promise = new Promise((resolve, reject) => {
selectElement.all(by.cssContainingText("option", text))
.then((options) => {
let getOptionTextPromises = [];
for (let option of options) {
getOptionTextPromises.push(Promise.resolve(option.getText()));
}
Promise.all(getOptionTextPromises).then((itemTextValues) => {
let itemIndex = Lazy(itemTextValues).indexOf(text);
let optionElement = options[itemIndex];
if (!optionElement) {
throw new Error(`[${className}].[${methodName}] optionElement not found`);
}
if (!optionElement.click) {
throw new Error(`[${className}].[${methodName}] optionElement does not have a click function.`);
}
optionElement.click()
.then(() => resolve());
});
});
});
return promise;
}
static selectOptionContaining(selectElement, text) {
const methodName = "selectOptionContaining";
HtmlActions.checkSpecified(className, methodName, "selectElement", selectElement);
HtmlActions.checkSpecified(className, methodName, "text", text);
let promise = new Promise((resolve, reject) => {
selectElement.all(by.cssContainingText("option", text))
.then((items) => {
let getOptionTextPromises = [];
for (let item of items) {
getOptionTextPromises.push(Promise.resolve(item.getText()));
}
Promise.all(getOptionTextPromises).then((itemTextValues) => {
let itemIndex = Lazy(itemTextValues).indexOf(text);
let optionElement = items[itemIndex];
if (!optionElement) {
throw new Error(`[${className}].[${methodName}] optionElement not found`);
}
if (!optionElement.click) {
throw new Error(`[${className}].[${methodName}] optionElement does not have a click function.`);
}
optionElement.click()
.then(() => resolve());
});
});
});
return promise;
}
static getDropDownOptionLabels(selectElement) {
const methodName = "getDropDownOptionLabels";
HtmlActions.checkSpecified(className, methodName, "selectElement", selectElement);
let promise = new Promise((resolve, reject) => {
selectElement
.all(by.tagName("option"))
.getAttribute("label")
.then((values) => {
resolve(values);
});
});
return promise;
}
static getInputText(element) {
const methodName = "getInputText";
HtmlActions.checkSpecified(className, methodName, "element", element);
let promise = new Promise((resolve, reject) => {
element.getAttribute("value")
.then((value) => {
resolve(value);
});
});
return promise;
}
static getDropDownSelectedValue(selectElement) {
const methodName = "getDropDownSelectedValue";
HtmlActions.checkSpecified(className, methodName, "selectElement", selectElement);
let promise = new Promise((resolve, reject) => {
let selectedOption = selectElement.$("option:checked");
selectedOption.getText()
.then((value) => {
resolve(value);
});
});
return promise;
}
static isCheckboxChecked(checkboxElement) {
const methodName = "isCheckboxChecked";
HtmlActions.checkSpecified(className, methodName, "checkboxElement", checkboxElement);
let promise = new Promise(function (resolve, reject) {
checkboxElement.isSelected()
.then((isSelected) => {
resolve(isSelected);
});
});
return promise;
}
}
exports.HtmlActions = HtmlActions;