diff --git a/src/errors/helper.js b/src/errors/helper.js index d91830c2..29c680b2 100644 --- a/src/errors/helper.js +++ b/src/errors/helper.js @@ -26,6 +26,7 @@ const ERROR_CODES = { STALE_ELEMENT_REFERENCE: 'STALE_ELEMENT_REFERENCE', ELEMENT_NOT_VISIBLE: 'ELEMENT_NOT_VISIBLE', ELEMENT_NOT_INTERACTABLE: 'ELEMENT_NOT_INTERACTABLE', + ELEMENT_INTERACTABLE: 'ELEMENT_INTERACTABLE', LOCATOR_MATCHES_MULTIPLE_ELEMENTS: 'LOCATOR_MATCHES_MULTIPLE_ELEMENTS', ELEMENT_STILL_EXISTS: 'ELEMENT_STILL_EXISTS', BROWSER_JS_EXECUTE_ERROR: 'BROWSER_JS_EXECUTE_ERROR', diff --git a/src/ox_modules/module-mob.js b/src/ox_modules/module-mob.js index cdb489ed..5c9c2232 100644 --- a/src/ox_modules/module-mob.js +++ b/src/ox_modules/module-mob.js @@ -605,6 +605,11 @@ export default class MobileModule extends WebDriverModule { this.helpers.assertContext = modUtils.assertContext; this.helpers.contextList = modUtils.contextList; this.helpers.getLogTypes = modUtils.getLogTypes; + this.helpers.assertUnableToFindElement = modUtils.assertUnableToFindElement; + this.helpers.assertNotVisible = modUtils.assertNotVisible; + this.helpers.throwNotInteractable = modUtils.throwNotInteractable; + this.helpers.throwInteractable = modUtils.throwInteractable; + this.helpers.verify = modUtils.verify; } async deleteSession() { diff --git a/src/ox_modules/module-mob/commands/assertText.js b/src/ox_modules/module-mob/commands/assertText.js index e01a5926..a7a417b9 100644 --- a/src/ox_modules/module-mob/commands/assertText.js +++ b/src/ox_modules/module-mob/commands/assertText.js @@ -26,6 +26,7 @@ module.exports = async function(locator, pattern, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); let text; try { diff --git a/src/ox_modules/module-mob/commands/assertValue.js b/src/ox_modules/module-mob/commands/assertValue.js index 7f97f008..4a69fabe 100644 --- a/src/ox_modules/module-mob/commands/assertValue.js +++ b/src/ox_modules/module-mob/commands/assertValue.js @@ -22,6 +22,7 @@ module.exports = async function(locator, pattern, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text; var actualError; diff --git a/src/ox_modules/module-mob/commands/clear.js b/src/ox_modules/module-mob/commands/clear.js index d6ff4655..ad6680f3 100644 --- a/src/ox_modules/module-mob/commands/clear.js +++ b/src/ox_modules/module-mob/commands/clear.js @@ -23,6 +23,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { await el.clearValue(); diff --git a/src/ox_modules/module-mob/commands/click.js b/src/ox_modules/module-mob/commands/click.js index db8e49ed..c4ab5f0f 100644 --- a/src/ox_modules/module-mob/commands/click.js +++ b/src/ox_modules/module-mob/commands/click.js @@ -21,6 +21,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); // if the element is outside the viewport - check interactability and try to scroll it into the view first if (await this.isWebViewContext() && !(await el.isClickable())) { diff --git a/src/ox_modules/module-mob/commands/clickHidden.js b/src/ox_modules/module-mob/commands/clickHidden.js index 70a8ade1..e3073ab6 100644 --- a/src/ox_modules/module-mob/commands/clickHidden.js +++ b/src/ox_modules/module-mob/commands/clickHidden.js @@ -22,6 +22,8 @@ module.exports = async function(locator, clickParent) { await this.helpers.assertContext(this.helpers.contextList.hybrid, this.helpers.contextList.web); var el = await this.helpers.getElement(locator); + this.helpers.assertUnableToFindElement(el, locator); + // NOTE: adding comments inside the passed function is not allowed! /*global document*/ var ret = await this.driver.execute(function (domEl, clickParent) { diff --git a/src/ox_modules/module-mob/commands/clickLong.js b/src/ox_modules/module-mob/commands/clickLong.js index 80b0f7ea..2ee6bdab 100644 --- a/src/ox_modules/module-mob/commands/clickLong.js +++ b/src/ox_modules/module-mob/commands/clickLong.js @@ -23,6 +23,7 @@ module.exports = async function(locator, duration, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); await el.touchAction([ 'press', diff --git a/src/ox_modules/module-mob/commands/clickMultipleTimes.js b/src/ox_modules/module-mob/commands/clickMultipleTimes.js index 81fa35b8..60eb25fe 100644 --- a/src/ox_modules/module-mob/commands/clickMultipleTimes.js +++ b/src/ox_modules/module-mob/commands/clickMultipleTimes.js @@ -23,6 +23,7 @@ module.exports = async function(locator, taps, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var actions = []; for (var i = 0; i < taps; i++) { diff --git a/src/ox_modules/module-mob/commands/dragAndDrop.js b/src/ox_modules/module-mob/commands/dragAndDrop.js index 8d744705..a9f3cb7b 100644 --- a/src/ox_modules/module-mob/commands/dragAndDrop.js +++ b/src/ox_modules/module-mob/commands/dragAndDrop.js @@ -26,6 +26,7 @@ module.exports = async function(locator, xoffset, yoffset, timeout) { await this.helpers.assertContext(this.helpers.contextList.android, this.helpers.contextList.ios); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); await el.touchAction([ 'press', diff --git a/src/ox_modules/module-mob/commands/getLocation.js b/src/ox_modules/module-mob/commands/getLocation.js index c5910805..f34f37bf 100644 --- a/src/ox_modules/module-mob/commands/getLocation.js +++ b/src/ox_modules/module-mob/commands/getLocation.js @@ -24,5 +24,6 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getLocation(); }; diff --git a/src/ox_modules/module-mob/commands/getText.js b/src/ox_modules/module-mob/commands/getText.js index 1221e11b..004b41fd 100644 --- a/src/ox_modules/module-mob/commands/getText.js +++ b/src/ox_modules/module-mob/commands/getText.js @@ -22,6 +22,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text = await el.getText(); if (text) { return text.trim().replace(/\s+/g, ' '); diff --git a/src/ox_modules/module-mob/commands/getValue.js b/src/ox_modules/module-mob/commands/getValue.js index 8ada5581..f4d1dc56 100644 --- a/src/ox_modules/module-mob/commands/getValue.js +++ b/src/ox_modules/module-mob/commands/getValue.js @@ -22,6 +22,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { var text = await el.getValue(); diff --git a/src/ox_modules/module-mob/commands/index.js b/src/ox_modules/module-mob/commands/index.js index 1095d856..d379be91 100644 --- a/src/ox_modules/module-mob/commands/index.js +++ b/src/ox_modules/module-mob/commands/index.js @@ -70,4 +70,10 @@ export {default as type} from './type'; export {default as unlockPattern} from './unlockPattern'; export {default as waitForExist} from './waitForExist'; export {default as waitForVisible} from './waitForVisible'; -export {default as waitForInteractable} from './waitForInteractable'; \ No newline at end of file +export {default as waitForNotVisible} from './waitForNotVisible'; +export {default as waitForInteractable} from './waitForInteractable'; +export {default as waitForNotInteractable} from './waitForNotInteractable'; +export {default as verifyAlert} from './verifyAlert'; +export {default as verifyText} from './verifyText'; +export {default as verifyTitle} from './verifyTitle'; +export {default as verifyValue} from './verifyValue'; \ No newline at end of file diff --git a/src/ox_modules/module-mob/commands/isCheckable.js b/src/ox_modules/module-mob/commands/isCheckable.js index 8466d51e..c6fdbc15 100644 --- a/src/ox_modules/module-mob/commands/isCheckable.js +++ b/src/ox_modules/module-mob/commands/isCheckable.js @@ -23,5 +23,6 @@ module.exports = async function(locator, timeout) { await this.helpers.assertContext(this.helpers.contextList.android); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getAttribute('checkable') == 'true'; }; diff --git a/src/ox_modules/module-mob/commands/isChecked.js b/src/ox_modules/module-mob/commands/isChecked.js index 6ab76a12..d208cbf6 100644 --- a/src/ox_modules/module-mob/commands/isChecked.js +++ b/src/ox_modules/module-mob/commands/isChecked.js @@ -23,5 +23,6 @@ module.exports = async function(locator, timeout) { await this.helpers.assertContext(this.helpers.contextList.android); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getAttribute('checked') == 'true'; }; diff --git a/src/ox_modules/module-mob/commands/isClickable.js b/src/ox_modules/module-mob/commands/isClickable.js index 77f3ab33..75ee6222 100644 --- a/src/ox_modules/module-mob/commands/isClickable.js +++ b/src/ox_modules/module-mob/commands/isClickable.js @@ -23,5 +23,6 @@ module.exports = async function(locator, timeout) { await this.helpers.assertContext(this.helpers.contextList.android); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getAttribute('clickable') == 'true'; }; diff --git a/src/ox_modules/module-mob/commands/isExist.js b/src/ox_modules/module-mob/commands/isExist.js index 0b323c55..8df3d3ca 100644 --- a/src/ox_modules/module-mob/commands/isExist.js +++ b/src/ox_modules/module-mob/commands/isExist.js @@ -23,8 +23,8 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); try { - await this.helpers.getElement(locator, false, timeout); - return true; + const el = await this.helpers.getElement(locator, false, timeout); + return !!el; } catch (e) { return false; } diff --git a/src/ox_modules/module-mob/commands/isSelected.js b/src/ox_modules/module-mob/commands/isSelected.js index 19027ced..3f1016a3 100644 --- a/src/ox_modules/module-mob/commands/isSelected.js +++ b/src/ox_modules/module-mob/commands/isSelected.js @@ -28,5 +28,6 @@ module.exports = async function(locator, timeout) { await this.helpers.assertContext(this.helpers.contextList.android, this.helpers.contextList.hybrid, this.helpers.contextList.web); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getAttribute('selected') == 'true'; }; diff --git a/src/ox_modules/module-mob/commands/isVisible.js b/src/ox_modules/module-mob/commands/isVisible.js index 5f233f11..c859202c 100644 --- a/src/ox_modules/module-mob/commands/isVisible.js +++ b/src/ox_modules/module-mob/commands/isVisible.js @@ -23,8 +23,8 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); try { - await this.helpers.getElement(locator, true, timeout); - return true; + const el = await this.helpers.getElement(locator, true, timeout); + return !!el; } catch (e) { return false; } diff --git a/src/ox_modules/module-mob/commands/scrollIntoElement.js b/src/ox_modules/module-mob/commands/scrollIntoElement.js index 7ca46aa4..4d998a64 100644 --- a/src/ox_modules/module-mob/commands/scrollIntoElement.js +++ b/src/ox_modules/module-mob/commands/scrollIntoElement.js @@ -33,6 +33,7 @@ module.exports = async function(scrollElmLocator, findElmLocator, xoffset = 0, y await this.helpers.assertContext(this.helpers.contextList.android, this.helpers.contextList.ios); var scrollElm = await this.helpers.getElement(scrollElmLocator, false, timeout); + this.helpers.assertUnableToFindElement(el, scrollElmLocator); var retry = 0; @@ -42,6 +43,7 @@ module.exports = async function(scrollElmLocator, findElmLocator, xoffset = 0, y var err = false; try { var el = await this.helpers.getElement(findElmLocator, true, 1000); + this.helpers.assertUnableToFindElement(el, findElmLocator); } catch (e) { err = true; } diff --git a/src/ox_modules/module-mob/commands/scrollIntoView.js b/src/ox_modules/module-mob/commands/scrollIntoView.js index cc75685d..9789d946 100644 --- a/src/ox_modules/module-mob/commands/scrollIntoView.js +++ b/src/ox_modules/module-mob/commands/scrollIntoView.js @@ -31,5 +31,6 @@ module.exports = async function(locator, options = true, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); await this.helpers.assertContext(this.helpers.contextList.hybrid, this.helpers.contextList.web); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); await el.scrollIntoView(options); }; diff --git a/src/ox_modules/module-mob/commands/select.js b/src/ox_modules/module-mob/commands/select.js index 1aad8bf6..9d6a53f3 100644 --- a/src/ox_modules/module-mob/commands/select.js +++ b/src/ox_modules/module-mob/commands/select.js @@ -29,6 +29,7 @@ module.exports = async function(selectLocator, optionLocator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(selectLocator, false, timeout); + this.helpers.assertUnableToFindElement(el, selectLocator); try { if (optionLocator.indexOf('value=') === 0) { diff --git a/src/ox_modules/module-mob/commands/selectFrame.js b/src/ox_modules/module-mob/commands/selectFrame.js index 41e6a096..59f7fc26 100644 --- a/src/ox_modules/module-mob/commands/selectFrame.js +++ b/src/ox_modules/module-mob/commands/selectFrame.js @@ -36,6 +36,7 @@ module.exports = async function(frameLocator) { for (var i = 0; i < arguments.length; i++) { var locator = arguments[i]; var el = await this.helpers.getElement(locator); + this.helpers.assertUnableToFindElement(el, locator); await this.driver.switchToFrame(el); } } diff --git a/src/ox_modules/module-mob/commands/swipe.js b/src/ox_modules/module-mob/commands/swipe.js index ea36ef99..b41b4dd8 100644 --- a/src/ox_modules/module-mob/commands/swipe.js +++ b/src/ox_modules/module-mob/commands/swipe.js @@ -29,6 +29,7 @@ module.exports = async function(locator, xoffset = 0, yoffset = 30, timeout, dur await this.helpers.assertContext(this.helpers.contextList.android, this.helpers.contextList.ios); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); const location = await el.getLocation(); diff --git a/src/ox_modules/module-mob/commands/swipeElement.js b/src/ox_modules/module-mob/commands/swipeElement.js index ab656de9..511e2f12 100644 --- a/src/ox_modules/module-mob/commands/swipeElement.js +++ b/src/ox_modules/module-mob/commands/swipeElement.js @@ -29,6 +29,7 @@ module.exports = async function(locator, xoffset = 0, yoffset = 30, timeout, dur await this.helpers.assertContext(this.helpers.contextList.android, this.helpers.contextList.ios); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); const location = await el.getLocation(); diff --git a/src/ox_modules/module-mob/commands/type.js b/src/ox_modules/module-mob/commands/type.js index efd8066c..a4c41931 100644 --- a/src/ox_modules/module-mob/commands/type.js +++ b/src/ox_modules/module-mob/commands/type.js @@ -25,6 +25,7 @@ module.exports = async function(locator, value, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { diff --git a/src/ox_modules/module-mob/commands/unlockPattern.js b/src/ox_modules/module-mob/commands/unlockPattern.js index 174aa26f..7302e16b 100644 --- a/src/ox_modules/module-mob/commands/unlockPattern.js +++ b/src/ox_modules/module-mob/commands/unlockPattern.js @@ -31,6 +31,7 @@ module.exports = async function(locator, cols, rows, pattern, timeout) { await this.helpers.assertContext(this.helpers.contextList.android); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var loc = await el.getLocation(); var locX = loc.x; diff --git a/src/ox_modules/module-mob/commands/verifyAlert.js b/src/ox_modules/module-mob/commands/verifyAlert.js new file mode 100644 index 00000000..bc2654d8 --- /dev/null +++ b/src/ox_modules/module-mob/commands/verifyAlert.js @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify whether alert matches the specified pattern and dismisses it. + * @description Text pattern can be any of the supported + * string matching patterns(on the top of page). + * @function verifyAlert + * @for web + * @param {String} pattern - Text pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * mob.init(caps);//Starts a mobile session and opens app from desired capabilities + * mob.click("id=Submit");// Clicks an element and opens an alert. + * mob.verifyAlert("Your Alert's text");// Verify the alert's text. + */ + +module.exports = async function(...args) { + return await this.helpers.verify(this.assertAlert, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-mob/commands/verifyText.js b/src/ox_modules/module-mob/commands/verifyText.js new file mode 100644 index 00000000..a8b2f1ec --- /dev/null +++ b/src/ox_modules/module-mob/commands/verifyText.js @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify element's inner text. + * @description Text pattern can be any of the supported + * string matching patterns (on the top of page). + * If the element is not interactable, then it will allways return empty string as its text. + * @function verifyText + * @param {String|Element} locator - Element locator. + * @param {String} pattern - Assertion text or pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @for android, ios, hybrid, web + * @example [javascript] Usage example + * mob.init(caps);//Starts a mobile session and opens app from desired capabilities + * mob.verifyText("id=UserName","John Doe");// Verify if an element’s text is as expected. + */ + +module.exports = async function(...args) { + return await this.helpers.verify(this.assertText, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-mob/commands/verifyTitle.js b/src/ox_modules/module-mob/commands/verifyTitle.js new file mode 100644 index 00000000..005199d5 --- /dev/null +++ b/src/ox_modules/module-mob/commands/verifyTitle.js @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ +/** + * @summary Verify the page title. + * @description Assertion pattern can be any of the supported + * string matching patterns(on the top of page). + * @function verifyTitle + * @param {String} pattern - Assertion text or pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @for hybrid, web + * @example [javascript] Usage example + * mob.init(caps);//Starts a mobile session and opens app from desired capabilities + * mob.verifyTitle("Your websites title!");// Verify if the title of the page. + */ + +module.exports = async function(...args) { + return await this.helpers.verify(this.assertTitle, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-mob/commands/verifyValue.js b/src/ox_modules/module-mob/commands/verifyValue.js new file mode 100644 index 00000000..0a076c47 --- /dev/null +++ b/src/ox_modules/module-mob/commands/verifyValue.js @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ +/** + * @summary Verify element's value. + * @function verifyValue + * @param {String|Element} locator - Element locator. + * @param {String} pattern - Value pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @for android, ios, hybrid, web + * @example [javascript] Usage example + * mob.init(caps);//Starts a mobile session and opens app from desired capabilities + * mob.verifyValue("id=UserName", "John Doe");// Verify if the value of an element. + */ + +module.exports = async function(...args) { + return await this.helpers.verify(this.assertValue, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-mob/commands/waitForExist.js b/src/ox_modules/module-mob/commands/waitForExist.js index 4f2cdddb..cf92df4b 100644 --- a/src/ox_modules/module-mob/commands/waitForExist.js +++ b/src/ox_modules/module-mob/commands/waitForExist.js @@ -20,5 +20,6 @@ */ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); - await this.helpers.getElement(locator, false, timeout); + const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); }; diff --git a/src/ox_modules/module-mob/commands/waitForInteractable.js b/src/ox_modules/module-mob/commands/waitForInteractable.js index 2eccdf9e..aff3e6e4 100644 --- a/src/ox_modules/module-mob/commands/waitForInteractable.js +++ b/src/ox_modules/module-mob/commands/waitForInteractable.js @@ -20,6 +20,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { await this.driver.waitUntil(async() => { @@ -31,6 +32,7 @@ module.exports = async function(locator, timeout) { }, { timeout: (timeout ? timeout : this.waitForTimeout) }); } catch (e) { - throw new this.OxError(this.errHelper.errorCode.ELEMENT_NOT_INTERACTABLE, `Element ${locator} is not interactable`); + await this.helpers.restoreTimeoutImplicit(); + this.helpers.throwNotInteractable(locator); } }; diff --git a/src/ox_modules/module-mob/commands/waitForNotInteractable.js b/src/ox_modules/module-mob/commands/waitForNotInteractable.js new file mode 100644 index 00000000..b72f9bd7 --- /dev/null +++ b/src/ox_modules/module-mob/commands/waitForNotInteractable.js @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Waits for element to become interactable. + * @function waitForNotInteractable + * @param {String|Element} locator - An element locator. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @for android, ios, hybrid, web + * @example [javascript] Usage example + * mob.init();//Opens browser session. + * mob.waitForNotInteractable("id=UserName");//Waits for an element is not clickable. + */ +module.exports = async function(locator, timeout) { + this.helpers.assertArgumentTimeout(timeout, 'timeout'); + const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + + try { + await this.driver.waitUntil(async() => { + const clickable = await el.getAttribute('clickable'); + const checkable = await el.getAttribute('checkable'); + const focusable = await el.getAttribute('focusable'); + const longClickable = await el.getAttribute('long-clickable'); + return (clickable || checkable || focusable || longClickable); + }, + { timeout: (timeout ? timeout : this.waitForTimeout) }); + } catch (e) { + await this.helpers.restoreTimeoutImplicit(); + return; + } + + this.helpers.throwInteractable(locator); +}; diff --git a/src/ox_modules/module-mob/commands/waitForNotVisible.js b/src/ox_modules/module-mob/commands/waitForNotVisible.js new file mode 100644 index 00000000..710fd8d8 --- /dev/null +++ b/src/ox_modules/module-mob/commands/waitForNotVisible.js @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Waits for element to become visible. + * @function waitForNotVisible + * @param {String|Element} locator - An element locator. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * mob.init();//Opens browser session. + * mob.open("www.yourwebsite.com");// Opens a website. + * mob.waitForNotVisible("id=Title", 45*1000);//Waits if an element is visible. + */ +module.exports = async function(locator, timeout) { + this.helpers.assertArgumentTimeout(timeout, 'timeout'); + const el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertNotVisible(el, locator); +}; diff --git a/src/ox_modules/module-mob/commands/waitForVisible.js b/src/ox_modules/module-mob/commands/waitForVisible.js index 79a6bc12..204fa3b4 100644 --- a/src/ox_modules/module-mob/commands/waitForVisible.js +++ b/src/ox_modules/module-mob/commands/waitForVisible.js @@ -19,5 +19,6 @@ */ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); - await this.helpers.getElement(locator, true, timeout); + const el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); }; diff --git a/src/ox_modules/module-web.js b/src/ox_modules/module-web.js index 5be898d4..30e2c153 100644 --- a/src/ox_modules/module-web.js +++ b/src/ox_modules/module-web.js @@ -720,6 +720,11 @@ export default class WebModule extends WebDriverModule { this.helpers.assertArgumentBoolOptional = modUtils.assertArgumentBoolOptional; this.helpers.assertArgumentTimeout = modUtils.assertArgumentTimeout; this.helpers.assertArgumentString = modUtils.assertArgumentString; + this.helpers.assertUnableToFindElement = modUtils.assertUnableToFindElement; + this.helpers.assertNotVisible = modUtils.assertNotVisible; + this.helpers.throwNotInteractable = modUtils.throwNotInteractable; + this.helpers.throwInteractable = modUtils.throwInteractable; + this.helpers.verify = modUtils.verify; } async _getHAR() { diff --git a/src/ox_modules/module-web/commands/assertExist.js b/src/ox_modules/module-web/commands/assertExist.js index 6eba7905..d70f102d 100644 --- a/src/ox_modules/module-web/commands/assertExist.js +++ b/src/ox_modules/module-web/commands/assertExist.js @@ -20,5 +20,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); - await this.helpers.getElement(locator, false, timeout); + const element = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(element, locator); }; diff --git a/src/ox_modules/module-web/commands/assertSelectedLabel.js b/src/ox_modules/module-web/commands/assertSelectedLabel.js index b7fc2c21..2492c69c 100644 --- a/src/ox_modules/module-web/commands/assertSelectedLabel.js +++ b/src/ox_modules/module-web/commands/assertSelectedLabel.js @@ -25,9 +25,11 @@ module.exports = async function(locator, pattern, timeout, waitForVisible = true this.helpers.assertArgument(pattern, 'pattern'); this.helpers.assertArgumentTimeout(timeout, 'timeout'); - const el = await this.helpers.getElement(locator, waitForVisible, timeout); + console.log('~~this.helpers', this.helpers); - let text; + const el = await this.helpers.getElement(locator, waitForVisible, timeout); + this.helpers.assertUnableToFindElement(el, locator); + let text = ''; try { await this.driver.waitUntil(async() => { var opts = el.$$('//option'); diff --git a/src/ox_modules/module-web/commands/assertSelectedValue.js b/src/ox_modules/module-web/commands/assertSelectedValue.js index a9b013f8..16a4407a 100644 --- a/src/ox_modules/module-web/commands/assertSelectedValue.js +++ b/src/ox_modules/module-web/commands/assertSelectedValue.js @@ -27,6 +27,8 @@ module.exports = async function(locator, pattern, timeout, waitForVisible = true const el = await this.helpers.getElement(locator, waitForVisible, timeout); + this.helpers.assertUnableToFindElement(el, locator); + let text; try { await this.driver.waitUntil(async() => { diff --git a/src/ox_modules/module-web/commands/assertText.js b/src/ox_modules/module-web/commands/assertText.js index f1564441..d52ec3a7 100644 --- a/src/ox_modules/module-web/commands/assertText.js +++ b/src/ox_modules/module-web/commands/assertText.js @@ -27,6 +27,8 @@ module.exports = async function(locator, pattern, timeout) { const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + let text; try { await this.driver.waitUntil(async() => { diff --git a/src/ox_modules/module-web/commands/assertValue.js b/src/ox_modules/module-web/commands/assertValue.js index 80b65552..1b53e528 100644 --- a/src/ox_modules/module-web/commands/assertValue.js +++ b/src/ox_modules/module-web/commands/assertValue.js @@ -26,6 +26,8 @@ module.exports = async function(locator, pattern, timeout) { const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + let text; try { await this.driver.waitUntil(async() => { diff --git a/src/ox_modules/module-web/commands/clear.js b/src/ox_modules/module-web/commands/clear.js index 9602a13c..03a078dc 100644 --- a/src/ox_modules/module-web/commands/clear.js +++ b/src/ox_modules/module-web/commands/clear.js @@ -23,6 +23,8 @@ module.exports = async function(locator, timeout) { const el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); + try { await el.clearValue(); } catch (e) { diff --git a/src/ox_modules/module-web/commands/click.js b/src/ox_modules/module-web/commands/click.js index f4477115..bcd1a15b 100644 --- a/src/ox_modules/module-web/commands/click.js +++ b/src/ox_modules/module-web/commands/click.js @@ -64,6 +64,8 @@ module.exports = async function(locator, timeout) { var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + try { var clickable = await el.isClickable(); } catch (e) { diff --git a/src/ox_modules/module-web/commands/clickHidden.js b/src/ox_modules/module-web/commands/clickHidden.js index 85af84ba..da040d6c 100644 --- a/src/ox_modules/module-web/commands/clickHidden.js +++ b/src/ox_modules/module-web/commands/clickHidden.js @@ -68,6 +68,7 @@ module.exports = async function(locator, clickParent = false) { }; var el = await this.helpers.getElement(locator); + this.helpers.assertUnableToFindElement(el, locator); await this.clickJS(el, clickParent); await this.checkWaitForAngular(); }; diff --git a/src/ox_modules/module-web/commands/doubleClick.js b/src/ox_modules/module-web/commands/doubleClick.js index d39353ea..2df7aca9 100644 --- a/src/ox_modules/module-web/commands/doubleClick.js +++ b/src/ox_modules/module-web/commands/doubleClick.js @@ -22,6 +22,8 @@ module.exports = async function(locator, timeout) { var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + try { var clickable = await el.isClickable(); } catch (e) { diff --git a/src/ox_modules/module-web/commands/dragAndDrop.js b/src/ox_modules/module-web/commands/dragAndDrop.js index abf6042e..7fb0dfee 100644 --- a/src/ox_modules/module-web/commands/dragAndDrop.js +++ b/src/ox_modules/module-web/commands/dragAndDrop.js @@ -26,7 +26,9 @@ module.exports = async function(srcElement, dstElement, duration, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var srcEl = await this.helpers.getElement(srcElement, false, timeout); + this.helpers.assertUnableToFindElement(srcEl, srcElement); var dstEl = await this.helpers.getElement(dstElement, false, timeout); + this.helpers.assertUnableToFindElement(dstEl, dstElement); await srcEl.dragAndDrop(dstEl, duration); await this.checkWaitForAngular(); diff --git a/src/ox_modules/module-web/commands/fileBrowse.js b/src/ox_modules/module-web/commands/fileBrowse.js index 47ba6338..ba298862 100644 --- a/src/ox_modules/module-web/commands/fileBrowse.js +++ b/src/ox_modules/module-web/commands/fileBrowse.js @@ -27,6 +27,7 @@ module.exports = async function(locator, filepath, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { // make an asynchronous call using archiver 3rd party library supporting promises const remoteFilePath = await this.driver.call(() => { diff --git a/src/ox_modules/module-web/commands/getAttribute.js b/src/ox_modules/module-web/commands/getAttribute.js index 6bfcad48..4f7c6e32 100644 --- a/src/ox_modules/module-web/commands/getAttribute.js +++ b/src/ox_modules/module-web/commands/getAttribute.js @@ -25,6 +25,8 @@ module.exports = async function(locator, attribute, timeout) { var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + var attrValue = await el.getAttribute(attribute); if (attrValue) { attrValue = attrValue.trim().replace(/\s+/g, ' '); diff --git a/src/ox_modules/module-web/commands/getCssValue.js b/src/ox_modules/module-web/commands/getCssValue.js index b204682b..7ae1f7a7 100644 --- a/src/ox_modules/module-web/commands/getCssValue.js +++ b/src/ox_modules/module-web/commands/getCssValue.js @@ -25,6 +25,8 @@ module.exports = async function(locator, propertyName, timeout) { var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + var css = await el.getCSSProperty(propertyName); if (css) { return css.value.trim().replace(/\s+/g, ' '); diff --git a/src/ox_modules/module-web/commands/getHTML.js b/src/ox_modules/module-web/commands/getHTML.js index 8bdd8553..d680d744 100644 --- a/src/ox_modules/module-web/commands/getHTML.js +++ b/src/ox_modules/module-web/commands/getHTML.js @@ -22,5 +22,8 @@ module.exports = async function(locator, includeElementTag, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + return await el.getHTML(includeElementTag); }; diff --git a/src/ox_modules/module-web/commands/getText.js b/src/ox_modules/module-web/commands/getText.js index e25ab60c..41e3ac78 100644 --- a/src/ox_modules/module-web/commands/getText.js +++ b/src/ox_modules/module-web/commands/getText.js @@ -22,6 +22,9 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + var text = await el.getText(); if (text) { return text.trim().replace(/\s+/g, ' '); diff --git a/src/ox_modules/module-web/commands/getValue.js b/src/ox_modules/module-web/commands/getValue.js index 1e88b2b3..3cb965c4 100644 --- a/src/ox_modules/module-web/commands/getValue.js +++ b/src/ox_modules/module-web/commands/getValue.js @@ -22,6 +22,9 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, true, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + let val; try { diff --git a/src/ox_modules/module-web/commands/index.js b/src/ox_modules/module-web/commands/index.js index 6b184305..1204b9fa 100644 --- a/src/ox_modules/module-web/commands/index.js +++ b/src/ox_modules/module-web/commands/index.js @@ -72,7 +72,18 @@ export {default as waitForNotValue} from './waitForNotValue'; export {default as waitForText} from './waitForText'; export {default as waitForValue} from './waitForValue'; export {default as waitForVisible} from './waitForVisible'; +export {default as waitForNotVisible} from './waitForNotVisible'; export {default as waitForWindow} from './waitForWindow'; export {default as waitForInteractable} from './waitForInteractable'; +export {default as waitForNotInteractable} from './waitForNotInteractable'; export {default as getHTML} from './getHTML'; export {default as isChecked} from './isChecked'; +export {default as verifyAlert} from './verifyAlert'; +export {default as verifyExist} from './verifyExist'; +export {default as verifySelectedLabel} from './verifySelectedLabel'; +export {default as verifySelectedValue} from './verifySelectedValue'; +export {default as verifyText} from './verifyText'; +export {default as verifyTextNotPresent} from './verifyTextNotPresent'; +export {default as verifyTextPresent} from './verifyTextPresent'; +export {default as verifyTitle} from './verifyTitle'; +export {default as verifyValue} from './verifyValue'; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/isChecked.js b/src/ox_modules/module-web/commands/isChecked.js index 1ec2f549..cba4b06c 100644 --- a/src/ox_modules/module-web/commands/isChecked.js +++ b/src/ox_modules/module-web/commands/isChecked.js @@ -22,5 +22,8 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + return await el.getAttribute('checked') == 'true'; }; diff --git a/src/ox_modules/module-web/commands/isExist.js b/src/ox_modules/module-web/commands/isExist.js index 3691a068..b2a1e796 100644 --- a/src/ox_modules/module-web/commands/isExist.js +++ b/src/ox_modules/module-web/commands/isExist.js @@ -23,8 +23,8 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); try { - await this.helpers.getElement(locator, false, timeout); - return true; + const element = await this.helpers.getElement(locator, false, timeout); + return !!element; } catch (e) { return false; } diff --git a/src/ox_modules/module-web/commands/isSelected.js b/src/ox_modules/module-web/commands/isSelected.js index 6036cf92..7e8a0770 100644 --- a/src/ox_modules/module-web/commands/isSelected.js +++ b/src/ox_modules/module-web/commands/isSelected.js @@ -27,5 +27,8 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + return await el.isSelected(); }; diff --git a/src/ox_modules/module-web/commands/isVisible.js b/src/ox_modules/module-web/commands/isVisible.js index a8ac720e..cbdb8251 100644 --- a/src/ox_modules/module-web/commands/isVisible.js +++ b/src/ox_modules/module-web/commands/isVisible.js @@ -23,8 +23,8 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); try { - await this.helpers.getElement(locator, true, timeout); - return true; + const element = await this.helpers.getElement(locator, true, timeout); + return !!element; } catch (e) { return false; } diff --git a/src/ox_modules/module-web/commands/makeVisible.js b/src/ox_modules/module-web/commands/makeVisible.js index 3aca0bd7..932ce15e 100644 --- a/src/ox_modules/module-web/commands/makeVisible.js +++ b/src/ox_modules/module-web/commands/makeVisible.js @@ -28,6 +28,8 @@ module.exports = async function (locator) { var el = await this.helpers.getElement(locator); + this.helpers.assertUnableToFindElement(el, locator); + /*global window*/ await this.driver.execute(function (domEl) { // make sure current element and all its ancestors have "display" style value different from "none" diff --git a/src/ox_modules/module-web/commands/point.js b/src/ox_modules/module-web/commands/point.js index f0e4f7ef..f44455a0 100644 --- a/src/ox_modules/module-web/commands/point.js +++ b/src/ox_modules/module-web/commands/point.js @@ -25,6 +25,9 @@ module.exports = async function(locator, xOffset, yOffset, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + await el.moveTo({xOffset: xOffset, yOffset: yOffset }); await this.checkWaitForAngular(); }; diff --git a/src/ox_modules/module-web/commands/pointJS.js b/src/ox_modules/module-web/commands/pointJS.js index b5c2ce60..a947ebaf 100644 --- a/src/ox_modules/module-web/commands/pointJS.js +++ b/src/ox_modules/module-web/commands/pointJS.js @@ -19,6 +19,9 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + var isIE = await this.getCapabilities().browserName === 'internet explorer'; /*global MouseEvent,document,window*/ diff --git a/src/ox_modules/module-web/commands/rightClick.js b/src/ox_modules/module-web/commands/rightClick.js index a775cc11..aed282fd 100644 --- a/src/ox_modules/module-web/commands/rightClick.js +++ b/src/ox_modules/module-web/commands/rightClick.js @@ -21,6 +21,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { var clickable = await el.isClickable(); diff --git a/src/ox_modules/module-web/commands/rightClickActions.js b/src/ox_modules/module-web/commands/rightClickActions.js index a7c3aeed..401e3f7b 100644 --- a/src/ox_modules/module-web/commands/rightClickActions.js +++ b/src/ox_modules/module-web/commands/rightClickActions.js @@ -25,6 +25,9 @@ module.exports = async function(locator, xOffset = 0, yOffset = 0, timeout) { this.helpers.assertArgumentNumber(yOffset, 'yOffset'); const el = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + const loc = await el.getLocation(); const x = parseInt(loc.x) + xOffset; diff --git a/src/ox_modules/module-web/commands/scrollToElement.js b/src/ox_modules/module-web/commands/scrollToElement.js index a191744a..7c8710fe 100644 --- a/src/ox_modules/module-web/commands/scrollToElement.js +++ b/src/ox_modules/module-web/commands/scrollToElement.js @@ -25,5 +25,8 @@ module.exports = async function(locator, alignToTop = true, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + + this.helpers.assertUnableToFindElement(el, locator); + await el.scrollIntoView(alignToTop); }; diff --git a/src/ox_modules/module-web/commands/select.js b/src/ox_modules/module-web/commands/select.js index fb61e9cf..57d24b2d 100644 --- a/src/ox_modules/module-web/commands/select.js +++ b/src/ox_modules/module-web/commands/select.js @@ -29,6 +29,8 @@ module.exports = async function(selectLocator, optionLocator, timeout) { var el = await this.helpers.getElement(selectLocator, false, timeout); + this.helpers.assertUnableToFindElement(el, selectLocator); + try { if (optionLocator.indexOf('value=') === 0) { await el.selectByAttribute('value', optionLocator.substring('value='.length)); diff --git a/src/ox_modules/module-web/commands/selectFrame.js b/src/ox_modules/module-web/commands/selectFrame.js index 1ca4a13d..a57f916e 100644 --- a/src/ox_modules/module-web/commands/selectFrame.js +++ b/src/ox_modules/module-web/commands/selectFrame.js @@ -36,6 +36,7 @@ module.exports = async function(frameLocator) { for (var i = 0; i < arguments.length; i++) { var locator = arguments[i]; var el = await this.helpers.getElement(locator); + this.helpers.assertUnableToFindElement(el, locator); await this.driver.switchToFrame(el); } } diff --git a/src/ox_modules/module-web/commands/type.js b/src/ox_modules/module-web/commands/type.js index 8220c6bc..2e095722 100644 --- a/src/ox_modules/module-web/commands/type.js +++ b/src/ox_modules/module-web/commands/type.js @@ -25,6 +25,7 @@ module.exports = async function(locator, value, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { if ( diff --git a/src/ox_modules/module-web/commands/verifyAlert.js b/src/ox_modules/module-web/commands/verifyAlert.js new file mode 100644 index 00000000..d7533fb2 --- /dev/null +++ b/src/ox_modules/module-web/commands/verifyAlert.js @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Asserts whether alert matches the specified pattern and dismisses it. + * @description Text pattern can be any of the supported + * string matching patterns(on the top of page). + * @function verifyAlert + * @param {String} pattern - Text pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.click("id=SaveButton");//Clicks on save – an alert would pop up + * web.verifyAlert("Your Alert's text");//verify the alert's text. + */ + +module.exports = async function(...args) { + return await this.helpers.verify(this.assertAlert, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/verifyExist.js b/src/ox_modules/module-web/commands/verifyExist.js new file mode 100644 index 00000000..deb1b9ca --- /dev/null +++ b/src/ox_modules/module-web/commands/verifyExist.js @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify whether element exists in the DOM. + * @function verifyExist + * @param {String|Element} locator - An element locator. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.verifyExist ("id=Username");// Verify if an element exists in the DOM. + */ + +module.exports = async function(...args) { + return await this.helpers.verify(this.assertExist, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/verifySelectedLabel.js b/src/ox_modules/module-web/commands/verifySelectedLabel.js new file mode 100644 index 00000000..8a4d601a --- /dev/null +++ b/src/ox_modules/module-web/commands/verifySelectedLabel.js @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify text of the currently selected option in a drop-down list. + * @description Assertion pattern can be any of the supported + * string matching patterns(on the top of page). + * @function verifySelectedLabel + * @param {String|Element} locator - An element locator. + * @param {String} pattern - The assertion pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @param {Boolean=} waitForVisible - Wait for visible. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.verifySelectedLabel("id=Selection", "United States");// Verify if an element's label is selected in the drop down list. + */ +module.exports = async function(...args) { + return await this.helpers.verify(this.assertSelectedLabel, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/verifySelectedValue.js b/src/ox_modules/module-web/commands/verifySelectedValue.js new file mode 100644 index 00000000..7a9dbc25 --- /dev/null +++ b/src/ox_modules/module-web/commands/verifySelectedValue.js @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify value of the currently selected option in a drop-down list. + * @description Assertion pattern can be any of the supported + * string matching patterns(on the top of page). + * @function verifySelectedValue + * @param {String|Element} locator - An element locator. + * @param {String} pattern - The assertion pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @param {Boolean=} waitForVisible - Wait for visible. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.verifySelectedValue("id=Selection", "3");// Verify if an element's value is selected in the drop down list. + */ +module.exports = async function(...args) { + return await this.helpers.verify(this.assertSelectedValue, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/verifyText.js b/src/ox_modules/module-web/commands/verifyText.js new file mode 100644 index 00000000..bae19a5b --- /dev/null +++ b/src/ox_modules/module-web/commands/verifyText.js @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify element's inner text. + * @description Text pattern can be any of the supported + * string matching patterns(on the top of page). + * If the element is not interactable, then it will allways return empty string as its text. + * @function verifyText + * @param {String|Element} locator - An element locator. + * @param {String} pattern - Text pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.verifyText("id=UserName","John Doe");// Verify if an element's text is as expected. + */ +module.exports = async function(...args) { + return await this.helpers.verify(this.assertText, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/verifyTextNotPresent.js b/src/ox_modules/module-web/commands/verifyTextNotPresent.js new file mode 100644 index 00000000..738f7e33 --- /dev/null +++ b/src/ox_modules/module-web/commands/verifyTextNotPresent.js @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify whether the given text is *not* present on the page. That is, whether there are + * no elements containing this text on the page. + * @function verifyTextNotPresent + * @param {String|Element} text - Text. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.verifyTextNotPresent("John Doe");// Verify if a text is not presented somewhere on the page. + */ +module.exports = async function(...args) { + return await this.helpers.verify(this.assertTextNotPresent, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/verifyTextPresent.js b/src/ox_modules/module-web/commands/verifyTextPresent.js new file mode 100644 index 00000000..e9567299 --- /dev/null +++ b/src/ox_modules/module-web/commands/verifyTextPresent.js @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify whether the given text is present somewhere on the page. That is whether an + * element containing this text exists on the page. + * @function verifyTextPresent + * @param {String} text - Text. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.verifyTextPresent("John Doe");// Verify if a text is presented somewhere on the page. + */ +module.exports = async function(...args) { + return await this.helpers.verify(this.assertTextPresent, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/verifyTitle.js b/src/ox_modules/module-web/commands/verifyTitle.js new file mode 100644 index 00000000..86f3eaa1 --- /dev/null +++ b/src/ox_modules/module-web/commands/verifyTitle.js @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify the page title. + * @description Assertion pattern can be any of the supported + * string matching patterns(on the top of page). + * @function verifyTitle + * @param {String} pattern - The assertion pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.verifyTitle("Your websites title!");// Verify the title of the page. + */ +module.exports = async function(...args) { + return await this.helpers.verify(this.assertTitle, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/verifyValue.js b/src/ox_modules/module-web/commands/verifyValue.js new file mode 100644 index 00000000..d365b733 --- /dev/null +++ b/src/ox_modules/module-web/commands/verifyValue.js @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify element's value. + * @description Value pattern can be any of the supported + * string matching patterns(on the top of page). + * @function verifyValue + * @param {String|Element} locator - An element locator. + * @param {String} pattern - Value pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session + * web.open("www.yourwebsite.com");// Opens a website. + * web.verifyValue("id=UserName", "John Doe");// Verify the value of an element. + */ +module.exports = async function(...args) { + return await this.helpers.verify(this.assertValue, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-web/commands/waitForExist.js b/src/ox_modules/module-web/commands/waitForExist.js index f4f03c8b..0f1ac451 100644 --- a/src/ox_modules/module-web/commands/waitForExist.js +++ b/src/ox_modules/module-web/commands/waitForExist.js @@ -19,5 +19,6 @@ */ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); - await this.helpers.getElement(locator, false, timeout); + const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); }; diff --git a/src/ox_modules/module-web/commands/waitForInteractable.js b/src/ox_modules/module-web/commands/waitForInteractable.js index c5b05b21..ea711a25 100644 --- a/src/ox_modules/module-web/commands/waitForInteractable.js +++ b/src/ox_modules/module-web/commands/waitForInteractable.js @@ -20,5 +20,11 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); const el = await this.helpers.getElement(locator, false, timeout); - await el.waitForClickable({ timeout: timeout ? timeout : this.waitForTimeout }); + this.helpers.assertUnableToFindElement(el, locator); + try { + await el.waitForClickable({ timeout: timeout ? timeout : this.waitForTimeout }); + } catch (e) { + await this.helpers.restoreTimeoutImplicit(); + this.helpers.throwNotInteractable(locator); + } }; diff --git a/src/ox_modules/module-web/commands/waitForNotExist.js b/src/ox_modules/module-web/commands/waitForNotExist.js index b89b3466..34c73459 100644 --- a/src/ox_modules/module-web/commands/waitForNotExist.js +++ b/src/ox_modules/module-web/commands/waitForNotExist.js @@ -28,6 +28,10 @@ module.exports = async function(locator, timeout) { el = await this.helpers.getElement(locator, false, timeout); } + if (!el) { + return; + } + if (el.error && el.error.error === 'no such element') { await this.helpers.restoreTimeoutImplicit(); return; diff --git a/src/ox_modules/module-web/commands/waitForNotInteractable.js b/src/ox_modules/module-web/commands/waitForNotInteractable.js new file mode 100644 index 00000000..d4b790ae --- /dev/null +++ b/src/ox_modules/module-web/commands/waitForNotInteractable.js @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Waits for element to become interactable. + * @function waitForNotInteractable + * @param {String|Element} locator - An element locator. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session. + * web.open("www.yourwebsite.com");// Opens a website. + * web.waitForNotInteractable("id=UserName");//Waits for an element isn't clickable in DOM. + */ +module.exports = async function(locator, timeout) { + this.helpers.assertArgumentTimeout(timeout, 'timeout'); + const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + try { + await el.waitForClickable({ timeout: timeout ? timeout : this.waitForTimeout }); + } catch (e) { + await this.helpers.restoreTimeoutImplicit(); + return; + } + + this.helpers.throwInteractable(locator); +}; diff --git a/src/ox_modules/module-web/commands/waitForNotText.js b/src/ox_modules/module-web/commands/waitForNotText.js index 3f0ea921..149dc2a2 100644 --- a/src/ox_modules/module-web/commands/waitForNotText.js +++ b/src/ox_modules/module-web/commands/waitForNotText.js @@ -25,6 +25,7 @@ module.exports = async function(locator, pattern, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text; try { diff --git a/src/ox_modules/module-web/commands/waitForNotValue.js b/src/ox_modules/module-web/commands/waitForNotValue.js index 5db74a6d..e48df5a5 100644 --- a/src/ox_modules/module-web/commands/waitForNotValue.js +++ b/src/ox_modules/module-web/commands/waitForNotValue.js @@ -25,6 +25,7 @@ module.exports = async function(locator, pattern, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text; try { diff --git a/src/ox_modules/module-web/commands/waitForNotVisible.js b/src/ox_modules/module-web/commands/waitForNotVisible.js new file mode 100644 index 00000000..66f82ad7 --- /dev/null +++ b/src/ox_modules/module-web/commands/waitForNotVisible.js @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Waits for element to become visible. + * @function waitForNotVisible + * @param {String|Element} locator - An element locator. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * web.init();//Opens browser session. + * web.open("www.yourwebsite.com");// Opens a website. + * web.waitForNotVisible("id=Title", 45*1000);//Waits if an element is visible. + */ +module.exports = async function(locator, timeout) { + this.helpers.assertArgumentTimeout(timeout, 'timeout'); + const el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertNotVisible(el, locator); +}; diff --git a/src/ox_modules/module-web/commands/waitForText.js b/src/ox_modules/module-web/commands/waitForText.js index d53167ce..545a3f7c 100644 --- a/src/ox_modules/module-web/commands/waitForText.js +++ b/src/ox_modules/module-web/commands/waitForText.js @@ -25,6 +25,7 @@ module.exports = async function(locator, pattern, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text; try { diff --git a/src/ox_modules/module-web/commands/waitForValue.js b/src/ox_modules/module-web/commands/waitForValue.js index b84cd709..ffa10f2a 100644 --- a/src/ox_modules/module-web/commands/waitForValue.js +++ b/src/ox_modules/module-web/commands/waitForValue.js @@ -25,6 +25,7 @@ module.exports = async function(locator, pattern, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text; try { diff --git a/src/ox_modules/module-web/commands/waitForVisible.js b/src/ox_modules/module-web/commands/waitForVisible.js index f32c4444..b17b2708 100644 --- a/src/ox_modules/module-web/commands/waitForVisible.js +++ b/src/ox_modules/module-web/commands/waitForVisible.js @@ -19,5 +19,6 @@ */ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); - await this.helpers.getElement(locator, true, timeout); + const el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); }; diff --git a/src/ox_modules/module-win.js b/src/ox_modules/module-win.js index 84bff758..72864e5b 100644 --- a/src/ox_modules/module-win.js +++ b/src/ox_modules/module-win.js @@ -197,6 +197,17 @@ export default class WindowsModule extends WebDriverModule { * @summary Ends the current session. */ async dispose(status) { + if (!status) { + status = 'passed'; + + if (this.rs.steps && Array.isArray(this.rs.steps) && this.rs.steps.length > 0) { + const failedFinded = this.rs.steps.find((item) => item.status === 'failed'); + if (failedFinded) { + status = 'failed'; + } + } + } + status = status.toUpperCase(); if (this.driver && this.isInitialized) { try { @@ -336,6 +347,11 @@ export default class WindowsModule extends WebDriverModule { this.helpers.assertArgumentBool = modUtils.assertArgumentBool; this.helpers.assertArgumentBoolOptional = modUtils.assertArgumentBoolOptional; this.helpers.assertArgumentTimeout = modUtils.assertArgumentTimeout; + this.helpers.assertUnableToFindElement = modUtils.assertUnableToFindElement; + this.helpers.assertNotVisible = modUtils.assertNotVisible; + this.helpers.throwNotInteractable = modUtils.throwNotInteractable; + this.helpers.throwInteractable = modUtils.throwInteractable; + this.helpers.verify = modUtils.verify; } } diff --git a/src/ox_modules/module-win/commands/assertText.js b/src/ox_modules/module-win/commands/assertText.js index e6245424..19bdfc08 100644 --- a/src/ox_modules/module-win/commands/assertText.js +++ b/src/ox_modules/module-win/commands/assertText.js @@ -22,6 +22,7 @@ module.exports = async function(locator, pattern, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text; try { diff --git a/src/ox_modules/module-win/commands/assertValue.js b/src/ox_modules/module-win/commands/assertValue.js index 218b6166..63f9e9e8 100644 --- a/src/ox_modules/module-win/commands/assertValue.js +++ b/src/ox_modules/module-win/commands/assertValue.js @@ -18,6 +18,7 @@ module.exports = async function(locator, pattern, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text; var actualError; diff --git a/src/ox_modules/module-win/commands/clear.js b/src/ox_modules/module-win/commands/clear.js index 0011b730..7bb96cf5 100644 --- a/src/ox_modules/module-win/commands/clear.js +++ b/src/ox_modules/module-win/commands/clear.js @@ -17,6 +17,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { await el.clearValue(); diff --git a/src/ox_modules/module-win/commands/click.js b/src/ox_modules/module-win/commands/click.js index c38819c4..0b89838c 100644 --- a/src/ox_modules/module-win/commands/click.js +++ b/src/ox_modules/module-win/commands/click.js @@ -17,5 +17,6 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); await el.click(); }; diff --git a/src/ox_modules/module-win/commands/clickLong.js b/src/ox_modules/module-win/commands/clickLong.js index b4b04f32..8f671e8a 100644 --- a/src/ox_modules/module-win/commands/clickLong.js +++ b/src/ox_modules/module-win/commands/clickLong.js @@ -19,6 +19,7 @@ module.exports = async function(locator, duration, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); await el.touchAction([ 'press', diff --git a/src/ox_modules/module-win/commands/clickMultipleTimes.js b/src/ox_modules/module-win/commands/clickMultipleTimes.js index 44f1fae6..0ca76d02 100644 --- a/src/ox_modules/module-win/commands/clickMultipleTimes.js +++ b/src/ox_modules/module-win/commands/clickMultipleTimes.js @@ -19,6 +19,7 @@ module.exports = async function(locator, taps, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); var actions = []; for (var i = 0; i < taps; i++) { diff --git a/src/ox_modules/module-win/commands/getLocation.js b/src/ox_modules/module-win/commands/getLocation.js index 72fbd41c..acb321d2 100644 --- a/src/ox_modules/module-win/commands/getLocation.js +++ b/src/ox_modules/module-win/commands/getLocation.js @@ -18,5 +18,6 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getLocation(); }; diff --git a/src/ox_modules/module-win/commands/getText.js b/src/ox_modules/module-win/commands/getText.js index 172e1709..e9ade506 100644 --- a/src/ox_modules/module-win/commands/getText.js +++ b/src/ox_modules/module-win/commands/getText.js @@ -18,6 +18,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); var text = await el.getText(); if (text) { return text.trim().replace(/\s+/g, ' '); diff --git a/src/ox_modules/module-win/commands/getValue.js b/src/ox_modules/module-win/commands/getValue.js index c417c364..b6dccf0c 100644 --- a/src/ox_modules/module-win/commands/getValue.js +++ b/src/ox_modules/module-win/commands/getValue.js @@ -18,6 +18,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { var text = await el.getValue(); diff --git a/src/ox_modules/module-win/commands/index.js b/src/ox_modules/module-win/commands/index.js index ec1df6c6..be9ffc1e 100644 --- a/src/ox_modules/module-win/commands/index.js +++ b/src/ox_modules/module-win/commands/index.js @@ -33,4 +33,9 @@ export {default as tap} from './tap'; export {default as type} from './type'; export {default as waitForExist} from './waitForExist'; export {default as waitForVisible} from './waitForVisible'; +export {default as waitForNotVisible} from './waitForNotVisible'; export {default as waitForInteractable} from './waitForInteractable'; +export {default as waitForNotInteractable} from './waitForNotInteractable'; +export {default as verifyText} from './verifyText'; +export {default as verifyTitle} from './verifyTitle'; +export {default as verifyValue} from './verifyValue'; diff --git a/src/ox_modules/module-win/commands/isCheckable.js b/src/ox_modules/module-win/commands/isCheckable.js index 1b0ddcfd..0464d182 100644 --- a/src/ox_modules/module-win/commands/isCheckable.js +++ b/src/ox_modules/module-win/commands/isCheckable.js @@ -18,5 +18,6 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getAttribute('checkable') == 'true'; }; diff --git a/src/ox_modules/module-win/commands/isChecked.js b/src/ox_modules/module-win/commands/isChecked.js index dd498562..5dffc36d 100644 --- a/src/ox_modules/module-win/commands/isChecked.js +++ b/src/ox_modules/module-win/commands/isChecked.js @@ -18,5 +18,6 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getAttribute('checked') == 'true'; }; diff --git a/src/ox_modules/module-win/commands/isClickable.js b/src/ox_modules/module-win/commands/isClickable.js index 1099c488..458f118d 100644 --- a/src/ox_modules/module-win/commands/isClickable.js +++ b/src/ox_modules/module-win/commands/isClickable.js @@ -18,5 +18,6 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.getAttribute('clickable') == 'true'; }; diff --git a/src/ox_modules/module-win/commands/isExist.js b/src/ox_modules/module-win/commands/isExist.js index 3db58b3a..266e3d55 100644 --- a/src/ox_modules/module-win/commands/isExist.js +++ b/src/ox_modules/module-win/commands/isExist.js @@ -19,8 +19,8 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); try { - await this.helpers.getElement(locator, false, timeout); - return true; + const el = await this.helpers.getElement(locator, false, timeout); + return !!el; } catch (e) { return false; } diff --git a/src/ox_modules/module-win/commands/isSelected.js b/src/ox_modules/module-win/commands/isSelected.js index d22de5d3..ec7fb819 100644 --- a/src/ox_modules/module-win/commands/isSelected.js +++ b/src/ox_modules/module-win/commands/isSelected.js @@ -18,6 +18,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); return await el.isSelected(); }; diff --git a/src/ox_modules/module-win/commands/isVisible.js b/src/ox_modules/module-win/commands/isVisible.js index abd1b9e4..9677e843 100644 --- a/src/ox_modules/module-win/commands/isVisible.js +++ b/src/ox_modules/module-win/commands/isVisible.js @@ -19,8 +19,8 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); try { - await this.helpers.getElement(locator, true, timeout); - return true; + const el = await this.helpers.getElement(locator, true, timeout); + return !!el; } catch (e) { return false; } diff --git a/src/ox_modules/module-win/commands/rightClick.js b/src/ox_modules/module-win/commands/rightClick.js index 70f2603f..9d54d488 100644 --- a/src/ox_modules/module-win/commands/rightClick.js +++ b/src/ox_modules/module-win/commands/rightClick.js @@ -17,6 +17,7 @@ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); const { width, height } = await this.driver.getElementSize(el.elementId); await this.driver.moveToElement(el.elementId, width / 2, height / 2); diff --git a/src/ox_modules/module-win/commands/type.js b/src/ox_modules/module-win/commands/type.js index d62ccfb6..a0c8581e 100644 --- a/src/ox_modules/module-win/commands/type.js +++ b/src/ox_modules/module-win/commands/type.js @@ -21,6 +21,7 @@ module.exports = async function(locator, value, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); var el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { await el.setValue(value.toString()); diff --git a/src/ox_modules/module-win/commands/verifyText.js b/src/ox_modules/module-win/commands/verifyText.js new file mode 100644 index 00000000..c13c9b24 --- /dev/null +++ b/src/ox_modules/module-win/commands/verifyText.js @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Verify element's inner text. + * @description Text pattern can be any of the supported + * string matching patterns(on the top of page). + * If the element is not interactable, then it will allways return empty string as its text. + * @function verifyText + * @param {String|Element} locator - Element locator. + * @param {String} pattern - Assertion text or pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + */ + +module.exports = async function(...args) { + return await this.helpers.verify(this.assertText, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-win/commands/verifyTitle.js b/src/ox_modules/module-win/commands/verifyTitle.js new file mode 100644 index 00000000..6810099d --- /dev/null +++ b/src/ox_modules/module-win/commands/verifyTitle.js @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ +/** + * @summary Verify the page title. + * @description Assertion pattern can be any of the supported + * string matching patterns(on the top of page). + * @function verifyTitle + * @param {String} pattern - Assertion text or pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + */ +module.exports = async function(...args) { + return await this.helpers.verify(this.assertTitle, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-win/commands/verifyValue.js b/src/ox_modules/module-win/commands/verifyValue.js new file mode 100644 index 00000000..0bc35bdc --- /dev/null +++ b/src/ox_modules/module-win/commands/verifyValue.js @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ +/** + * @summary Verify element's value. + * @function verifyValue + * @param {String|Element} locator - Element locator. + * @param {String} pattern - Value pattern. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + */ + +module.exports = async function(...args) { + return await this.helpers.verify(this.assertValue, this, ...args); +}; \ No newline at end of file diff --git a/src/ox_modules/module-win/commands/waitForExist.js b/src/ox_modules/module-win/commands/waitForExist.js index f9632f2f..36a91552 100644 --- a/src/ox_modules/module-win/commands/waitForExist.js +++ b/src/ox_modules/module-win/commands/waitForExist.js @@ -16,5 +16,6 @@ */ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); - await this.helpers.getElement(locator, false, timeout); + const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); }; diff --git a/src/ox_modules/module-win/commands/waitForInteractable.js b/src/ox_modules/module-win/commands/waitForInteractable.js index e4046472..bf3d7ac1 100644 --- a/src/ox_modules/module-win/commands/waitForInteractable.js +++ b/src/ox_modules/module-win/commands/waitForInteractable.js @@ -20,6 +20,7 @@ const interactableClassNames = ['Edit', 'Button']; module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); try { await this.driver.waitUntil(async() => { const isControlElement = await el.getAttribute('IsControlElement'); @@ -31,6 +32,7 @@ module.exports = async function(locator, timeout) { }, { timeout: (timeout ? timeout : this.waitForTimeout) }); } catch (e) { - throw new this.OxError(this.errHelper.errorCode.ELEMENT_NOT_INTERACTABLE, `Element ${locator} is not interactable`); + await this.helpers.restoreTimeoutImplicit(); + this.helpers.throwNotInteractable(locator); } }; diff --git a/src/ox_modules/module-win/commands/waitForNotInteractable.js b/src/ox_modules/module-win/commands/waitForNotInteractable.js new file mode 100644 index 00000000..ab356a24 --- /dev/null +++ b/src/ox_modules/module-win/commands/waitForNotInteractable.js @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Waits for element to become interactable. + * @function waitForInteractable + * @param {String|Element} locator - An element locator. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + * @example [javascript] Usage example + * win.init();//Opens browser session. + * win.waitForInteractable("id=UserName");//Waits for an element is not clickable. + */ +const interactableClassNames = ['Edit', 'Button']; +module.exports = async function(locator, timeout) { + this.helpers.assertArgumentTimeout(timeout, 'timeout'); + const el = await this.helpers.getElement(locator, false, timeout); + this.helpers.assertUnableToFindElement(el, locator); + try { + await this.driver.waitUntil(async() => { + const isControlElement = await el.getAttribute('IsControlElement'); + const isEnabled = await el.getAttribute('IsEnabled'); + const isKeyboardFocusable = await el.getAttribute('IsKeyboardFocusable'); + const className = await el.getAttribute('ClassName'); + + return (isControlElement || isEnabled || isKeyboardFocusable || interactableClassNames.includes(className)); + }, + { timeout: (timeout ? timeout : this.waitForTimeout) }); + } catch (e) { + await this.helpers.restoreTimeoutImplicit(); + return; + } + + this.helpers.throwInteractable(locator); +}; diff --git a/src/ox_modules/module-win/commands/waitForNotVisible.js b/src/ox_modules/module-win/commands/waitForNotVisible.js new file mode 100644 index 00000000..7e781613 --- /dev/null +++ b/src/ox_modules/module-win/commands/waitForNotVisible.js @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015-present CloudBeat Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +/** + * @summary Waits for element to become visible. + * @function waitForNotVisible + * @param {String|Element} locator - An element locator. + * @param {Number=} timeout - Timeout in milliseconds. Default is 60 seconds. + */ +module.exports = async function(locator, timeout) { + this.helpers.assertArgumentTimeout(timeout, 'timeout'); + const el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertNotVisible(el, locator); +}; diff --git a/src/ox_modules/module-win/commands/waitForVisible.js b/src/ox_modules/module-win/commands/waitForVisible.js index 9364f6e4..2577c2ce 100644 --- a/src/ox_modules/module-win/commands/waitForVisible.js +++ b/src/ox_modules/module-win/commands/waitForVisible.js @@ -15,5 +15,6 @@ */ module.exports = async function(locator, timeout) { this.helpers.assertArgumentTimeout(timeout, 'timeout'); - await this.helpers.getElement(locator, true, timeout); + const el = await this.helpers.getElement(locator, true, timeout); + this.helpers.assertUnableToFindElement(el, locator); }; diff --git a/src/ox_modules/utils.js b/src/ox_modules/utils.js index 3c0fc5fc..697bda81 100644 --- a/src/ox_modules/utils.js +++ b/src/ox_modules/utils.js @@ -83,7 +83,7 @@ module.exports = { if (timeout) { await module.exports.restoreTimeoutImplicit.call(this); } - throw new OxError(errHelper.errorCode.ELEMENT_NOT_FOUND, `Unable to find element: ${locator}`); + return null; } if (waitForVisible) { @@ -151,7 +151,7 @@ module.exports = { if (timeout) { await module.exports.restoreTimeoutImplicit.call(this); } - throw new OxError(errHelper.errorCode.ELEMENT_NOT_FOUND, `Unable to find element: ${locator}`); + return null; } if (waitForVisible) { @@ -422,4 +422,58 @@ module.exports = { throw new OxError(errHelper.errorCode.CIRCULAR_ERROR, hasCircularDependency); } }, + + assertUnableToFindElement: function(element, locator) { + if (!element) { + throw new OxError(errHelper.errorCode.ELEMENT_NOT_FOUND, `Unable to find element: ${locator}`); + } + }, + + assertNotVisible: function(element, locator) { + if (element) { + let errorText = ''; + + if (typeof locator === 'string') { + errorText = `Element with locator: "${locator}" still visible`; + } else { + errorText = 'Element still visible'; + } + + throw new OxError(errHelper.errorCode.TIMEOUT, errorText); + } + }, + + throwNotInteractable: function(locator) { + let errorText = ''; + + if (typeof locator === 'string') { + errorText = `Element with locator: "${locator}" is not interactable`; + } else { + errorText = 'Element not interactable'; + } + + throw new OxError(errHelper.errorCode.ELEMENT_NOT_INTERACTABLE, errorText); + }, + + throwInteractable: function(locator) { + let errorText = ''; + + if (typeof locator === 'string') { + errorText = `Element with locator: "${locator}" is interactable`; + } else { + errorText = 'Element is interactable'; + } + + throw new OxError(errHelper.errorCode.ELEMENT_INTERACTABLE, errorText); + }, + + verify: async function(method, self, ...args) { + try { + await method.apply(self, args); + } catch (e) { + // for warning status + e.isFatal = false; + throw e; + } + } }; diff --git a/src/ox_reporters/html/tests-details.ejs b/src/ox_reporters/html/tests-details.ejs index 32d46e75..d94ec8b7 100644 --- a/src/ox_reporters/html/tests-details.ejs +++ b/src/ox_reporters/html/tests-details.ejs @@ -2,6 +2,7 @@ const PASSED_LABEL = `PASSED`; const FAILED_LABEL = `FAILED`; const SKIPPED_LABEL = `SKIPPED`; + const WARNING_LABEL = `WARNING`; %>
@@ -82,7 +83,10 @@ <%= stepResult.name %> <%= stepResult.duration %> - <%- stepResult.status === 'passed' ? PASSED_LABEL : (stepResult.status === 'skipped' ? SKIPPED_LABEL : FAILED_LABEL) %> + <%- stepResult.status === 'passed' ? PASSED_LABEL : '' %> + <%- stepResult.status === 'warning' ? WARNING_LABEL : '' %> + <%- stepResult.status === 'skipped' ? SKIPPED_LABEL : '' %> + <%- stepResult.status === 'failed' ? FAILED_LABEL : '' %>