UNPKG

skutter

Version:

Skutter: Opinionated BDD Browser based test framework

334 lines (333 loc) 15 kB
"use strict"; 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;